4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-29 02:20:21 +08:00
newlib-cygwin/winsup/cygwin/child_info.h
Christopher Faylor 1fb6667f1c * child_info.h (CURR_CHILD_INFO_MAGIC): Reset.
(child_info::rd_proc_pipe): Declare new field.
(child_info::wr_proc_pipe): Ditto.
(child_info::prefork): Declare new function, derived from previous pinfo
version.
* dcrt0.cc (child_info_fork::handle_fork): Close previous wr_proc_pipe when
appropriate and assign new one from passed-in child_info block.
(child_info_spawn::handle_spawn): Assign our wr_proc_pipe handle from passed-in
child_info block.
* fork.cc (child_info::prefork): Define new function.
(frok::child): Clear rd_proc_pipe and wr_proc_pipe so they will not be closed
by the child_info destructor.
(frok::parent): Use child_info prefork handling, outside of retry loop.  Set
rd_proc_pipe in child's pinfo after successful CreateProcess.  Eliminate
postfork call.
* globals.cc (my_wr_proc_pipe): Define/declare new variable.
* pinfo.cc (pinfo::pending_rd_proc_pipe): Delete.
(pinfo::pending_wr_proc_pipe): Ditto.
(pinfo::prefork): Ditto.
(pinfo::postfork): Ditto.
(pinfo::postexec): Ditto.
(pinfo::wait): Assume that rd_proc_pipe is set up correctly prior to call.
(_pinfo::alert_parent): Replace "wr_proc_pipe" with "my_wr_proc_pipe".
* pinfo.h (_pinfo::_wr_proc_pipe): Delete declaration.
(_pinfo::set_rd_proc_pipe): Define new function.
(pinfo::pending_rd_proc_pipe): Delete declaration.
(pinfo::pending_wr_proc_pipe): Ditto.
(pinfo::prefork): Ditto.
(pinfo::postfork): Ditto.
(pinfo::postexec): Ditto.
(pinfo::wr_proc_pipe): Ditto.
* sigproc.cc (child_info::child_info): Clear rd_proc_pipe and wr_proc_pipe.
(child_info::cleanup): Close rd_proc_pipe and wr_proc_pipe if necessary.
(child_info_fork::child_info_fork): Set forker_finished to NULL by default.
(child_info_spawn::child_info_spawn): Use my_wr_proc_pipe rather than
myself->wr_proc_pipe.
(child_info::sync): Ditto.
(child_info_spawn::cleanup): Call child_info::cleanup.
* spawn.cc (child_info_spawn::worker): Remove call to myself.prefork().  Set
wr_proc_pipe when execing or set up new rd_proc_pipe/wr_proc_pipe via
child_info::prefork when spawning.  Remove call to pinfo::postexec.  Set
rd_proc_pipe in child pinfo when spawning.  Use my_wr_proc_pipe rather than
myself->wr_proc_pipe.  Remove call to postfork.
2012-03-20 15:07:30 +00:00

190 lines
4.8 KiB
C++

