* 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.
This commit is contained in:
Christopher Faylor 2004-09-12 03:47:57 +00:00
parent ca5ec6685a
commit d584454c82
21 changed files with 235 additions and 216 deletions

View File

@ -1,3 +1,36 @@
2004-09-11 Pierre Humblet <pierre.humblet@ieee.org>
Christopher Faylor <cgf@timesys.com>
* exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess
is starting.
2004-09-10 Christopher Faylor <cgf@timesys.com>
* 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 <corinna@vinschen.de> 2004-09-10 Corinna Vinschen <corinna@vinschen.de>
* fhandler.cc (fhandler_base::dup): Use debug_printf. * fhandler.cc (fhandler_base::dup): Use debug_printf.

View File

@ -42,7 +42,6 @@ public:
DWORD intro; // improbable string DWORD intro; // improbable string
unsigned long magic; // magic number unique to child_info unsigned long magic; // magic number unique to child_info
unsigned short type; // type of record, exec, spawn, fork 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 subproc_ready; // used for synchronization with parent
HANDLE user_h; HANDLE user_h;
HANDLE parent; 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 *child_proc_info;
extern child_info_spawn *spawn_info __attribute__ ((alias ("child_proc_info"))); extern child_info_spawn *spawn_info __attribute__ ((alias ("child_proc_info")));

View File

@ -277,6 +277,7 @@ struct init_cygheap
struct _cygtls **threadlist; struct _cygtls **threadlist;
size_t sthreads; size_t sthreads;
int open_fhs; int open_fhs;
pid_t pid; /* my pid */
void close_ctty (); void close_ctty ();
}; };

View File

@ -605,7 +605,6 @@ dll_crt0_0 ()
GetStartupInfo (&si); GetStartupInfo (&si);
child_proc_info = (child_info *) si.lpReserved2; child_proc_info = (child_info *) si.lpReserved2;
int mypid = 0;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
|| memcmp (child_proc_info->zero, zeros, || memcmp (child_proc_info->zero, zeros,
sizeof (child_proc_info->zero)) != 0) sizeof (child_proc_info->zero)) != 0)
@ -625,7 +624,7 @@ dll_crt0_0 ()
switch (child_proc_info->type) switch (child_proc_info->type)
{ {
case _PROC_FORK: case _PROC_FORK:
user_data->forkee = child_proc_info->cygpid; user_data->forkee = true;
should_be_cb = sizeof (child_info_fork); should_be_cb = sizeof (child_info_fork);
/* fall through */; /* fall through */;
case _PROC_SPAWN: case _PROC_SPAWN:
@ -639,7 +638,6 @@ dll_crt0_0 ()
else else
{ {
cygwin_user_h = child_proc_info->user_h; cygwin_user_h = child_proc_info->user_h;
mypid = child_proc_info->cygpid;
break; break;
} }
default: default:
@ -667,7 +665,7 @@ dll_crt0_0 ()
alloc_stack (fork_info); alloc_stack (fork_info);
cygheap_fixup_in_child (false); cygheap_fixup_in_child (false);
memory_init (); memory_init ();
set_myself (mypid); set_myself (NULL);
close_ppid_handle = !!child_proc_info->pppid_handle; close_ppid_handle = !!child_proc_info->pppid_handle;
break; break;
case _PROC_SPAWN: case _PROC_SPAWN:
@ -686,7 +684,7 @@ dll_crt0_0 ()
hMainProc, &h, 0, FALSE, hMainProc, &h, 0, FALSE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL; h = NULL;
set_myself (mypid, h); set_myself (h);
__argc = spawn_info->moreinfo->argc; __argc = spawn_info->moreinfo->argc;
__argv = spawn_info->moreinfo->argv; __argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->envp; envp = spawn_info->moreinfo->envp;
@ -771,7 +769,7 @@ dll_crt0_1 (char *)
_tlsbase = (char *) fork_info->stackbottom; _tlsbase = (char *) fork_info->stackbottom;
_tlstop = (char *) fork_info->stacktop; _tlstop = (char *) fork_info->stacktop;
} }
longjmp (fork_info->jmp, fork_info->cygpid); longjmp (fork_info->jmp, true);
} }
#ifdef DEBUGGING #ifdef DEBUGGING
@ -934,7 +932,7 @@ _dll_crt0 ()
_impure_ptr->_current_locale = "C"; _impure_ptr->_current_locale = "C";
if (child_proc_info && child_proc_info->type == _PROC_FORK) if (child_proc_info && child_proc_info->type == _PROC_FORK)
user_data->forkee = child_proc_info->cygpid; user_data->forkee = true;
else else
__sinit (_impure_ptr); __sinit (_impure_ptr);

