Cygwin: posix_spawn: add Cygwin-specific code fixing process synchronisation
Newlib's posix_spawn has been taken from FreeBSD. The code relies on BSD-specific behaviour of vfork, namely the fact that vfork blocks the parent until the child exits or calls execve as well as the fact that the child shares parent memory in non-COW mode. This behaviour can't be emulated by Cygwin. Cygwin's vfork is equivalent to fork. This is POSIX-compliant, but it's lacking BSD's vfork ingrained synchronization of the parent to wait for the child calling execve, or the chance to just write a variable and the parent will see the result. So this requires a Cygwin-specific solution. The core function of posix_spawn, called do_posix_spawn is now implemented twice, once using the BSD method, and once for Cygwin using Windows synchronization under the hood waiting for the child to call execve and signalling errors upstream. The Windows specifics are hidden inside Cygwin, so newlib only calls internal Cygwin functions. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
@@ -37,7 +37,7 @@ enum child_status
|
||||
#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 0xf4531879U
|
||||
#define CURR_CHILD_INFO_MAGIC 0xecc930b9U
|
||||
|
||||
#define NPROCS 256
|
||||
|
||||
@@ -144,6 +144,7 @@ class child_info_spawn: public child_info
|
||||
{
|
||||
HANDLE hExeced;
|
||||
HANDLE ev;
|
||||
HANDLE sem;
|
||||
pid_t cygpid;
|
||||
public:
|
||||
cygheap_exec_info *moreinfo;
|
||||
@@ -159,6 +160,11 @@ public:
|
||||
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 __reg1 handle_spawn ();
|
||||
void set_sem (HANDLE _sem)
|
||||
{
|
||||
/* Don't leak semaphore handle into exec'ed process. */
|
||||
SetHandleInformation (sem = _sem, HANDLE_FLAG_INHERIT, 0);
|
||||
}
|
||||
bool set_saw_ctrl_c ()
|
||||
{
|
||||
if (!has_execed ())
|
||||
@@ -188,8 +194,8 @@ public:
|
||||
bool get_parent_handle ();
|
||||
bool has_execed_cygwin () const { return iscygwin () && has_execed (); }
|
||||
operator HANDLE& () {return hExeced;}
|
||||
int __reg3 worker (const char *, const char *const *, const char *const [], int,
|
||||
int = -1, int = -1);;
|
||||
int __reg3 worker (const char *, const char *const *, const char *const [],
|
||||
int, int = -1, int = -1);
|
||||
};
|
||||
|
||||
extern child_info_spawn ch_spawn;
|
||||
|
Reference in New Issue
Block a user