/* child_info.h: shared child info for cygwin
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2011
Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include <setjmp.h>
enum child_info_types
{
_CH_NADA = 0,
_CH_EXEC = 1,
_CH_SPAWN = 2,
_CH_FORK = 3,
_CH_WHOOPS = 4
};
enum child_status
{
_CI_STRACED = 0x01,
_CI_ISCYGWIN = 0x02,
_CI_SAW_CTRL_C = 0x04
};
#define OPROC_MAGIC_MASK 0xff00ff00
#define OPROC_MAGIC_GENERIC 0xaf00f000
#define PROC_MAGIC_GENERIC 0xaf00fa00
#define EXEC_MAGIC_SIZE sizeof(child_info)
/* Change this value if you get a message indicating that it is out-of-sync. */
#define CURR_CHILD_INFO_MAGIC 0xa49e665eU
#define NPROCS 256
#include "pinfo.h"
struct cchildren
{
pid_t pid;
pinfo_minimal p;
};
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between
different cygwin versions. */
class child_info
{
public:
DWORD msv_count; // zeroed on < W2K3, set to pseudo-count on Vista
DWORD cb; // size of this record
DWORD intro; // improbable string
unsigned long magic; // magic number unique to child_info
unsigned short type; // type of record, exec, spawn, fork
init_cygheap *cygheap;
void *cygheap_max;
unsigned char flag;
int retry; // number of times we've tried to start child process
HANDLE rd_proc_pipe;
HANDLE wr_proc_pipe;
HANDLE subproc_ready; // used for synchronization with parent
HANDLE user_h;
HANDLE parent;
DWORD cygheap_reserve_sz;
unsigned fhandler_union_cb;
DWORD exit_code; // process exit code
static int retry_count;// retry count;
child_info (unsigned, child_info_types, bool);
child_info (): subproc_ready (NULL), parent (NULL) {}
~child_info ();
void refresh_cygheap () { cygheap_max = ::cygheap_max; }
void ready (bool);
bool sync (int, HANDLE&, DWORD) __attribute__ ((regparm (3)));
DWORD proc_retry (HANDLE) __attribute__ ((regparm (2)));
bool isstraced () const {return !!(flag & _CI_STRACED);}
bool iscygwin () const {return !!(flag & _CI_ISCYGWIN);}
bool saw_ctrl_c () const {return !!(flag & _CI_SAW_CTRL_C);}
void prefork (bool = false);
void cleanup ();
};
class mount_info;
class _pinfo;
class child_info_fork: public child_info
{
public:
HANDLE forker_finished;// for synchronization with child
jmp_buf jmp; // where child will jump to
void *stackaddr; // address of parent stack
void *stacktop; // location of top of parent stack
void *stackbottom; // location of bottom of parent stack
size_t guardsize; // size of POSIX guard region or (size_t) -1 if
// user stack
char filler[4];
child_info_fork ();
void handle_fork () __attribute__ ((regparm (1)));;
bool abort (const char *fmt = NULL, ...);
void alloc_stack ();
void alloc_stack_hard_way (volatile char *);
};
class fhandler_base;
class cygheap_exec_info
{
public:
int argc;
char **argv;
int envc;
char **envp;
HANDLE myself_pinfo;
int nchildren;
cchildren children[0];
static cygheap_exec_info *alloc ();
void record_children ();
void reattach_children (HANDLE);
};
class child_info_spawn: public child_info
{
muto *lock;
HANDLE hExeced;
HANDLE ev;
public:
cygheap_exec_info *moreinfo;
int __stdin;
int __stdout;
char filler[4];
void cleanup ();
child_info_spawn () {};
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 set (child_info_types ci, bool b) { new (this) child_info_spawn (ci, b);}
void handle_spawn () __attribute__ ((regparm (1)));
bool set_saw_ctrl_c ()
{
if (!has_execed ())
return false;
flag |= _CI_SAW_CTRL_C;
return true;
}
bool signal_myself_exited ()
{
if (!ev)
return false;
else
{
SetEvent (ev);
return true;
}
}
void wait_for_myself () { WaitForSingleObject (ev, INFINITE); }
bool has_execed () const
{
if (hExeced)
return true;
if (type != _CH_EXEC)
return false;
lock->acquire ();
lock->release ();
return !!hExeced;
}
bool has_execed_cygwin () const { return iscygwin () && has_execed (); }
operator HANDLE& () {return hExeced;}
int worker (const char *, const char *const *, const char *const [], int,
int = -1, int = -1) __attribute__ ((regparm (3)));;
};
extern child_info_spawn ch_spawn;
#define have_execed ch_spawn.has_execed ()
#define have_execed_cygwin ch_spawn.has_execed_cygwin ()
void __stdcall init_child_info (DWORD, child_info *, HANDLE);
extern "C" {
extern child_info *child_proc_info;
extern child_info_spawn *spawn_info asm ("_child_proc_info");
extern child_info_fork *fork_info asm ("_child_proc_info");
}