From d584454c8231f5811136b1ab88defe6e5ca81923 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 12 Sep 2004 03:47:57 +0000 Subject: [PATCH] * exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess is starting. * child_info.h (init_child_info): Remove pid argument from declaration. * cygheap.h (init_cygheap::pid): New element. * dcrt0.cc (dll_crt0_0): Eliminate handling of now-noexistent cygpid parameter in child_info struct. Set forkee to 'true' rather than cygpid since the pid value was never used. (dll_crt0_1): Ditto. (_dll_crt0): Ditto. * fork.cc (fork_child): Don't wait for sigthread. This is handled in the fork call now. (fork_parent): Remove obsolete pid argument from init_child_info call. Don't do anything special with cygpid when DEBUGGING. (fork): Delay all signals during fork. (fork_init): Don't do anything special when DEBUGGING. * pinfo.cc (set_myself): Remove pid parameter. Use new pid field in cygheap. (pinfo_init): Don't pass pid argument to set_myself. * sigproc.cc (sig_send): Wait for dwProcessId to be non-zero as well as sendsig. (init_child_info): Eliminate handling of pid. (wait_sig): Implement method to temporarily hold off sending signals. * sigproc.h (__SIGHOLD): New enum. (__SIGNOHOLD): Ditto. * spawn.cc (spawn_guts): Remove obsolete pid argument from init_child_info call. --- winsup/cygwin/ChangeLog | 33 ++++++++++ winsup/cygwin/child_info.h | 3 +- winsup/cygwin/cygheap.h | 1 + winsup/cygwin/dcrt0.cc | 12 ++-- winsup/cygwin/exceptions.cc | 2 + winsup/cygwin/fhandler.cc | 8 +-- winsup/cygwin/fhandler_dsp.cc | 8 +-- winsup/cygwin/fhandler_proc.cc | 44 ++++++------- winsup/cygwin/fork.cc | 39 +---------- winsup/cygwin/init.cc | 6 +- winsup/cygwin/mmap.cc | 2 +- winsup/cygwin/path.cc | 16 ++--- winsup/cygwin/pinfo.cc | 15 ++--- winsup/cygwin/pipe.cc | 114 ++++++++++++++++----------------- winsup/cygwin/security.cc | 6 +- winsup/cygwin/select.cc | 100 ++++++++++++++--------------- winsup/cygwin/sigproc.cc | 15 ++++- winsup/cygwin/sigproc.h | 4 +- winsup/cygwin/spawn.cc | 13 +++- winsup/cygwin/syscalls.cc | 4 +- winsup/cygwin/uname.cc | 6 +- 21 files changed, 235 insertions(+), 216 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a0f1e778b..9012c741f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,36 @@ +2004-09-11 Pierre Humblet + Christopher Faylor + + * exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess + is starting. + +2004-09-10 Christopher Faylor + + * child_info.h (init_child_info): Remove pid argument from declaration. + * cygheap.h (init_cygheap::pid): New element. + * dcrt0.cc (dll_crt0_0): Eliminate handling of now-noexistent cygpid + parameter in child_info struct. Set forkee to 'true' rather than cygpid + since the pid value was never used. + (dll_crt0_1): Ditto. + (_dll_crt0): Ditto. + * fork.cc (fork_child): Don't wait for sigthread. This is handled in + the fork call now. + (fork_parent): Remove obsolete pid argument from init_child_info call. Don't + do anything special with cygpid when DEBUGGING. + (fork): Delay all signals during fork. + (fork_init): Don't do anything special when DEBUGGING. + * pinfo.cc (set_myself): Remove pid parameter. Use new pid field in + cygheap. + (pinfo_init): Don't pass pid argument to set_myself. + * sigproc.cc (sig_send): Wait for dwProcessId to be non-zero as well as + sendsig. + (init_child_info): Eliminate handling of pid. + (wait_sig): Implement method to temporarily hold off sending signals. + * sigproc.h (__SIGHOLD): New enum. + (__SIGNOHOLD): Ditto. + * spawn.cc (spawn_guts): Remove obsolete pid argument from + init_child_info call. + 2004-09-10 Corinna Vinschen * fhandler.cc (fhandler_base::dup): Use debug_printf. diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index fa9257bdc..66676caac 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -42,7 +42,6 @@ public: DWORD intro; // improbable string unsigned long magic; // magic number unique to child_info unsigned short type; // type of record, exec, spawn, fork - int cygpid; // cygwin pid of child process HANDLE subproc_ready; // used for synchronization with parent HANDLE user_h; HANDLE parent; @@ -105,7 +104,7 @@ public: } }; -void __stdcall init_child_info (DWORD, child_info *, int, HANDLE); +void __stdcall init_child_info (DWORD, child_info *, HANDLE); extern child_info *child_proc_info; extern child_info_spawn *spawn_info __attribute__ ((alias ("child_proc_info"))); diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index c19a51ae2..b8203bf08 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -277,6 +277,7 @@ struct init_cygheap struct _cygtls **threadlist; size_t sthreads; int open_fhs; + pid_t pid; /* my pid */ void close_ctty (); }; diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 93568f5fd..2ab6eb610 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -605,7 +605,6 @@ dll_crt0_0 () GetStartupInfo (&si); child_proc_info = (child_info *) si.lpReserved2; - int mypid = 0; if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info || memcmp (child_proc_info->zero, zeros, sizeof (child_proc_info->zero)) != 0) @@ -625,7 +624,7 @@ dll_crt0_0 () switch (child_proc_info->type) { case _PROC_FORK: - user_data->forkee = child_proc_info->cygpid; + user_data->forkee = true; should_be_cb = sizeof (child_info_fork); /* fall through */; case _PROC_SPAWN: @@ -639,7 +638,6 @@ dll_crt0_0 () else { cygwin_user_h = child_proc_info->user_h; - mypid = child_proc_info->cygpid; break; } default: @@ -667,7 +665,7 @@ dll_crt0_0 () alloc_stack (fork_info); cygheap_fixup_in_child (false); memory_init (); - set_myself (mypid); + set_myself (NULL); close_ppid_handle = !!child_proc_info->pppid_handle; break; case _PROC_SPAWN: @@ -686,7 +684,7 @@ dll_crt0_0 () hMainProc, &h, 0, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) h = NULL; - set_myself (mypid, h); + set_myself (h); __argc = spawn_info->moreinfo->argc; __argv = spawn_info->moreinfo->argv; envp = spawn_info->moreinfo->envp; @@ -771,7 +769,7 @@ dll_crt0_1 (char *) _tlsbase = (char *) fork_info->stackbottom; _tlstop = (char *) fork_info->stacktop; } - longjmp (fork_info->jmp, fork_info->cygpid); + longjmp (fork_info->jmp, true); } #ifdef DEBUGGING @@ -934,7 +932,7 @@ _dll_crt0 () _impure_ptr->_current_locale = "C"; if (child_proc_info && child_proc_info->type == _PROC_FORK) - user_data->forkee = child_proc_info->cygpid; + user_data->forkee = true; else __sinit (_impure_ptr); diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 64846553a..1a065f720 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -805,6 +805,8 @@ ctrl_c_handler (DWORD type) if (!cygwin_finished_initializing) { + if (myself->ppid_handle) /* Was this process created by a cygwin process? */ + return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */ debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT); ExitProcess (STATUS_CONTROL_C_EXIT); } diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 31d77d7e2..56627d673 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -484,10 +484,10 @@ fhandler_base::open_9x (int flags, mode_t mode) { /* If mode has no write bits set, we set the R/O attribute. */ if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH))) - file_attributes |= FILE_ATTRIBUTE_READONLY; + file_attributes |= FILE_ATTRIBUTE_READONLY; /* The file attributes are needed for later use in, e.g. fchmod. */ pc.file_attributes (file_attributes & FILE_ATTRIBUTE_VALID_SET_FLAGS); - } + } x = CreateFile (get_win32_name (), access, shared, &sa, creation_distribution, file_attributes, 0); @@ -818,7 +818,7 @@ fhandler_base::write (const void *ptr, size_t len) on any OS. */ /* Check there is enough space */ if (!SetEndOfFile (get_output_handle ())) - { + { __seterrno (); return -1; } @@ -837,7 +837,7 @@ fhandler_base::write (const void *ptr, size_t len) if (!ret || written < zeros_this_time) { if (!ret) - { + { __seterrno (); if (get_errno () == EPIPE) raise (SIGPIPE); diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc index 8c6404308..6a10a24f9 100644 --- a/winsup/cygwin/fhandler_dsp.cc +++ b/winsup/cygwin/fhandler_dsp.cc @@ -882,7 +882,7 @@ fhandler_dev_dsp::Audio_in::waitfordata () if (pHdr->dwFlags) /* Zero if queued following error in queueblock */ { /* Errors are ignored here. They will probbaly cause a failure - in the subsequent PrepareHeader */ + in the subsequent PrepareHeader */ rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR)); debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr); } @@ -1149,7 +1149,7 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr) CASE (SNDCTL_DSP_RESET) close_audio_in (); close_audio_out (true); - return 0; + return 0; break; CASE (SNDCTL_DSP_GETBLKSIZE) @@ -1328,8 +1328,8 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr) CASE (SNDCTL_DSP_SYNC) // Stop audio out device close_audio_out (); - // Stop audio in device - close_audio_in (); + // Stop audio in device + close_audio_in (); return 0; default: diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index 464d67d04..0443240d2 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -849,36 +849,36 @@ format_proc_cpuinfo (char *destbuf, size_t maxsize) if (features1 & (1 << 25)) print (" sse"); if (is_intel) - { - if (features1 & (1 << 26)) + { + if (features1 & (1 << 26)) print (" sse2"); - if (features1 & (1 << 27)) + if (features1 & (1 << 27)) print (" ss"); - if (features1 & (1 << 28)) + if (features1 & (1 << 28)) print (" htt"); - if (features1 & (1 << 29)) + if (features1 & (1 << 29)) print (" tmi"); - if (features1 & (1 << 30)) + if (features1 & (1 << 30)) print (" ia-64"); - if (features1 & (1 << 31)) + if (features1 & (1 << 31)) print (" pbe"); - if (features2 & (1 << 0)) + if (features2 & (1 << 0)) print (" pni"); - if (features2 & (1 << 3)) + if (features2 & (1 << 3)) print (" monitor"); - if (features2 & (1 << 4)) + if (features2 & (1 << 4)) print (" ds_cpl"); if (features2 & (1 << 7)) print (" tm2"); - if (features2 & (1 << 8)) + if (features2 & (1 << 8)) print (" est"); - if (features2 & (1 << 10)) + if (features2 & (1 << 10)) print (" cid"); - } + } if (is_amd && maxe >= 0x80000001) - { + { // uses AMD extended calls to check // for 3dnow and 3dnow extended support // (source: AMD Athlon Processor Recognition Application Note) @@ -887,14 +887,14 @@ format_proc_cpuinfo (char *destbuf, size_t maxsize) { cpuid (&unused, &unused, &unused, &features2, 0x80000001); - if (features2 & (1 << 11)) - print (" syscall"); - if (features2 & (1 << 19)) - print (" mp"); - if (features2 & (1 << 22)) - print (" mmxext"); - if (features2 & (1 << 29)) - print (" lm"); + if (features2 & (1 << 11)) + print (" syscall"); + if (features2 & (1 << 19)) + print (" mp"); + if (features2 & (1 << 22)) + print (" mmxext"); + if (features2 & (1 << 29)) + print (" lm"); if (features2 & (1 << 30)) // 31th bit is on print (" 3dnowext"); if (features2 & (1 << 31)) // 32th bit (highest) is on diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 1fcca437e..a2571a964 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -31,12 +31,6 @@ details. */ #include "cygmalloc.h" #include "cygthread.h" -#ifdef DEBUGGING -static int npid; -static int npid_max; -static pid_t fork_pids[100]; -#endif - /* Timeout to wait for child to start, parent to init child, etc. */ /* FIXME: Once things stabilize, bump up to a few minutes. */ #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */ @@ -318,7 +312,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls) pthread::atforkchild (); fixup_timers_after_fork (); - wait_for_sigthread (); cygbench ("fork-child"); cygwin_finished_initializing = true; return 0; @@ -425,7 +418,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, ProtectHandleINH (subproc_ready); ProtectHandleINH (forker_finished); - init_child_info (PROC_FORK, &ch, 1, subproc_ready); + init_child_info (PROC_FORK, &ch, subproc_ready); ch.forker_finished = forker_finished; @@ -439,23 +432,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll, cygheap->user.deimpersonate (); ch.parent = hParent; -#ifdef DEBUGGING - if (npid_max) - { - for (int pass = 0; pass < 2; pass++) - { - pid_t pid; - while ((pid = fork_pids[npid++])) - if (!pinfo (pid)) - { - ch.cygpid = pid; - goto out; - } - npid = 0; - } - } - out: -#endif syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)", myself->progname, myself->progname, c_flags, &si, &pi); @@ -499,11 +475,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, ResumeThread (pi.hThread); } -#ifdef DEBUGGING - int forked_pid = ch.cygpid != 1 ? ch.cygpid : cygwin_pid (pi.dwProcessId); -#else int forked_pid = cygwin_pid (pi.dwProcessId); -#endif pinfo forked (forked_pid, 1); if (!forked) @@ -665,11 +637,13 @@ fork () child_info_fork ch; + sig_send (NULL, __SIGHOLD); int res = setjmp (ch.jmp); if (res) res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls); else res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch); + sig_send (NULL, __SIGNOHOLD); MALLOC_CHECK; syscall_printf ("%d = fork()", res); @@ -679,13 +653,6 @@ fork () void fork_init () { - char buf[1024]; - if (!GetEnvironmentVariable ("CYGWIN_FORK_PIDS", buf, 1024)) - return; - pid_t pid; - char *p, *pe; - for (p = buf; (pid = strtol (p, &pe, 10)); p = pe) - fork_pids[npid_max++] = pid; } #endif /*DEBUGGING*/ diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index d0842a7ed..cc8687032 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -116,10 +116,10 @@ dll_entry (HANDLE h, DWORD reason, void *static_load) { case DLL_PROCESS_ATTACH: /* Is the stack at an unusual high address? Check if we're running on - a 64 bit machine. If so, respawn. */ + a 64 bit machine. If so, respawn. */ if (&is_64bit_machine >= (PBOOL) 0x400000 - && IsWow64Process (hMainProc, &is_64bit_machine) - && is_64bit_machine) + && IsWow64Process (hMainProc, &is_64bit_machine) + && is_64bit_machine) respawn_wow64_process (); prime_threads (); diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index ae6a78d1d..d46ddd21e 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -797,7 +797,7 @@ mprotect (void *addr, size_t len, int prot) { MEMORY_BASIC_INFORMATION mbi; if (VirtualQuery (addr, &mbi, sizeof mbi)) - { + { if (mbi.AllocationProtect == PAGE_WRITECOPY || mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY) writecopy = true; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 375ba7ee2..769c197c4 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -981,14 +981,14 @@ normalize_win32_path (const char *src, char *dst, char **tail) else if (strchr (src, ':') == NULL && *src != '/') { if (beg_src_slash) - dst += cygheap->cwd.get_drive (dst); + dst += cygheap->cwd.get_drive (dst); else if (!cygheap->cwd.get (dst, 0)) return get_errno (); else - { - dst += strlen (dst); - *dst++ = '\\'; - } + { + dst += strlen (dst); + *dst++ = '\\'; + } } while (*src) @@ -1508,11 +1508,11 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, return err; chroot_ok = true; } - else + else { int offset = 0; if (src_path[1] != '/' && src_path[1] != ':') - offset = cygheap->cwd.get_drive (dst); + offset = cygheap->cwd.get_drive (dst); backslashify (src_path, dst + offset, 0); } out: @@ -2189,7 +2189,7 @@ mount_info::add_item (const char *native, const char *posix, unsigned mountflags posixerr = normalize_posix_path (posix, posixtmp, &posixtail); debug_printf ("%s[%s], %s[%s], %p", - native, nativeerr ? error : nativetmp, + native, nativeerr ? error : nativetmp, posix, posixerr ? error : posixtmp, mountflags); if (nativeerr || posixerr) diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 4156ef022..1ed4f0a7c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -44,7 +44,7 @@ pinfo_fixup_after_fork () { if (hexec_proc) CloseHandle (hexec_proc); - /* Keeps the cygpid from being reused. No rights required */ + /* Keeps the cygpid from being reused. No rights required */ if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0, TRUE, 0)) { @@ -58,19 +58,18 @@ pinfo_fixup_after_fork () This is done once when the dll is first loaded. */ void __stdcall -set_myself (pid_t pid, HANDLE h) +set_myself (HANDLE h) { - DWORD winpid = GetCurrentProcessId (); - if (pid == 1) - pid = cygwin_pid (winpid); - myself.init (pid, PID_IN_USE | PID_MYSELF, h); - myself->dwProcessId = winpid; + if (!h) + cygheap->pid = cygwin_pid (GetCurrentProcessId ()); + myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h); myself->process_state |= PID_IN_USE; myself->start_time = time (NULL); /* Register our starting time. */ (void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname)); if (!strace.active) strace.hello (); + debug_printf ("myself->dwProcessId %u", myself->dwProcessId); InitializeCriticalSection (&myself->lock); return; } @@ -90,7 +89,7 @@ pinfo_init (char **envp, int envc) { /* Invent our own pid. */ - set_myself (1); + set_myself (NULL); myself->ppid = 1; myself->pgid = myself->sid = myself->pid; myself->ctty = -1; diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index aff3dd156..a55645eb7 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -223,9 +223,9 @@ leave: unlike CreatePipe, which returns a bool for success or failure. */ static int create_selectable_pipe (PHANDLE read_pipe_ptr, - PHANDLE write_pipe_ptr, - LPSECURITY_ATTRIBUTES sa_ptr, - DWORD psize) + PHANDLE write_pipe_ptr, + LPSECURITY_ATTRIBUTES sa_ptr, + DWORD psize) { /* Default to error. */ *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE; @@ -251,62 +251,62 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, debug_printf ("CreateNamedPipe: name %s, size %lu", pipename, psize); /* Use CreateNamedPipe instead of CreatePipe, because the latter - returns a write handle that does not permit FILE_READ_ATTRIBUTES - access, on versions of win32 earlier than WinXP SP2. - CreatePipe also stupidly creates a full duplex pipe, which is - a waste, since only a single direction is actually used. - It's important to only allow a single instance, to ensure that - the pipe was not created earlier by some other process, even if - the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE - because that is only available for Win2k SP2 and WinXP. */ + returns a write handle that does not permit FILE_READ_ATTRIBUTES + access, on versions of win32 earlier than WinXP SP2. + CreatePipe also stupidly creates a full duplex pipe, which is + a waste, since only a single direction is actually used. + It's important to only allow a single instance, to ensure that + the pipe was not created earlier by some other process, even if + the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE + because that is only available for Win2k SP2 and WinXP. */ SetLastError (0); read_pipe = CreateNamedPipe (pipename, - PIPE_ACCESS_INBOUND, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, - 1, /* max instances */ - psize, /* output buffer size */ - psize, /* input buffer size */ - NMPWAIT_USE_DEFAULT_WAIT, - sa_ptr); + PIPE_ACCESS_INBOUND, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, + 1, /* max instances */ + psize, /* output buffer size */ + psize, /* input buffer size */ + NMPWAIT_USE_DEFAULT_WAIT, + sa_ptr); DWORD err = GetLastError (); /* Win 95 seems to return NULL instead of INVALID_HANDLE_VALUE */ if ((read_pipe || !err) && read_pipe != INVALID_HANDLE_VALUE) - { - debug_printf ("pipe read handle %p", read_pipe); - break; - } + { + debug_printf ("pipe read handle %p", read_pipe); + break; + } switch (err) - { - case ERROR_PIPE_BUSY: - /* The pipe is already open with compatible parameters. - Pick a new name and retry. */ - debug_printf ("pipe busy, retrying"); - continue; - case ERROR_ACCESS_DENIED: - /* The pipe is already open with incompatible parameters. - Pick a new name and retry. */ - debug_printf ("pipe access denied, retrying"); - continue; - case ERROR_CALL_NOT_IMPLEMENTED: - /* We are on an older Win9x platform without named pipes. - Return an anonymous pipe as the best approximation. */ - debug_printf ("CreateNamedPipe not implemented, resorting to " - "CreatePipe size %lu", psize); - if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize)) - { - debug_printf ("pipe read handle %p", *read_pipe_ptr); - debug_printf ("pipe write handle %p", *write_pipe_ptr); - return NO_ERROR; - } - err = GetLastError (); - debug_printf ("CreatePipe failed, %E"); - return err; - default: - debug_printf ("CreateNamedPipe failed, %E"); - return err; - } + { + case ERROR_PIPE_BUSY: + /* The pipe is already open with compatible parameters. + Pick a new name and retry. */ + debug_printf ("pipe busy, retrying"); + continue; + case ERROR_ACCESS_DENIED: + /* The pipe is already open with incompatible parameters. + Pick a new name and retry. */ + debug_printf ("pipe access denied, retrying"); + continue; + case ERROR_CALL_NOT_IMPLEMENTED: + /* We are on an older Win9x platform without named pipes. + Return an anonymous pipe as the best approximation. */ + debug_printf ("CreateNamedPipe not implemented, resorting to " + "CreatePipe size %lu", psize); + if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize)) + { + debug_printf ("pipe read handle %p", *read_pipe_ptr); + debug_printf ("pipe write handle %p", *write_pipe_ptr); + return NO_ERROR; + } + err = GetLastError (); + debug_printf ("CreatePipe failed, %E"); + return err; + default: + debug_printf ("CreateNamedPipe failed, %E"); + return err; + } /* NOTREACHED */ } @@ -315,12 +315,12 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, /* Open the named pipe for writing. Be sure to permit FILE_READ_ATTRIBUTES access. */ write_pipe = CreateFile (pipename, - GENERIC_WRITE | FILE_READ_ATTRIBUTES, - 0, /* share mode */ - sa_ptr, - OPEN_EXISTING, - 0, /* flags and attributes */ - 0); /* handle to template file */ + GENERIC_WRITE | FILE_READ_ATTRIBUTES, + 0, /* share mode */ + sa_ptr, + OPEN_EXISTING, + 0, /* flags and attributes */ + 0); /* handle to template file */ if (write_pipe == INVALID_HANDLE_VALUE) { diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index d6ff4f699..73619aa9c 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -163,8 +163,8 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr) { tgt.Buffer = (PWCHAR) buf; tgt.MaximumLength = (strlen (srcstr) + 1) * sizeof (WCHAR); - tgt.Length = sys_mbstowcs (buf, srcstr, tgt.MaximumLength / sizeof (WCHAR)) - * sizeof (WCHAR); + tgt.Length = sys_mbstowcs (buf, srcstr, tgt.MaximumLength / sizeof (WCHAR)) + * sizeof (WCHAR); if (tgt.Length) tgt.Length -= sizeof (WCHAR); } @@ -173,7 +173,7 @@ void str2uni_cat (UNICODE_STRING &tgt, const char *srcstr) { int len = sys_mbstowcs (tgt.Buffer + tgt.Length / sizeof (WCHAR), srcstr, - (tgt.MaximumLength - tgt.Length) / sizeof (WCHAR)); + (tgt.MaximumLength - tgt.Length) / sizeof (WCHAR)); if (len) tgt.Length += (len - 1) * sizeof (WCHAR); else diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index e2d11a408..95ee14161 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -507,63 +507,63 @@ out: if (s->write_selected) { if (s->write_ready) - { - select_printf ("%s, already ready for write", fh->get_name ()); - gotone++; - } + { + select_printf ("%s, already ready for write", fh->get_name ()); + gotone++; + } /* Do we need to do anything about SIGTTOU here? */ else if (fh->get_device () == FH_PIPER) select_printf ("%s, select for write on read end of pipe", fh->get_name ()); else - { - /* We don't worry about the guard mutex, because that only applies - when from_select is false, and peek_pipe is never called that - way for writes. */ + { + /* We don't worry about the guard mutex, because that only applies + when from_select is false, and peek_pipe is never called that + way for writes. */ - IO_STATUS_BLOCK iosb = {0}; - FILE_PIPE_LOCAL_INFORMATION fpli = {0}; + IO_STATUS_BLOCK iosb = {0}; + FILE_PIPE_LOCAL_INFORMATION fpli = {0}; - if (NtQueryInformationFile (h, - &iosb, - &fpli, - sizeof (fpli), - FilePipeLocalInformation)) - { - /* If NtQueryInformationFile fails, optimistically assume the - pipe is writable. This could happen on Win9x, because - NtQueryInformationFile is not available, or if we somehow - inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES - access on the write end. */ - select_printf ("%s, NtQueryInformationFile failed", - fh->get_name ()); - gotone += s->write_ready = true; - } - /* Ensure that enough space is available for atomic writes, - as required by POSIX. Subsequent writes with size > PIPE_BUF - can still block, but most (all?) UNIX variants seem to work - this way (e.g., BSD, Linux, Solaris). */ - else if (fpli.WriteQuotaAvailable >= PIPE_BUF) - { - select_printf ("%s, ready for write: size %lu, avail %lu", - fh->get_name (), - fpli.OutboundQuota, - fpli.WriteQuotaAvailable); - gotone += s->write_ready = true; - } - /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider - the pipe writable only if it is completely empty, to minimize the - probability that a subsequent write will block. */ - else if (fpli.OutboundQuota < PIPE_BUF && - fpli.WriteQuotaAvailable == fpli.OutboundQuota) - { - select_printf ("%s, tiny pipe: size %lu, avail %lu", - fh->get_name (), - fpli.OutboundQuota, - fpli.WriteQuotaAvailable); - gotone += s->write_ready = true; - } - } + if (NtQueryInformationFile (h, + &iosb, + &fpli, + sizeof (fpli), + FilePipeLocalInformation)) + { + /* If NtQueryInformationFile fails, optimistically assume the + pipe is writable. This could happen on Win9x, because + NtQueryInformationFile is not available, or if we somehow + inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES + access on the write end. */ + select_printf ("%s, NtQueryInformationFile failed", + fh->get_name ()); + gotone += s->write_ready = true; + } + /* Ensure that enough space is available for atomic writes, + as required by POSIX. Subsequent writes with size > PIPE_BUF + can still block, but most (all?) UNIX variants seem to work + this way (e.g., BSD, Linux, Solaris). */ + else if (fpli.WriteQuotaAvailable >= PIPE_BUF) + { + select_printf ("%s, ready for write: size %lu, avail %lu", + fh->get_name (), + fpli.OutboundQuota, + fpli.WriteQuotaAvailable); + gotone += s->write_ready = true; + } + /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider + the pipe writable only if it is completely empty, to minimize the + probability that a subsequent write will block. */ + else if (fpli.OutboundQuota < PIPE_BUF && + fpli.WriteQuotaAvailable == fpli.OutboundQuota) + { + select_printf ("%s, tiny pipe: size %lu, avail %lu", + fh->get_name (), + fpli.OutboundQuota, + fpli.WriteQuotaAvailable); + gotone += s->write_ready = true; + } + } } return gotone; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 47096f086..e9fec6643 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -707,6 +707,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) sendsig = myself->sendsig; else { + for (int i = 0; !p->dwProcessId && i < 10000; i++) + low_priority_sleep (0); HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId); if (!hp) { @@ -854,14 +856,13 @@ subproc_init (void) by fork/spawn/exec. */ void __stdcall -init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready) +init_child_info (DWORD chtype, child_info *ch, HANDLE subproc_ready) { memset (ch, 0, sizeof *ch); ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info); ch->intro = PROC_MAGIC_GENERIC; ch->magic = CHILD_INFO_MAGIC; ch->type = chtype; - ch->cygpid = pid; ch->subproc_ready = subproc_ready; ch->pppid_handle = myself->ppid_handle; ch->fhandler_union_cb = sizeof (fhandler_union); @@ -1064,6 +1065,7 @@ wait_sig (VOID *self) { HANDLE readsig; char sa_buf[1024]; + Static bool holding_signals; /* Initialization */ (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); @@ -1080,6 +1082,7 @@ wait_sig (VOID *self) myself->process_state |= PID_ACTIVE; myself->process_state &= ~PID_INITIALIZING; + sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId); /* If we've been execed, then there is still a stub left in the previous windows process waiting to see if it's started a cygwin process or not. Signalling subproc_ready indicates that we are a cygwin process. */ @@ -1159,9 +1162,17 @@ wait_sig (VOID *self) if (q->si.si_signo == __SIGDELETE || q->process () > 0) sigq.del (); break; + case __SIGHOLD: + holding_signals = 1; + break; + case __SIGNOHOLD: + holding_signals = 0; + break; default: if (pack.si.si_signo < 0) sig_clear (-pack.si.si_signo); + else if (holding_signals) + sigq.add (pack); else { int sig = pack.si.si_signo; diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 4e70dea6b..776d1d9dc 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -24,7 +24,9 @@ enum __SIGCOMMUNE = -(NSIG + 3), __SIGPENDING = -(NSIG + 4), __SIGDELETE = -(NSIG + 5), - __SIGFLUSHFAST = -(NSIG + 6) + __SIGFLUSHFAST = -(NSIG + 6), + __SIGHOLD = -(NSIG + 7), + __SIGNOHOLD = -(NSIG + 8) }; #endif diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 4e876c8d0..0766b40a7 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -393,8 +393,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, ProtectHandleINH (subproc_ready); } - init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, - subproc_ready); + init_child_info (chtype, &ciresrv, subproc_ready); ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info)); ciresrv.moreinfo->old_title = NULL; @@ -630,6 +629,10 @@ spawn_guts (const char * prog_arg, const char *const *argv, flags |= DETACHED_PROCESS; if (mode != _P_OVERLAY) flags |= CREATE_SUSPENDED; +#if 0 //someday + else + myself->dwProcessId = 0; +#endif /* Some file types (currently only sockets) need extra effort in the parent after CreateProcess and before copying the datastructures @@ -638,7 +641,6 @@ spawn_guts (const char * prog_arg, const char *const *argv, if (cygheap->fdtab.need_fixup_before ()) flags |= CREATE_SUSPENDED; - const char *runpath = null_app_name ? NULL : (const char *) real_path; syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf); @@ -649,6 +651,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, cygheap->fdtab.set_file_pointers_for_exec (); cygheap->user.deimpersonate (); + /* When ruid != euid we create the new process under the current original account and impersonate in child, this way maintaining the different effective vs. real ids. @@ -729,6 +732,10 @@ spawn_guts (const char * prog_arg, const char *const *argv, { __seterrno (); syscall_printf ("CreateProcess failed, %E"); +#if 0 // someday + if (mode == _P_OVERLAY) + myself->dwProcessId = GetCurrentProcessId (); +#endif if (subproc_ready) ForceCloseHandle (subproc_ready); cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 04291d2d0..ddb0da7d3 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -712,7 +712,7 @@ link (const char *a, const char *b) goto docopy; } if (GetLastError () != ERROR_PROC_NOT_FOUND) - { + { syscall_printf ("CreateHardLinkA failed"); __seterrno (); goto done; @@ -804,7 +804,7 @@ link (const char *a, const char *b) CloseHandle (hFileSource); if (!bSuccess) - { + { /* Only copy file if FS doesn't support hard links */ if (write_err == ERROR_INVALID_FUNCTION) { diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index 65708f018..caf951d8f 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -79,13 +79,13 @@ uname (struct utsname *name) __small_sprintf (name->machine, "i%d86", ptype); break; case PROCESSOR_ARCHITECTURE_IA64: - strcpy (name->machine, "ia64"); + strcpy (name->machine, "ia64"); break; case PROCESSOR_ARCHITECTURE_AMD64: - strcpy (name->machine, "amd64"); + strcpy (name->machine, "amd64"); break; case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: - strcpy (name->machine, "ia32-win64"); + strcpy (name->machine, "ia32-win64"); case PROCESSOR_ARCHITECTURE_ALPHA: strcpy (name->machine, "alpha"); break;