View File

@ -805,6 +805,8 @@ ctrl_c_handler (DWORD type)
if (!cygwin_finished_initializing) 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); debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
ExitProcess (STATUS_CONTROL_C_EXIT); ExitProcess (STATUS_CONTROL_C_EXIT);
} }

View File

@ -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 has no write bits set, we set the R/O attribute. */
if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH))) 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. */ /* The file attributes are needed for later use in, e.g. fchmod. */
pc.file_attributes (file_attributes & FILE_ATTRIBUTE_VALID_SET_FLAGS); pc.file_attributes (file_attributes & FILE_ATTRIBUTE_VALID_SET_FLAGS);
} }
x = CreateFile (get_win32_name (), access, shared, &sa, creation_distribution, x = CreateFile (get_win32_name (), access, shared, &sa, creation_distribution,
file_attributes, 0); file_attributes, 0);
@ -818,7 +818,7 @@ fhandler_base::write (const void *ptr, size_t len)
on any OS. */ on any OS. */
/* Check there is enough space */ /* Check there is enough space */
if (!SetEndOfFile (get_output_handle ())) if (!SetEndOfFile (get_output_handle ()))
{ {
__seterrno (); __seterrno ();
return -1; return -1;
} }
@ -837,7 +837,7 @@ fhandler_base::write (const void *ptr, size_t len)
if (!ret || written < zeros_this_time) if (!ret || written < zeros_this_time)
{ {
if (!ret) if (!ret)
{ {
__seterrno (); __seterrno ();
if (get_errno () == EPIPE) if (get_errno () == EPIPE)
raise (SIGPIPE); raise (SIGPIPE);

View File

@ -882,7 +882,7 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
if (pHdr->dwFlags) /* Zero if queued following error in queueblock */ if (pHdr->dwFlags) /* Zero if queued following error in queueblock */
{ {
/* Errors are ignored here. They will probbaly cause a failure /* Errors are ignored here. They will probbaly cause a failure
in the subsequent PrepareHeader */ in the subsequent PrepareHeader */
rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR)); rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr); 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) CASE (SNDCTL_DSP_RESET)
close_audio_in (); close_audio_in ();
close_audio_out (true); close_audio_out (true);
return 0; return 0;
break; break;
CASE (SNDCTL_DSP_GETBLKSIZE) CASE (SNDCTL_DSP_GETBLKSIZE)
@ -1328,8 +1328,8 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
CASE (SNDCTL_DSP_SYNC) CASE (SNDCTL_DSP_SYNC)
// Stop audio out device // Stop audio out device
close_audio_out (); close_audio_out ();
// Stop audio in device // Stop audio in device
close_audio_in (); close_audio_in ();
return 0; return 0;
default: default:

View File

@ -849,36 +849,36 @@ format_proc_cpuinfo (char *destbuf, size_t maxsize)
if (features1 & (1 << 25)) if (features1 & (1 << 25))
print (" sse"); print (" sse");
if (is_intel) if (is_intel)
{ {
if (features1 & (1 << 26)) if (features1 & (1 << 26))
print (" sse2"); print (" sse2");
if (features1 & (1 << 27)) if (features1 & (1 << 27))
print (" ss"); print (" ss");
if (features1 & (1 << 28)) if (features1 & (1 << 28))
print (" htt"); print (" htt");
if (features1 & (1 << 29)) if (features1 & (1 << 29))
print (" tmi"); print (" tmi");
if (features1 & (1 << 30)) if (features1 & (1 << 30))
print (" ia-64"); print (" ia-64");
if (features1 & (1 << 31)) if (features1 & (1 << 31))
print (" pbe"); print (" pbe");
if (features2 & (1 << 0)) if (features2 & (1 << 0))
print (" pni"); print (" pni");
if (features2 & (1 << 3)) if (features2 & (1 << 3))
print (" monitor"); print (" monitor");
if (features2 & (1 << 4)) if (features2 & (1 << 4))
print (" ds_cpl"); print (" ds_cpl");
if (features2 & (1 << 7)) if (features2 & (1 << 7))
print (" tm2"); print (" tm2");
if (features2 & (1 << 8)) if (features2 & (1 << 8))
print (" est"); print (" est");
if (features2 & (1 << 10)) if (features2 & (1 << 10))
print (" cid"); print (" cid");
} }
if (is_amd && maxe >= 0x80000001) if (is_amd && maxe >= 0x80000001)
{ {
// uses AMD extended calls to check // uses AMD extended calls to check
// for 3dnow and 3dnow extended support // for 3dnow and 3dnow extended support
// (source: AMD Athlon Processor Recognition Application Note) // (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); cpuid (&unused, &unused, &unused, &features2, 0x80000001);
if (features2 & (1 << 11)) if (features2 & (1 << 11))
print (" syscall"); print (" syscall");
if (features2 & (1 << 19)) if (features2 & (1 << 19))
print (" mp"); print (" mp");
if (features2 & (1 << 22)) if (features2 & (1 << 22))
print (" mmxext"); print (" mmxext");
if (features2 & (1 << 29)) if (features2 & (1 << 29))
print (" lm"); print (" lm");
if (features2 & (1 << 30)) // 31th bit is on if (features2 & (1 << 30)) // 31th bit is on
print (" 3dnowext"); print (" 3dnowext");
if (features2 & (1 << 31)) // 32th bit (highest) is on if (features2 & (1 << 31)) // 32th bit (highest) is on

View File

@ -31,12 +31,6 @@ details. */
#include "cygmalloc.h" #include "cygmalloc.h"
#include "cygthread.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. */ /* Timeout to wait for child to start, parent to init child, etc. */
/* FIXME: Once things stabilize, bump up to a few minutes. */ /* FIXME: Once things stabilize, bump up to a few minutes. */
#define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */ #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
@ -318,7 +312,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
pthread::atforkchild (); pthread::atforkchild ();
fixup_timers_after_fork (); fixup_timers_after_fork ();
wait_for_sigthread ();
cygbench ("fork-child"); cygbench ("fork-child");
cygwin_finished_initializing = true; cygwin_finished_initializing = true;
return 0; return 0;
@ -425,7 +418,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ProtectHandleINH (subproc_ready); ProtectHandleINH (subproc_ready);
ProtectHandleINH (forker_finished); 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; ch.forker_finished = forker_finished;
@ -439,23 +432,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
ch.parent = hParent; 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)", syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi); myself->progname, myself->progname, c_flags, &si, &pi);
@ -499,11 +475,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ResumeThread (pi.hThread); 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); int forked_pid = cygwin_pid (pi.dwProcessId);
#endif
pinfo forked (forked_pid, 1); pinfo forked (forked_pid, 1);
if (!forked) if (!forked)
@ -665,11 +637,13 @@ fork ()
child_info_fork ch; child_info_fork ch;
sig_send (NULL, __SIGHOLD);
int res = setjmp (ch.jmp); int res = setjmp (ch.jmp);
if (res) if (res)
res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls); res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
else else
res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch); res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch);
sig_send (NULL, __SIGNOHOLD);
MALLOC_CHECK; MALLOC_CHECK;
syscall_printf ("%d = fork()", res); syscall_printf ("%d = fork()", res);
@ -679,13 +653,6 @@ fork ()
void void
fork_init () 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*/ #endif /*DEBUGGING*/

