mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-21 16:26:12 +08:00
* child_info.h (cchildren): New struct.
(child_info_spawn::nchildren): Rename from nprocs. (child_info_spawn::children): Change type to cchildren for more bookkeeping possibilities. (child_info_spawn::child_info_spawn): Clear nchildren. (child_info_spawn::record_children): Declare new function. (child_info_spawn::reattach_children): Ditto. * dcrt0.cc (child_info_spawn::handle_spawn): Call reattach_children to gather list of processes we are potentially waiting for. * pinfo.h (pinfo::pinfo): Make sure that rd_proc_pipe is always cleared. (pinfo::reattach): New function. * sigproc.cc: Move pinfo.h earlier so that it can be used in sigproc.h. (get_proc_lock): Don't bother with a lock during DLL initialization. (proc_subproc): Handle PROC_REATTACH_CHILD. (proc_terminate): Orphan children only when we are not an execed process or when the pid is about to be occupied by a non-cygwin process. (child_info_spawn::record_children): Define new function. (child_info_spawn::reattach_children): Ditto. * sigproc.h (procstuff): Define PROC_REATTACH_CHILD and renumber other elements. * spawn.cc (spawn_guts): Record any to-be-waited-for subprocesses if about to exec a cygwin process. * sigproc.cc (sig_send): Fix harmless transposition of fifth and six arguments to DuplicateHandle(). (child_info::child_info): Ditto. * globals.cc (hExeced): Make NO_COPY.
This commit is contained in:
parent
be2280986d
commit
b79b15e9e3
@ -1,3 +1,35 @@
|
|||||||
|
2011-10-25 Christopher Faylor <me.cygwin2011@cgf.cx>
|
||||||
|
|
||||||
|
* child_info.h (cchildren): New struct.
|
||||||
|
(child_info_spawn::nchildren): Rename from nprocs.
|
||||||
|
(child_info_spawn::children): Change type to cchildren for more
|
||||||
|
bookkeeping possibilities.
|
||||||
|
(child_info_spawn::child_info_spawn): Clear nchildren.
|
||||||
|
(child_info_spawn::record_children): Declare new function.
|
||||||
|
(child_info_spawn::reattach_children): Ditto.
|
||||||
|
* dcrt0.cc (child_info_spawn::handle_spawn): Call reattach_children to
|
||||||
|
gather list of processes we are potentially waiting for.
|
||||||
|
* pinfo.h (pinfo::pinfo): Make sure that rd_proc_pipe is always cleared.
|
||||||
|
(pinfo::reattach): New function.
|
||||||
|
* sigproc.cc: Move pinfo.h earlier so that it can be used in sigproc.h.
|
||||||
|
(get_proc_lock): Don't bother with a lock during DLL initialization.
|
||||||
|
(proc_subproc): Handle PROC_REATTACH_CHILD.
|
||||||
|
(proc_terminate): Orphan children only when we are not an execed
|
||||||
|
process or when the pid is about to be occupied by a non-cygwin
|
||||||
|
process.
|
||||||
|
(child_info_spawn::record_children): Define new function.
|
||||||
|
(child_info_spawn::reattach_children): Ditto.
|
||||||
|
* sigproc.h (procstuff): Define PROC_REATTACH_CHILD and renumber other
|
||||||
|
elements.
|
||||||
|
* spawn.cc (spawn_guts): Record any to-be-waited-for subprocesses if
|
||||||
|
about to exec a cygwin process.
|
||||||
|
|
||||||
|
* sigproc.cc (sig_send): Fix harmless transposition of fifth and six
|
||||||
|
arguments to DuplicateHandle().
|
||||||
|
(child_info::child_info): Ditto.
|
||||||
|
|
||||||
|
* globals.cc (hExeced): Make NO_COPY.
|
||||||
|
|
||||||
2011-10-25 Corinna Vinschen <corinna@vinschen.de>
|
2011-10-25 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* hookapi.cc (hook_or_detect_cygwin): Take additional handle
|
* hookapi.cc (hook_or_detect_cygwin): Take additional handle
|
||||||
|
@ -38,10 +38,16 @@ enum child_status
|
|||||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
||||||
|
|
||||||
/* Change this value if you get a message indicating that it is out-of-sync. */
|
/* Change this value if you get a message indicating that it is out-of-sync. */
|
||||||
#define CURR_CHILD_INFO_MAGIC 0x29afd207U
|
#define CURR_CHILD_INFO_MAGIC 0xa049a83aU
|
||||||
|
|
||||||
#define NPROCS 256
|
#define NPROCS 256
|
||||||
|
|
||||||
|
struct cchildren
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
HANDLE rd_proc_pipe;
|
||||||
|
};
|
||||||
|
|
||||||
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||||
below class. The layout is checksummed to determine compatibility between
|
below class. The layout is checksummed to determine compatibility between
|
||||||
different cygwin versions. */
|
different cygwin versions. */
|
||||||
@ -56,8 +62,6 @@ public:
|
|||||||
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;
|
||||||
int nprocs;
|
|
||||||
pid_t children[NPROCS];
|
|
||||||
init_cygheap *cygheap;
|
init_cygheap *cygheap;
|
||||||
void *cygheap_max;
|
void *cygheap_max;
|
||||||
DWORD cygheap_reserve_sz;
|
DWORD cygheap_reserve_sz;
|
||||||
@ -119,6 +123,8 @@ public:
|
|||||||
int __stdin;
|
int __stdin;
|
||||||
int __stdout;
|
int __stdout;
|
||||||
char filler[4];
|
char filler[4];
|
||||||
|
int nchildren;
|
||||||
|
cchildren children[NPROCS];
|
||||||
|
|
||||||
~child_info_spawn ()
|
~child_info_spawn ()
|
||||||
{
|
{
|
||||||
@ -135,8 +141,10 @@ public:
|
|||||||
cfree (moreinfo);
|
cfree (moreinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
child_info_spawn (): moreinfo (NULL) {};
|
child_info_spawn (): moreinfo (NULL), nchildren (0) {};
|
||||||
child_info_spawn (child_info_types, bool);
|
child_info_spawn (child_info_types, bool);
|
||||||
|
void record_children ();
|
||||||
|
void reattach_children ();
|
||||||
void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
|
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 set (child_info_types ci, bool b) { new (this) child_info_spawn (ci, b);}
|
||||||
void handle_spawn () __attribute__ ((regparm (1)));
|
void handle_spawn () __attribute__ ((regparm (1)));
|
||||||
|
@ -625,6 +625,12 @@ child_info_spawn::handle_spawn ()
|
|||||||
cygheap->fdtab.move_fd (__stdout, 1);
|
cygheap->fdtab.move_fd (__stdout, 1);
|
||||||
cygheap->user.groups.clear_supp ();
|
cygheap->user.groups.clear_supp ();
|
||||||
|
|
||||||
|
/* If we're execing we may have "inherited" a list of children forked by the
|
||||||
|
previous process executing under this pid. Reattach them here so that we
|
||||||
|
can wait for them. */
|
||||||
|
if (type == _PROC_EXEC)
|
||||||
|
reattach_children ();
|
||||||
|
|
||||||
ready (true);
|
ready (true);
|
||||||
|
|
||||||
/* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of
|
/* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of
|
||||||
|
@ -22,7 +22,7 @@ HANDLE NO_COPY hMainThread;
|
|||||||
HANDLE NO_COPY hProcToken;
|
HANDLE NO_COPY hProcToken;
|
||||||
HANDLE NO_COPY hProcImpToken;
|
HANDLE NO_COPY hProcImpToken;
|
||||||
HMODULE NO_COPY cygwin_hmodule;
|
HMODULE NO_COPY cygwin_hmodule;
|
||||||
HANDLE hExeced;
|
HANDLE NO_COPY hExeced;
|
||||||
int NO_COPY sigExeced;
|
int NO_COPY sigExeced;
|
||||||
WCHAR NO_COPY windows_system_directory[MAX_PATH];
|
WCHAR NO_COPY windows_system_directory[MAX_PATH];
|
||||||
UINT NO_COPY windows_system_directory_length;
|
UINT NO_COPY windows_system_directory_length;
|
||||||
|
@ -971,19 +971,25 @@ _pinfo::dup_proc_pipe (HANDLE hProcess)
|
|||||||
int
|
int
|
||||||
pinfo::wait ()
|
pinfo::wait ()
|
||||||
{
|
{
|
||||||
/* FIXME: execed processes should be able to wait for pids that were started
|
/* If rd_proc_pipe that means we're in an execed process which already has
|
||||||
by the process which execed them. */
|
grabbed the read end of the pipe from the previous cygwin process running
|
||||||
if (!CreatePipe (&rd_proc_pipe, &((*this)->wr_proc_pipe), &sec_none_nih, 16))
|
with this pid. */
|
||||||
|
if (!rd_proc_pipe)
|
||||||
{
|
{
|
||||||
system_printf ("Couldn't create pipe tracker for pid %d, %E",
|
/* FIXME: execed processes should be able to wait for pids that were started
|
||||||
(*this)->pid);
|
by the process which execed them. */
|
||||||
return 0;
|
if (!CreatePipe (&rd_proc_pipe, &((*this)->wr_proc_pipe), &sec_none_nih, 16))
|
||||||
}
|
{
|
||||||
|
system_printf ("Couldn't create pipe tracker for pid %d, %E",
|
||||||
|
(*this)->pid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(*this)->dup_proc_pipe (hProcess))
|
if (!(*this)->dup_proc_pipe (hProcess))
|
||||||
{
|
{
|
||||||
system_printf ("Couldn't duplicate pipe topid %d(%p), %E", (*this)->pid, hProcess);
|
system_printf ("Couldn't duplicate pipe topid %d(%p), %E", (*this)->pid, hProcess);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preserve (); /* Preserve the shared memory associated with the pinfo */
|
preserve (); /* Preserve the shared memory associated with the pinfo */
|
||||||
|
@ -147,8 +147,8 @@ public:
|
|||||||
bool waiter_ready;
|
bool waiter_ready;
|
||||||
class cygthread *wait_thread;
|
class cygthread *wait_thread;
|
||||||
void init (pid_t, DWORD, HANDLE) __attribute__ ((regparm(3)));
|
void init (pid_t, DWORD, HANDLE) __attribute__ ((regparm(3)));
|
||||||
pinfo (): procinfo (NULL) {}
|
pinfo (): procinfo (NULL), rd_proc_pipe (NULL) {}
|
||||||
pinfo (_pinfo *x): procinfo (x), hProcess (NULL) {}
|
pinfo (_pinfo *x): procinfo (x), rd_proc_pipe (NULL), hProcess (NULL) {}
|
||||||
pinfo (pid_t n) : rd_proc_pipe (NULL), hProcess (NULL) {init (n, 0, NULL);}
|
pinfo (pid_t n) : rd_proc_pipe (NULL), hProcess (NULL) {init (n, 0, NULL);}
|
||||||
pinfo (pid_t n, DWORD flag) : rd_proc_pipe (NULL), hProcess (NULL), waiter_ready (0), wait_thread (NULL) {init (n, flag, NULL);}
|
pinfo (pid_t n, DWORD flag) : rd_proc_pipe (NULL), hProcess (NULL), waiter_ready (0), wait_thread (NULL) {init (n, flag, NULL);}
|
||||||
void thisproc (HANDLE) __attribute__ ((regparm (2)));
|
void thisproc (HANDLE) __attribute__ ((regparm (2)));
|
||||||
@ -175,6 +175,11 @@ public:
|
|||||||
#ifndef _SIGPROC_H
|
#ifndef _SIGPROC_H
|
||||||
int remember () {system_printf ("remember is not here"); return 0;}
|
int remember () {system_printf ("remember is not here"); return 0;}
|
||||||
#else
|
#else
|
||||||
|
void reattach ()
|
||||||
|
{
|
||||||
|
proc_subproc (PROC_REATTACH_CHILD, (DWORD) this);
|
||||||
|
destroy = false;
|
||||||
|
}
|
||||||
int remember (bool detach)
|
int remember (bool detach)
|
||||||
{
|
{
|
||||||
int res = proc_subproc (detach ? PROC_DETACHED_CHILD : PROC_ADDCHILD,
|
int res = proc_subproc (detach ? PROC_DETACHED_CHILD : PROC_ADDCHILD,
|
||||||
|
@ -14,7 +14,6 @@ details. */
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "pinfo.h"
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
@ -23,6 +22,7 @@ details. */
|
|||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
#include "pinfo.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -129,6 +129,8 @@ signal_fixup_after_exec ()
|
|||||||
static bool
|
static bool
|
||||||
get_proc_lock (DWORD what, DWORD val)
|
get_proc_lock (DWORD what, DWORD val)
|
||||||
{
|
{
|
||||||
|
if (!cygwin_finished_initializing)
|
||||||
|
return true;
|
||||||
Static int lastwhat = -1;
|
Static int lastwhat = -1;
|
||||||
if (!sync_proc_subproc)
|
if (!sync_proc_subproc)
|
||||||
{
|
{
|
||||||
@ -234,6 +236,9 @@ proc_subproc (DWORD what, DWORD val)
|
|||||||
}
|
}
|
||||||
if (what == PROC_DETACHED_CHILD)
|
if (what == PROC_DETACHED_CHILD)
|
||||||
break;
|
break;
|
||||||
|
/* fall through intentionally */
|
||||||
|
|
||||||
|
case PROC_REATTACH_CHILD:
|
||||||
procs[nprocs] = vchild;
|
procs[nprocs] = vchild;
|
||||||
rc = procs[nprocs].wait ();
|
rc = procs[nprocs].wait ();
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -379,6 +384,7 @@ proc_terminate ()
|
|||||||
set to 1 so we don't do that either.
|
set to 1 so we don't do that either.
|
||||||
if (!hExeced)
|
if (!hExeced)
|
||||||
*/
|
*/
|
||||||
|
if (!hExeced || ISSTATE (myself, PID_NOTCYGWIN))
|
||||||
procs[i]->ppid = 1;
|
procs[i]->ppid = 1;
|
||||||
if (procs[i].wait_thread)
|
if (procs[i].wait_thread)
|
||||||
{
|
{
|
||||||
@ -596,8 +602,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
VerifyHandle (hp);
|
VerifyHandle (hp);
|
||||||
if (!DuplicateHandle (hp, dupsig, GetCurrentProcess (), &sendsig, false,
|
if (!DuplicateHandle (hp, dupsig, GetCurrentProcess (), &sendsig, 0,
|
||||||
0, DUPLICATE_SAME_ACCESS) || !sendsig)
|
false, DUPLICATE_SAME_ACCESS) || !sendsig)
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
sigproc_printf ("DuplicateHandle failed, %E");
|
sigproc_printf ("DuplicateHandle failed, %E");
|
||||||
@ -619,7 +625,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
|||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!DuplicateHandle (GetCurrentProcess (), tome, hp, &tome, false, 0,
|
if (!DuplicateHandle (GetCurrentProcess (), tome, hp, &tome, 0, false,
|
||||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
||||||
{
|
{
|
||||||
sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
|
sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
|
||||||
@ -807,7 +813,7 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, bool need_subpr
|
|||||||
allow the child to duplicate handles from the parent to itself. */
|
allow the child to duplicate handles from the parent to itself. */
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
|
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
|
||||||
GetCurrentProcess (), &parent, 0, TRUE,
|
GetCurrentProcess (), &parent, 0, true,
|
||||||
DUPLICATE_SAME_ACCESS))
|
DUPLICATE_SAME_ACCESS))
|
||||||
system_printf ("couldn't create handle to myself for child, %E");
|
system_printf ("couldn't create handle to myself for child, %E");
|
||||||
}
|
}
|
||||||
@ -830,6 +836,42 @@ child_info_spawn::child_info_spawn (child_info_types chtype, bool need_subproc_r
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record any non-reaped subprocesses to be passed to about-to-be-execed
|
||||||
|
process. FIXME: There is a race here if the process exits while we
|
||||||
|
are recording it. */
|
||||||
|
void
|
||||||
|
child_info_spawn::record_children ()
|
||||||
|
{
|
||||||
|
/* FIXME: locking */
|
||||||
|
for (nchildren = 0; nchildren < nprocs; nchildren++)
|
||||||
|
{
|
||||||
|
children[nchildren].pid = procs[nchildren]->pid;
|
||||||
|
children[nchildren].rd_proc_pipe = procs[nchildren].rd_proc_pipe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reattach non-reaped subprocesses passed in from the cygwin process
|
||||||
|
which previously operated under this pid. FIXME: Is there a race here
|
||||||
|
if the process exits during cygwin's exec handoff? */
|
||||||
|
void
|
||||||
|
child_info_spawn::reattach_children ()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nchildren; i++)
|
||||||
|
{
|
||||||
|
pinfo p (children[i].pid, PID_MAP_RW);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
if (!DuplicateHandle (parent, children[i].rd_proc_pipe,
|
||||||
|
GetCurrentProcess (), &p.rd_proc_pipe, 0,
|
||||||
|
false, DUPLICATE_SAME_ACCESS))
|
||||||
|
system_printf ("couldn't duplicate parent %p handles for forked children after exec, %E",
|
||||||
|
children[i].rd_proc_pipe);
|
||||||
|
p.hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, false, p->pid);
|
||||||
|
p.reattach ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
child_info::ready (bool execed)
|
child_info::ready (bool execed)
|
||||||
{
|
{
|
||||||
|
@ -34,10 +34,11 @@ enum
|
|||||||
enum procstuff
|
enum procstuff
|
||||||
{
|
{
|
||||||
PROC_ADDCHILD = 1, // add a new subprocess to list
|
PROC_ADDCHILD = 1, // add a new subprocess to list
|
||||||
PROC_DETACHED_CHILD = 2, // set up a detached child
|
PROC_REATTACH_CHILD = 2, // reattach after exec
|
||||||
PROC_CLEARWAIT = 3, // clear all waits - signal arrived
|
PROC_DETACHED_CHILD = 3, // set up a detached child
|
||||||
PROC_WAIT = 4, // setup for wait() for subproc
|
PROC_CLEARWAIT = 4, // clear all waits - signal arrived
|
||||||
PROC_NOTHING = 5 // nothing, really
|
PROC_WAIT = 5, // setup for wait() for subproc
|
||||||
|
PROC_NOTHING = 6 // nothing, really
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sigpacket
|
struct sigpacket
|
||||||
|
@ -546,6 +546,8 @@ spawn_guts (const char *prog_arg, const char *const *argv,
|
|||||||
ch.moreinfo = moreinfo;
|
ch.moreinfo = moreinfo;
|
||||||
ch.__stdin = __stdin;
|
ch.__stdin = __stdin;
|
||||||
ch.__stdout = __stdout;
|
ch.__stdout = __stdout;
|
||||||
|
if (mode == _P_OVERLAY && ch.iscygwin ())
|
||||||
|
ch.record_children ();
|
||||||
|
|
||||||
si.lpReserved2 = (LPBYTE) &ch;
|
si.lpReserved2 = (LPBYTE) &ch;
|
||||||
si.cbReserved2 = sizeof (ch);
|
si.cbReserved2 = sizeof (ch);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user