diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 17 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 41 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.cc | 21 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.h | 10 | ||||
-rw-r--r-- | winsup/cygwin/shared.h | 6 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 9 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 1 |
7 files changed, 81 insertions, 24 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0bb01136d..3e413e718 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,20 @@ +Wed Aug 23 23:00:24 2000 Christopher Faylor <cgf@cygnus.com> + + * dcrt0.cc (dll_crt0_1): Move exception list and constructor stuff + earlier in the process. Use new second argument to set_myself. + (cygwin_dll_init): Initialize exception list and constructor stuff + here. + (_dll_crt0): And here. Also, deal with inherited pinfo shared memory + region from parent. + * pinfo.cc (set_myself): Accept a second argument signifying the a + shared memory region, passed from an execing parent. + (pinfo_init): Ditto. + * pinfo.h: Ditto. + * shared.h (child_info): Add a handle field to pass to child. + * spawn.cc (spawn_guts): Create a shared handle to pass to an execed + child. + * winsup.h: Remove extraneous declaration. + Wed Aug 23 10:51:57 2000 Christopher Faylor <cgf@cygnus.com> * include/sys/cygwin.h: Protect class definitions. diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index fa0f4dd86..20005d3e2 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -615,12 +615,6 @@ sigthread::init (const char *s) static void dll_crt0_1 () { - /* According to onno@stack.urc.tue.nl, the exception handler record must - be on the stack. */ - /* FIXME: Verify forked children get their exception handler set up ok. */ - exception_list cygwin_except_entry; - do_global_ctors (&__CTOR_LIST__, 1); - #ifdef DEBUGGING if (child_proc_info) switch (child_proc_info->type) @@ -666,7 +660,7 @@ dll_crt0_1 () // should be blocked. if (mypid) - set_myself ((pid_t) mypid); + set_myself ((pid_t) mypid, NULL); (void) SetErrorMode (SEM_FAILCRITICALERRORS); @@ -683,11 +677,6 @@ dll_crt0_1 () instead of each time a file is opened. */ set_process_privileges (); - /* Initialize SIGSEGV handling, etc... Because the exception handler - references data in the shared area, this must be done after - shared_init. */ - init_exceptions (&cygwin_except_entry); - if (user_data->forkee) { /* If we've played with the stack, stacksize != 0. That means that @@ -812,6 +801,15 @@ extern "C" void __stdcall _dll_crt0 () { char zeros[sizeof (ciresrv->zero)] = {0}; + /* According to onno@stack.urc.tue.nl, the exception handler record must + be on the stack. */ + /* FIXME: Verify forked children get their exception handler set up ok. */ + exception_list cygwin_except_entry; + /* Initialize SIGSEGV handling, etc... Because the exception handler + references data in the shared area, this must be done after + shared_init. */ + init_exceptions (&cygwin_except_entry); + do_global_ctors (&__CTOR_LIST__, 1); #ifdef DEBUGGING char buf[80]; @@ -834,6 +832,7 @@ _dll_crt0 () DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc, &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS); + HANDLE h; GetStartupInfo (&si); if (si.cbReserved2 >= EXEC_MAGIC_SIZE && memcmp (ciresrv->zero, zeros, sizeof (zeros)) == 0) @@ -868,6 +867,14 @@ _dll_crt0 () case PROC_EXEC: case PROC_SPAWN: info = si.lpReserved2 + ciresrv->cb; + if (child_proc_info->myself_pinfo && + DuplicateHandle (hMainProc, child_proc_info->myself_pinfo, + hMainProc, &h, 0, 0, + DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) + { + set_myself (mypid, h); + mypid = 0; + } break; case PROC_FORK: case PROC_FORK1: @@ -905,6 +912,16 @@ cygwin_dll_init () { static char **envp; static int _fmode; + /* According to onno@stack.urc.tue.nl, the exception handler record must + be on the stack. */ + /* FIXME: Verify forked children get their exception handler set up ok. */ + exception_list cygwin_except_entry; + /* Initialize SIGSEGV handling, etc... Because the exception handler + references data in the shared area, this must be done after + shared_init. */ + init_exceptions (&cygwin_except_entry); + do_global_ctors (&__CTOR_LIST__, 1); + user_data->heapbase = user_data->heapptr = user_data->heaptop = NULL; if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 347015be4..0d52ec9f9 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -30,17 +30,17 @@ static pinfo NO_COPY myself_identity ((_pinfo *)&pinfo_dummy); This is done once when the dll is first loaded. */ void __stdcall -set_myself (pid_t pid) +set_myself (pid_t pid, HANDLE h) { DWORD winpid = GetCurrentProcessId (); if (pid == 1) pid = cygwin_pid (winpid); - myself.init (pid, 1); + myself.init (pid, 1, h); myself->dwProcessId = winpid; myself->process_state |= PID_IN_USE; myself->start_time = time (NULL); /* Register our starting time. */ pid_t myself_cyg_pid = cygwin_pid (myself->dwProcessId); - if (pid != myself_cyg_pid) + if (pid != myself_cyg_pid && parent_alive) myself_identity.init (myself_cyg_pid, PID_EXECED); char buf[30]; @@ -95,7 +95,7 @@ pinfo_init (LPBYTE info) { /* Invent our own pid. */ - set_myself (1); + set_myself (1, NULL); myself->ppid = 1; myself->pgid = myself->sid = myself->pid; myself->ctty = -1; @@ -197,7 +197,7 @@ _pinfo::record_death () } void -pinfo::init (pid_t n, DWORD create) +pinfo::init (pid_t n, DWORD create, HANDLE in_h) { if (n == myself->pid) { @@ -217,7 +217,12 @@ pinfo::init (pid_t n, DWORD create) else mapsize = sizeof (_pinfo); - if (!create) + if (in_h) + { + h = in_h; + created = 0; + } + else if (!create) { /* CGF FIXME -- deal with inheritance after an exec */ h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapname); @@ -225,7 +230,7 @@ pinfo::init (pid_t n, DWORD create) } else { - h = CreateFileMapping ((HANDLE) 0xffffffff, &sec_none_nih, + h = CreateFileMapping ((HANDLE) 0xffffffff, &sec_all_nih, PAGE_READWRITE, 0, mapsize, mapname); created = h && GetLastError () != ERROR_ALREADY_EXISTS; } @@ -238,11 +243,13 @@ pinfo::init (pid_t n, DWORD create) return; } + ProtectHandle1 (h, pinfo_shared_handle); child = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (child->process_state & PID_EXECED) { pid_t realpid = child->pid; + debug_printf ("execed process windows pid %d, cygwin pid %d", n, realpid); release (); if (realpid == n) api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n); diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index b8ee9140b..f84659813 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -117,7 +117,7 @@ class pinfo _pinfo *child; int destroy; public: - void init (pid_t n, DWORD create = 0); + void init (pid_t n, DWORD create = 0, HANDLE h = NULL); pinfo () {} pinfo (_pinfo *x): child (x) {} pinfo (pid_t n) {init (n);} @@ -127,7 +127,7 @@ public: if (h) { UnmapViewOfFile (child); - CloseHandle (h); + ForceCloseHandle1 (h, pinfo_shared_handle); h = NULL; } } @@ -145,7 +145,9 @@ public: int operator == (char *x) const {return (char *) child == x;} _pinfo *operator * () const {return child;} operator _pinfo * () const {return child;} + // operator bool () const {return (int) h;} void remember () {destroy = 0; proc_subproc (PROC_ADDCHILD, (DWORD) this);} + HANDLE shared_handle () {return h;} }; #define ISSTATE(p, f) (!!((p)->process_state & f)) @@ -168,5 +170,7 @@ cygwin_pid (pid_t pid) { return (pid_t) (os_being_run == winNT) ? pid : -(int) pid; } -void __stdcall pinfo_init (PBYTE); + +void __stdcall pinfo_init (BYTE *); +void __stdcall set_myself (pid_t pid, HANDLE h = NULL); extern pinfo myself; diff --git a/winsup/cygwin/shared.h b/winsup/cygwin/shared.h index 2a8e9a6e1..5e3ecd6fe 100644 --- a/winsup/cygwin/shared.h +++ b/winsup/cygwin/shared.h @@ -67,6 +67,12 @@ public: HANDLE shared_h; HANDLE console_h; HANDLE parent_alive; // handle of thread used to track children + HANDLE myself_pinfo; + ~child_info () + { + if (myself_pinfo) + CloseHandle (myself_pinfo); + } }; class child_info_fork: public child_info diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 940f8d170..c9a9c3a11 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -494,9 +494,13 @@ skip_arg_parsing: } init_child_info (chtype, ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr); + if (mode != _P_OVERLAY || + !DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc, + &ciresrv->myself_pinfo, 0, + TRUE, DUPLICATE_SAME_ACCESS)) + ciresrv->myself_pinfo = NULL; LPBYTE resrv = si.lpReserved2 + sizeof *ciresrv; -# undef ciresrv if (fdtab.linearize_fd_array (resrv, len) < 0) { @@ -611,6 +615,9 @@ skip_arg_parsing: free (envblock); MALLOC_CHECK; + if (ciresrv->myself_pinfo) + CloseHandle (ciresrv->myself_pinfo); + /* Set errno now so that debugging messages from it appear before our final debugging message [this is a general rule for debugging messages]. */ diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index be151e75b..56126692a 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -283,7 +283,6 @@ long __stdcall to_time_t (FILETIME * ptr); int __stdcall lock_pinfo_for_update (DWORD timeout); #endif void unlock_pinfo (void); -void _stdcall set_myself (pid_t pid); /* Retrieve a security descriptor that allows all access */ SECURITY_DESCRIPTOR *__stdcall get_null_sd (void); |