diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 65dd26787..0fbb6055f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,22 @@ +2006-03-20 Christopher Faylor + + * child_info.h (child_status): New enum. + (child_info::flag): Rename from 'straced'. + (child_info::isstraced): New function. + (child_info::iscygwin): Ditto. + (child_info_fork::handle_fork): Reparmize. + (child_info_fork::handle_failure): Ditto. + (child_info_spawn::handle_spawn): New function. + * dcrt0.cc (get_cygwin_startup_info): Use isstraced method. + (child_info_spawn::handle_spawn): Define new function from code + previously in dll_crt0_0. + (dll_crt0_0): Move spawn stuff into handle_spawn. Only call + init_console_handler for fork case. + * sigproc.cc (child_info::child_info): Set flag appropriately. + (child_info::proc_retry): Treat exit code as "funny" if it's a cygwin + process. + * spawn.cc (spawn_guts): Remove commented out flag setting. + 2006-03-19 Christopher Faylor * pinfo.cc (commune_process): Fix randomly invalid pointer which caused diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index efca03465..e6599e845 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -18,6 +18,12 @@ enum child_info_types _PROC_WHOOPS }; +enum child_status +{ + _CI_STRACED = 0x01, + _CI_ISCYGWIN = 0x0 +}; + #define OPROC_MAGIC_MASK 0xff00ff00 #define OPROC_MAGIC_GENERIC 0xaf00f000 @@ -29,7 +35,8 @@ enum child_info_types #define EXEC_MAGIC_SIZE sizeof(child_info) -#define CURR_CHILD_INFO_MAGIC 0x482b2eaU +/* Change this value if you get a message indicating that it is out-of-sync. */ +#define CURR_CHILD_INFO_MAGIC 0xa189e57U /* NOTE: Do not make gratuitous changes to the names or organization of the below class. The layout is checksummed to determine compatibility between @@ -48,7 +55,7 @@ public: init_cygheap *cygheap; void *cygheap_max; DWORD cygheap_reserve_sz; - unsigned char straced; + unsigned char flag; unsigned fhandler_union_cb; int retry; // number of times we've tried to start child process DWORD exit_code; // process exit code @@ -58,7 +65,9 @@ public: ~child_info (); void ready (bool); bool sync (int, HANDLE&, DWORD) __attribute__ ((regparm (3))); - DWORD proc_retry (HANDLE); + DWORD proc_retry (HANDLE) __attribute__ ((regparm (2))); + bool isstraced () const {return flag & _CI_STRACED;} + bool iscygwin () const {return flag & _CI_ISCYGWIN;} }; class mount_info; @@ -73,8 +82,8 @@ public: void *stacktop; // location of top of parent stack void *stackbottom; // location of bottom of parent stack child_info_fork (); - void handle_fork (); - bool handle_failure (DWORD); + void handle_fork () __attribute__ ((regparm (1)));; + bool handle_failure (DWORD) __attribute__ ((regparm (2))); }; class fhandler_base; @@ -115,6 +124,7 @@ public: child_info_spawn (child_info_types, bool); void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} void set (child_info_types ci, bool b) { new (this) child_info_spawn (ci, b);} + void handle_spawn () __attribute__ ((regparm (1))); }; void __stdcall init_child_info (DWORD, child_info *, HANDLE); diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index de01d7435..0518ac28f 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -622,7 +622,7 @@ get_cygwin_startup_info () multiple_cygwin_problem ("proc size", res->cb, should_be_cb); else if (sizeof (fhandler_union) != res->fhandler_union_cb) multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union)); - if (res->straced) + if (res->isstraced ()) { res->ready (false); for (unsigned i = 0; !being_debugged () && i < 10000; i++) @@ -669,6 +669,33 @@ child_info_fork::handle_fork () api_fatal ("recreate_mmaps_after_fork_failed"); } +void +child_info_spawn::handle_spawn () +{ + HANDLE h; + cygheap_fixup_in_child (true); + memory_init (); + if (!moreinfo->myself_pinfo || + !DuplicateHandle (hMainProc, moreinfo->myself_pinfo, hMainProc, &h, 0, + FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) + h = NULL; + set_myself (h); + ready (true); + __argc = moreinfo->argc; + __argv = moreinfo->argv; + envp = moreinfo->envp; + envc = moreinfo->envc; + if (!dynamically_loaded) + cygheap->fdtab.fixup_after_exec (); + signal_fixup_after_exec (); + if (moreinfo->old_title) + { + old_title = strcpy (title_buf, moreinfo->old_title); + cfree (moreinfo->old_title); + } + init_console_handler (myself->ctty >= 0); +} + void __stdcall dll_crt0_0 () { @@ -718,31 +745,9 @@ dll_crt0_0 () break; case _PROC_SPAWN: case _PROC_EXEC: - HANDLE h; - cygheap_fixup_in_child (true); - memory_init (); - if (!spawn_info->moreinfo->myself_pinfo || - !DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo, - hMainProc, &h, 0, FALSE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) - h = NULL; - set_myself (h); - child_proc_info->ready (true); - __argc = spawn_info->moreinfo->argc; - __argv = spawn_info->moreinfo->argv; - envp = spawn_info->moreinfo->envp; - envc = spawn_info->moreinfo->envc; - if (!dynamically_loaded) - cygheap->fdtab.fixup_after_exec (); - signal_fixup_after_exec (); - if (spawn_info->moreinfo->old_title) - { - old_title = strcpy (title_buf, spawn_info->moreinfo->old_title); - cfree (spawn_info->moreinfo->old_title); - } + spawn_info->handle_spawn (); break; } - init_console_handler (myself->ctty >= 0); } user_data->resourcelocks->Init (); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index a82e90002..00a6cf90e 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -785,7 +785,11 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, bool need_subpr sigproc_printf ("subproc_ready %p", subproc_ready); cygheap = ::cygheap; cygheap_max = ::cygheap_max; - straced = strace.attached (); + flag = 0; + if (strace.attached ()) + flag |= _CI_STRACED; + if (need_subproc_ready) + flag |= _CI_ISCYGWIN; retry = child_info::retry_count; /* Create an inheritable handle to pass to the child process. This will allow the child to duplicate handles from the parent to itself. */ @@ -903,7 +907,7 @@ child_info::proc_retry (HANDLE h) /* Count down non-recognized exit codes more quickly since they aren't due to known conditions. */ default: - if ((exit_code & 0xc0000000) != 0xc0000000) + if (!iscygwin () && (exit_code & 0xc0000000) != 0xc0000000) break; if ((retry -= 2) < 0) retry = 0; diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 16955bbb7..4b48de59e 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -601,7 +601,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, int flags = GetPriorityClass (hMainProc); sigproc_printf ("priority class %d", flags); - flags |= /* CREATE_DEFAULT_ERROR_MODE | */CREATE_SEPARATE_WOW_VDM; + flags |= CREATE_SEPARATE_WOW_VDM; if (mode == _P_DETACH) flags |= DETACHED_PROCESS;