View File

@ -116,10 +116,10 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
/* Is the stack at an unusual high address? Check if we're running on /* 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 if (&is_64bit_machine >= (PBOOL) 0x400000
&& IsWow64Process (hMainProc, &is_64bit_machine) && IsWow64Process (hMainProc, &is_64bit_machine)
&& is_64bit_machine) && is_64bit_machine)
respawn_wow64_process (); respawn_wow64_process ();
prime_threads (); prime_threads ();

View File

@ -797,7 +797,7 @@ mprotect (void *addr, size_t len, int prot)
{ {
MEMORY_BASIC_INFORMATION mbi; MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery (addr, &mbi, sizeof mbi)) if (VirtualQuery (addr, &mbi, sizeof mbi))
{ {
if (mbi.AllocationProtect == PAGE_WRITECOPY if (mbi.AllocationProtect == PAGE_WRITECOPY
|| mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY) || mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY)
writecopy = true; writecopy = true;

View File

@ -981,14 +981,14 @@ normalize_win32_path (const char *src, char *dst, char **tail)
else if (strchr (src, ':') == NULL && *src != '/') else if (strchr (src, ':') == NULL && *src != '/')
{ {
if (beg_src_slash) if (beg_src_slash)
dst += cygheap->cwd.get_drive (dst); dst += cygheap->cwd.get_drive (dst);
else if (!cygheap->cwd.get (dst, 0)) else if (!cygheap->cwd.get (dst, 0))
return get_errno (); return get_errno ();
else else
{ {
dst += strlen (dst); dst += strlen (dst);
*dst++ = '\\'; *dst++ = '\\';
} }
} }
while (*src) while (*src)
@ -1508,11 +1508,11 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
return err; return err;
chroot_ok = true; chroot_ok = true;
} }
else else
{ {
int offset = 0; int offset = 0;
if (src_path[1] != '/' && src_path[1] != ':') 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); backslashify (src_path, dst + offset, 0);
} }
out: out:
@ -2189,7 +2189,7 @@ mount_info::add_item (const char *native, const char *posix, unsigned mountflags
posixerr = normalize_posix_path (posix, posixtmp, &posixtail); posixerr = normalize_posix_path (posix, posixtmp, &posixtail);
debug_printf ("%s[%s], %s[%s], %p", debug_printf ("%s[%s], %s[%s], %p",
native, nativeerr ? error : nativetmp, native, nativeerr ? error : nativetmp,
posix, posixerr ? error : posixtmp, mountflags); posix, posixerr ? error : posixtmp, mountflags);
if (nativeerr || posixerr) if (nativeerr || posixerr)

View File

@ -44,7 +44,7 @@ pinfo_fixup_after_fork ()
{ {
if (hexec_proc) if (hexec_proc)
CloseHandle (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, if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
TRUE, 0)) TRUE, 0))
{ {
@ -58,19 +58,18 @@ pinfo_fixup_after_fork ()
This is done once when the dll is first loaded. */ This is done once when the dll is first loaded. */
void __stdcall void __stdcall
set_myself (pid_t pid, HANDLE h) set_myself (HANDLE h)
{ {
DWORD winpid = GetCurrentProcessId (); if (!h)
if (pid == 1) cygheap->pid = cygwin_pid (GetCurrentProcessId ());
pid = cygwin_pid (winpid); myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
myself.init (pid, PID_IN_USE | PID_MYSELF, h);
myself->dwProcessId = winpid;
myself->process_state |= PID_IN_USE; myself->process_state |= PID_IN_USE;
myself->start_time = time (NULL); /* Register our starting time. */ myself->start_time = time (NULL); /* Register our starting time. */
(void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname)); (void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
if (!strace.active) if (!strace.active)
strace.hello (); strace.hello ();
debug_printf ("myself->dwProcessId %u", myself->dwProcessId);
InitializeCriticalSection (&myself->lock); InitializeCriticalSection (&myself->lock);
return; return;
} }
@ -90,7 +89,7 @@ pinfo_init (char **envp, int envc)
{ {
/* Invent our own pid. */ /* Invent our own pid. */
set_myself (1); set_myself (NULL);
myself->ppid = 1; myself->ppid = 1;
myself->pgid = myself->sid = myself->pid; myself->pgid = myself->sid = myself->pid;
myself->ctty = -1; myself->ctty = -1;

View File

@ -223,9 +223,9 @@ leave:
unlike CreatePipe, which returns a bool for success or failure. */ unlike CreatePipe, which returns a bool for success or failure. */
static int static int
create_selectable_pipe (PHANDLE read_pipe_ptr, create_selectable_pipe (PHANDLE read_pipe_ptr,
PHANDLE write_pipe_ptr, PHANDLE write_pipe_ptr,
LPSECURITY_ATTRIBUTES sa_ptr, LPSECURITY_ATTRIBUTES sa_ptr,
DWORD psize) DWORD psize)
{ {
/* Default to error. */ /* Default to error. */
*read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE; *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); debug_printf ("CreateNamedPipe: name %s, size %lu", pipename, psize);
/* Use CreateNamedPipe instead of CreatePipe, because the latter /* Use CreateNamedPipe instead of CreatePipe, because the latter
returns a write handle that does not permit FILE_READ_ATTRIBUTES returns a write handle that does not permit FILE_READ_ATTRIBUTES
access, on versions of win32 earlier than WinXP SP2. access, on versions of win32 earlier than WinXP SP2.
CreatePipe also stupidly creates a full duplex pipe, which is CreatePipe also stupidly creates a full duplex pipe, which is
a waste, since only a single direction is actually used. a waste, since only a single direction is actually used.
It's important to only allow a single instance, to ensure that 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 pipe was not created earlier by some other process, even if
the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
because that is only available for Win2k SP2 and WinXP. */ because that is only available for Win2k SP2 and WinXP. */
SetLastError (0); SetLastError (0);
read_pipe = CreateNamedPipe (pipename, read_pipe = CreateNamedPipe (pipename,
PIPE_ACCESS_INBOUND, PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1, /* max instances */ 1, /* max instances */
psize, /* output buffer size */ psize, /* output buffer size */
psize, /* input buffer size */ psize, /* input buffer size */
NMPWAIT_USE_DEFAULT_WAIT, NMPWAIT_USE_DEFAULT_WAIT,
sa_ptr); sa_ptr);
DWORD err = GetLastError (); DWORD err = GetLastError ();
/* Win 95 seems to return NULL instead of INVALID_HANDLE_VALUE */ /* Win 95 seems to return NULL instead of INVALID_HANDLE_VALUE */
if ((read_pipe || !err) && read_pipe != INVALID_HANDLE_VALUE) if ((read_pipe || !err) && read_pipe != INVALID_HANDLE_VALUE)
{ {
debug_printf ("pipe read handle %p", read_pipe); debug_printf ("pipe read handle %p", read_pipe);
break; break;
} }
switch (err) switch (err)
{ {
case ERROR_PIPE_BUSY: case ERROR_PIPE_BUSY:
/* The pipe is already open with compatible parameters. /* The pipe is already open with compatible parameters.
Pick a new name and retry. */ Pick a new name and retry. */
debug_printf ("pipe busy, retrying"); debug_printf ("pipe busy, retrying");
continue; continue;
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
/* The pipe is already open with incompatible parameters. /* The pipe is already open with incompatible parameters.
Pick a new name and retry. */ Pick a new name and retry. */
debug_printf ("pipe access denied, retrying"); debug_printf ("pipe access denied, retrying");
continue; continue;
case ERROR_CALL_NOT_IMPLEMENTED: case ERROR_CALL_NOT_IMPLEMENTED:
/* We are on an older Win9x platform without named pipes. /* We are on an older Win9x platform without named pipes.
Return an anonymous pipe as the best approximation. */ Return an anonymous pipe as the best approximation. */
debug_printf ("CreateNamedPipe not implemented, resorting to " debug_printf ("CreateNamedPipe not implemented, resorting to "
"CreatePipe size %lu", psize); "CreatePipe size %lu", psize);
if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize)) if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
{ {
debug_printf ("pipe read handle %p", *read_pipe_ptr); debug_printf ("pipe read handle %p", *read_pipe_ptr);
debug_printf ("pipe write handle %p", *write_pipe_ptr); debug_printf ("pipe write handle %p", *write_pipe_ptr);
return NO_ERROR; return NO_ERROR;
} }
err = GetLastError (); err = GetLastError ();
debug_printf ("CreatePipe failed, %E"); debug_printf ("CreatePipe failed, %E");
return err; return err;
default: default:
debug_printf ("CreateNamedPipe failed, %E"); debug_printf ("CreateNamedPipe failed, %E");
return err; return err;
} }
/* NOTREACHED */ /* NOTREACHED */
} }
@ -315,12 +315,12 @@ create_selectable_pipe (PHANDLE read_pipe_ptr,
/* Open the named pipe for writing. /* Open the named pipe for writing.
Be sure to permit FILE_READ_ATTRIBUTES access. */ Be sure to permit FILE_READ_ATTRIBUTES access. */
write_pipe = CreateFile (pipename, write_pipe = CreateFile (pipename,
GENERIC_WRITE | FILE_READ_ATTRIBUTES, GENERIC_WRITE | FILE_READ_ATTRIBUTES,
0, /* share mode */ 0, /* share mode */
sa_ptr, sa_ptr,
OPEN_EXISTING, OPEN_EXISTING,
0, /* flags and attributes */ 0, /* flags and attributes */
0); /* handle to template file */ 0); /* handle to template file */
if (write_pipe == INVALID_HANDLE_VALUE) if (write_pipe == INVALID_HANDLE_VALUE)
{ {

View File

@ -163,8 +163,8 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
{ {
tgt.Buffer = (PWCHAR) buf; tgt.Buffer = (PWCHAR) buf;
tgt.MaximumLength = (strlen (srcstr) + 1) * sizeof (WCHAR); tgt.MaximumLength = (strlen (srcstr) + 1) * sizeof (WCHAR);
tgt.Length = sys_mbstowcs (buf, srcstr, tgt.MaximumLength / sizeof (WCHAR)) tgt.Length = sys_mbstowcs (buf, srcstr, tgt.MaximumLength / sizeof (WCHAR))
* sizeof (WCHAR); * sizeof (WCHAR);
if (tgt.Length) if (tgt.Length)
tgt.Length -= sizeof (WCHAR); tgt.Length -= sizeof (WCHAR);
} }
@ -173,7 +173,7 @@ void
str2uni_cat (UNICODE_STRING &tgt, const char *srcstr) str2uni_cat (UNICODE_STRING &tgt, const char *srcstr)
{ {
int len = sys_mbstowcs (tgt.Buffer + tgt.Length / sizeof (WCHAR), 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) if (len)
tgt.Length += (len - 1) * sizeof (WCHAR); tgt.Length += (len - 1) * sizeof (WCHAR);
else else

View File

@ -507,63 +507,63 @@ out:
if (s->write_selected) if (s->write_selected)
{ {
if (s->write_ready) if (s->write_ready)
{ {
select_printf ("%s, already ready for write", fh->get_name ()); select_printf ("%s, already ready for write", fh->get_name ());
gotone++; gotone++;
} }
/* Do we need to do anything about SIGTTOU here? */ /* Do we need to do anything about SIGTTOU here? */
else if (fh->get_device () == FH_PIPER) else if (fh->get_device () == FH_PIPER)
select_printf ("%s, select for write on read end of pipe", select_printf ("%s, select for write on read end of pipe",
fh->get_name ()); fh->get_name ());
else else
{ {
/* We don't worry about the guard mutex, because that only applies /* We don't worry about the guard mutex, because that only applies
when from_select is false, and peek_pipe is never called that when from_select is false, and peek_pipe is never called that
way for writes. */ way for writes. */
IO_STATUS_BLOCK iosb = {0}; IO_STATUS_BLOCK iosb = {0};
FILE_PIPE_LOCAL_INFORMATION fpli = {0}; FILE_PIPE_LOCAL_INFORMATION fpli = {0};
if (NtQueryInformationFile (h, if (NtQueryInformationFile (h,
&iosb, &iosb,
&fpli, &fpli,
sizeof (fpli), sizeof (fpli),
FilePipeLocalInformation)) FilePipeLocalInformation))
{ {
/* If NtQueryInformationFile fails, optimistically assume the /* If NtQueryInformationFile fails, optimistically assume the
pipe is writable. This could happen on Win9x, because pipe is writable. This could happen on Win9x, because
NtQueryInformationFile is not available, or if we somehow NtQueryInformationFile is not available, or if we somehow
inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
access on the write end. */ access on the write end. */
select_printf ("%s, NtQueryInformationFile failed", select_printf ("%s, NtQueryInformationFile failed",
fh->get_name ()); fh->get_name ());
gotone += s->write_ready = true; gotone += s->write_ready = true;
} }
/* Ensure that enough space is available for atomic writes, /* Ensure that enough space is available for atomic writes,
as required by POSIX. Subsequent writes with size > PIPE_BUF as required by POSIX. Subsequent writes with size > PIPE_BUF
can still block, but most (all?) UNIX variants seem to work can still block, but most (all?) UNIX variants seem to work
this way (e.g., BSD, Linux, Solaris). */ this way (e.g., BSD, Linux, Solaris). */
else if (fpli.WriteQuotaAvailable >= PIPE_BUF) else if (fpli.WriteQuotaAvailable >= PIPE_BUF)
{ {
select_printf ("%s, ready for write: size %lu, avail %lu", select_printf ("%s, ready for write: size %lu, avail %lu",
fh->get_name (), fh->get_name (),
fpli.OutboundQuota, fpli.OutboundQuota,
fpli.WriteQuotaAvailable); fpli.WriteQuotaAvailable);
gotone += s->write_ready = true; gotone += s->write_ready = true;
} }
/* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider
the pipe writable only if it is completely empty, to minimize the the pipe writable only if it is completely empty, to minimize the
probability that a subsequent write will block. */ probability that a subsequent write will block. */
else if (fpli.OutboundQuota < PIPE_BUF && else if (fpli.OutboundQuota < PIPE_BUF &&
fpli.WriteQuotaAvailable == fpli.OutboundQuota) fpli.WriteQuotaAvailable == fpli.OutboundQuota)
{ {
select_printf ("%s, tiny pipe: size %lu, avail %lu", select_printf ("%s, tiny pipe: size %lu, avail %lu",
fh->get_name (), fh->get_name (),
fpli.OutboundQuota, fpli.OutboundQuota,
fpli.WriteQuotaAvailable); fpli.WriteQuotaAvailable);
gotone += s->write_ready = true; gotone += s->write_ready = true;
} }
} }
} }
return gotone; return gotone;

View File

@ -707,6 +707,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
sendsig = myself->sendsig; sendsig = myself->sendsig;
else else
{ {
for (int i = 0; !p->dwProcessId && i < 10000; i++)
low_priority_sleep (0);
HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId); HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId);
if (!hp) if (!hp)
{ {
@ -854,14 +856,13 @@ subproc_init (void)
by fork/spawn/exec. */ by fork/spawn/exec. */
void __stdcall 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); memset (ch, 0, sizeof *ch);
ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info); ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info);
ch->intro = PROC_MAGIC_GENERIC; ch->intro = PROC_MAGIC_GENERIC;
ch->magic = CHILD_INFO_MAGIC; ch->magic = CHILD_INFO_MAGIC;
ch->type = chtype; ch->type = chtype;
ch->cygpid = pid;
ch->subproc_ready = subproc_ready; ch->subproc_ready = subproc_ready;
ch->pppid_handle = myself->ppid_handle; ch->pppid_handle = myself->ppid_handle;
ch->fhandler_union_cb = sizeof (fhandler_union); ch->fhandler_union_cb = sizeof (fhandler_union);
@ -1064,6 +1065,7 @@ wait_sig (VOID *self)
{ {
HANDLE readsig; HANDLE readsig;
char sa_buf[1024]; char sa_buf[1024];
Static bool holding_signals;
/* Initialization */ /* Initialization */
(void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
@ -1080,6 +1082,7 @@ wait_sig (VOID *self)
myself->process_state |= PID_ACTIVE; myself->process_state |= PID_ACTIVE;
myself->process_state &= ~PID_INITIALIZING; 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 /* 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. windows process waiting to see if it's started a cygwin process or not.
Signalling subproc_ready indicates that we are a cygwin process. */ 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) if (q->si.si_signo == __SIGDELETE || q->process () > 0)
sigq.del (); sigq.del ();
break; break;
case __SIGHOLD:
holding_signals = 1;
break;
case __SIGNOHOLD:
holding_signals = 0;
break;
default: default:
if (pack.si.si_signo < 0) if (pack.si.si_signo < 0)
sig_clear (-pack.si.si_signo); sig_clear (-pack.si.si_signo);
else if (holding_signals)
sigq.add (pack);
else else
{ {
int sig = pack.si.si_signo; int sig = pack.si.si_signo;

View File

@ -24,7 +24,9 @@ enum
__SIGCOMMUNE = -(NSIG + 3), __SIGCOMMUNE = -(NSIG + 3),
__SIGPENDING = -(NSIG + 4), __SIGPENDING = -(NSIG + 4),
__SIGDELETE = -(NSIG + 5), __SIGDELETE = -(NSIG + 5),
__SIGFLUSHFAST = -(NSIG + 6) __SIGFLUSHFAST = -(NSIG + 6),
__SIGHOLD = -(NSIG + 7),
__SIGNOHOLD = -(NSIG + 8)
}; };
#endif #endif

View File

@ -393,8 +393,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
ProtectHandleINH (subproc_ready); ProtectHandleINH (subproc_ready);
} }
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, init_child_info (chtype, &ciresrv, subproc_ready);
subproc_ready);
ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info)); ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
ciresrv.moreinfo->old_title = NULL; ciresrv.moreinfo->old_title = NULL;
@ -630,6 +629,10 @@ spawn_guts (const char * prog_arg, const char *const *argv,
flags |= DETACHED_PROCESS; flags |= DETACHED_PROCESS;
if (mode != _P_OVERLAY) if (mode != _P_OVERLAY)
flags |= CREATE_SUSPENDED; flags |= CREATE_SUSPENDED;
#if 0 //someday
else
myself->dwProcessId = 0;
#endif
/* Some file types (currently only sockets) need extra effort in the /* Some file types (currently only sockets) need extra effort in the
parent after CreateProcess and before copying the datastructures 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 ()) if (cygheap->fdtab.need_fixup_before ())
flags |= CREATE_SUSPENDED; flags |= CREATE_SUSPENDED;
const char *runpath = null_app_name ? NULL : (const char *) real_path; 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); 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->fdtab.set_file_pointers_for_exec ();
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
/* When ruid != euid we create the new process under the current original /* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different account and impersonate in child, this way maintaining the different
effective vs. real ids. effective vs. real ids.
@ -729,6 +732,10 @@ spawn_guts (const char * prog_arg, const char *const *argv,
{ {
__seterrno (); __seterrno ();
syscall_printf ("CreateProcess failed, %E"); syscall_printf ("CreateProcess failed, %E");
#if 0 // someday
if (mode == _P_OVERLAY)
myself->dwProcessId = GetCurrentProcessId ();
#endif
if (subproc_ready) if (subproc_ready)
ForceCloseHandle (subproc_ready); ForceCloseHandle (subproc_ready);
cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0); cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);

View File

@ -712,7 +712,7 @@ link (const char *a, const char *b)
goto docopy; goto docopy;
} }
if (GetLastError () != ERROR_PROC_NOT_FOUND) if (GetLastError () != ERROR_PROC_NOT_FOUND)
{ {
syscall_printf ("CreateHardLinkA failed"); syscall_printf ("CreateHardLinkA failed");
__seterrno (); __seterrno ();
goto done; goto done;
@ -804,7 +804,7 @@ link (const char *a, const char *b)
CloseHandle (hFileSource); CloseHandle (hFileSource);
if (!bSuccess) if (!bSuccess)
{ {
/* Only copy file if FS doesn't support hard links */ /* Only copy file if FS doesn't support hard links */
if (write_err == ERROR_INVALID_FUNCTION) if (write_err == ERROR_INVALID_FUNCTION)
{ {

View File

@ -79,13 +79,13 @@ uname (struct utsname *name)
__small_sprintf (name->machine, "i%d86", ptype); __small_sprintf (name->machine, "i%d86", ptype);
break; break;
case PROCESSOR_ARCHITECTURE_IA64: case PROCESSOR_ARCHITECTURE_IA64:
strcpy (name->machine, "ia64"); strcpy (name->machine, "ia64");
break; break;
case PROCESSOR_ARCHITECTURE_AMD64: case PROCESSOR_ARCHITECTURE_AMD64:
strcpy (name->machine, "amd64"); strcpy (name->machine, "amd64");
break; break;
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
strcpy (name->machine, "ia32-win64"); strcpy (name->machine, "ia32-win64");
case PROCESSOR_ARCHITECTURE_ALPHA: case PROCESSOR_ARCHITECTURE_ALPHA:
strcpy (name->machine, "alpha"); strcpy (name->machine, "alpha");
break; break;