Reintegrate socket duplication via WSADuplicateSocket/WSASocket.
* autoload.cc (WSADuplicateSocketW): Define. (WSASocketW): Define. * dtable.cc (dtable::release): Call dec_need_fixup_before if necessary. (dtable::fixup_before_fork): New function. (dtable::fixup_before_exec): New function. * dtable.h (class dtable): Add member cnt_need_fixup_before. Add declarations for above new functions. (dtable::dec_need_fixup_before): New inline method. (dtable::inc_need_fixup_before): New inline method. (dtable::need_fixup_before): New inline method. * fhandler.h (fhandler_base::fixup_before_fork_exec): New virtual method. (fhandler_base::need_fixup_before): New virtual method. (class fhandler_socket): Add member prot_info_ptr. (fhandler_socket::init_fixup_before): Declare. (fhandler_socket::need_fixup_before): New inline method. (fhandler_socket::fixup_before_fork_exec): Declare. (fhandler_socket::fixup_after_exec): Declare. * fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize prot_info_ptr to NULL. (fhandler_socket::~fhandler_socket): Free prot_info_ptr conditionally. (fhandler_socket::init_fixup_before): New method. (fhandler_socket::fixup_before_fork_exec): Ditto. (fhandler_socket::fixup_after_fork): Use WSASocketW to duplicate socket if necessary. (fhandler_socket::fixup_after_exec): New method. (fhandler_socket::dup): Use fixup_before_fork_exec/fixup_after_fork to duplicate socket if necessary. * fork.cc (frok::parent): Start child suspended if some fhandler needs fixup before fork. If so, call dtable::fixup_before_fork after CreateProcess and resume child. * net.cc (fdsock): Try to find out if socket needs fixup before and initialize socket accordingly. Add HUGE comment to explain what happens and why. * spawn.cc (spawn_guts): Start child suspended if some fhandler needs fixup before exec. If so, call dtable::fixup_before_exec after CreateProcess.
This commit is contained in:
parent
88242190ec
commit
b14f53a8ec
@ -1,3 +1,44 @@
|
|||||||
|
2009-11-17 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
Reintegrate socket duplication via WSADuplicateSocket/WSASocket.
|
||||||
|
* autoload.cc (WSADuplicateSocketW): Define.
|
||||||
|
(WSASocketW): Define.
|
||||||
|
* dtable.cc (dtable::release): Call dec_need_fixup_before if necessary.
|
||||||
|
(dtable::fixup_before_fork): New function.
|
||||||
|
(dtable::fixup_before_exec): New function.
|
||||||
|
* dtable.h (class dtable): Add member cnt_need_fixup_before. Add
|
||||||
|
declarations for above new functions.
|
||||||
|
(dtable::dec_need_fixup_before): New inline method.
|
||||||
|
(dtable::inc_need_fixup_before): New inline method.
|
||||||
|
(dtable::need_fixup_before): New inline method.
|
||||||
|
* fhandler.h (fhandler_base::fixup_before_fork_exec): New virtual
|
||||||
|
method.
|
||||||
|
(fhandler_base::need_fixup_before): New virtual method.
|
||||||
|
(class fhandler_socket): Add member prot_info_ptr.
|
||||||
|
(fhandler_socket::init_fixup_before): Declare.
|
||||||
|
(fhandler_socket::need_fixup_before): New inline method.
|
||||||
|
(fhandler_socket::fixup_before_fork_exec): Declare.
|
||||||
|
(fhandler_socket::fixup_after_exec): Declare.
|
||||||
|
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize
|
||||||
|
prot_info_ptr to NULL.
|
||||||
|
(fhandler_socket::~fhandler_socket): Free prot_info_ptr conditionally.
|
||||||
|
(fhandler_socket::init_fixup_before): New method.
|
||||||
|
(fhandler_socket::fixup_before_fork_exec): Ditto.
|
||||||
|
(fhandler_socket::fixup_after_fork): Use WSASocketW to duplicate
|
||||||
|
socket if necessary.
|
||||||
|
(fhandler_socket::fixup_after_exec): New method.
|
||||||
|
(fhandler_socket::dup): Use fixup_before_fork_exec/fixup_after_fork
|
||||||
|
to duplicate socket if necessary.
|
||||||
|
* fork.cc (frok::parent): Start child suspended if some fhandler
|
||||||
|
needs fixup before fork. If so, call dtable::fixup_before_fork after
|
||||||
|
CreateProcess and resume child.
|
||||||
|
* net.cc (fdsock): Try to find out if socket needs fixup before and
|
||||||
|
initialize socket accordingly. Add HUGE comment to explain what happens
|
||||||
|
and why.
|
||||||
|
* spawn.cc (spawn_guts): Start child suspended if some fhandler needs
|
||||||
|
fixup before exec. If so, call dtable::fixup_before_exec after
|
||||||
|
CreateProcess.
|
||||||
|
|
||||||
2009-11-16 Eric Blake <ebb9@byu.net>
|
2009-11-16 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
* environ.cc (setenv): Detect invalid argument.
|
* environ.cc (setenv): Detect invalid argument.
|
||||||
|
@ -387,6 +387,7 @@ LoadDLLfunc (setsockopt, 20, ws2_32)
|
|||||||
LoadDLLfunc (shutdown, 8, ws2_32)
|
LoadDLLfunc (shutdown, 8, ws2_32)
|
||||||
LoadDLLfunc (socket, 12, ws2_32)
|
LoadDLLfunc (socket, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAAsyncSelect, 16, ws2_32)
|
LoadDLLfunc (WSAAsyncSelect, 16, ws2_32)
|
||||||
|
LoadDLLfunc (WSADuplicateSocketW, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
|
LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
||||||
@ -396,6 +397,7 @@ LoadDLLfunc (WSARecvFrom, 36, ws2_32)
|
|||||||
LoadDLLfunc (WSASendMsg, 24, ws2_32)
|
LoadDLLfunc (WSASendMsg, 24, ws2_32)
|
||||||
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
||||||
LoadDLLfunc (WSASetLastError, 4, ws2_32)
|
LoadDLLfunc (WSASetLastError, 4, ws2_32)
|
||||||
|
LoadDLLfunc (WSASocketW, 24, ws2_32)
|
||||||
// LoadDLLfunc (WSAStartup, 8, ws2_32)
|
// LoadDLLfunc (WSAStartup, 8, ws2_32)
|
||||||
LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
|
LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
|
||||||
|
|
||||||
|
@ -248,6 +248,8 @@ dtable::release (int fd)
|
|||||||
{
|
{
|
||||||
if (!not_open (fd))
|
if (!not_open (fd))
|
||||||
{
|
{
|
||||||
|
if (fds[fd]->need_fixup_before ())
|
||||||
|
dec_need_fixup_before ();
|
||||||
fhandler_base *arch = fds[fd]->archetype;
|
fhandler_base *arch = fds[fd]->archetype;
|
||||||
delete fds[fd];
|
delete fds[fd];
|
||||||
if (arch && !arch->usecount)
|
if (arch && !arch->usecount)
|
||||||
@ -1020,3 +1022,31 @@ handle_to_fn (HANDLE h, char *posix_fn)
|
|||||||
strcpy (posix_fn, unknown_file);
|
strcpy (posix_fn, unknown_file);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dtable::fixup_before_fork (DWORD target_proc_id)
|
||||||
|
{
|
||||||
|
lock ();
|
||||||
|
fhandler_base *fh;
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
if ((fh = fds[i]) != NULL)
|
||||||
|
{
|
||||||
|
debug_printf ("fd %d (%s)", i, fh->get_name ());
|
||||||
|
fh->fixup_before_fork_exec (target_proc_id);
|
||||||
|
}
|
||||||
|
unlock ();
|
||||||
|
}
|
||||||
|
void
|
||||||
|
dtable::fixup_before_exec (DWORD target_proc_id)
|
||||||
|
{
|
||||||
|
lock ();
|
||||||
|
fhandler_base *fh;
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
if ((fh = fds[i]) != NULL && !fh->close_on_exec ())
|
||||||
|
{
|
||||||
|
debug_printf ("fd %d (%s)", i, fh->get_name ());
|
||||||
|
fh->fixup_before_fork_exec (target_proc_id);
|
||||||
|
}
|
||||||
|
unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -31,14 +31,22 @@ class dtable
|
|||||||
unsigned farchetype;
|
unsigned farchetype;
|
||||||
static const int initial_archetype_size = 8;
|
static const int initial_archetype_size = 8;
|
||||||
int first_fd_for_open;
|
int first_fd_for_open;
|
||||||
|
int cnt_need_fixup_before;
|
||||||
void lock () {lock_process::locker.acquire ();}
|
void lock () {lock_process::locker.acquire ();}
|
||||||
void unlock () {lock_process::locker.release ();}
|
void unlock () {lock_process::locker.release ();}
|
||||||
public:
|
public:
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
dtable () : archetypes (NULL), narchetypes (0), farchetype (0), first_fd_for_open(3) {}
|
dtable () : archetypes (NULL), narchetypes (0), farchetype (0), first_fd_for_open(3), cnt_need_fixup_before(0) {}
|
||||||
void init () {first_fd_for_open = 3;}
|
void init () {first_fd_for_open = 3;}
|
||||||
|
|
||||||
|
void dec_need_fixup_before ()
|
||||||
|
{ if (cnt_need_fixup_before > 0) --cnt_need_fixup_before; }
|
||||||
|
void inc_need_fixup_before ()
|
||||||
|
{ cnt_need_fixup_before++; }
|
||||||
|
bool need_fixup_before ()
|
||||||
|
{ return cnt_need_fixup_before > 0; }
|
||||||
|
|
||||||
void move_fd (int, int);
|
void move_fd (int, int);
|
||||||
int vfork_child_dup ();
|
int vfork_child_dup ();
|
||||||
void vfork_parent_restore ();
|
void vfork_parent_restore ();
|
||||||
@ -73,6 +81,8 @@ public:
|
|||||||
fhandler_base *find_archetype (device& dev);
|
fhandler_base *find_archetype (device& dev);
|
||||||
fhandler_base **add_archetype ();
|
fhandler_base **add_archetype ();
|
||||||
void delete_archetype (fhandler_base *);
|
void delete_archetype (fhandler_base *);
|
||||||
|
void fixup_before_exec (DWORD win_proc_id);
|
||||||
|
void fixup_before_fork (DWORD win_proc_id);
|
||||||
friend void dtable_init ();
|
friend void dtable_init ();
|
||||||
friend void __stdcall close_all_files (bool);
|
friend void __stdcall close_all_files (bool);
|
||||||
friend class fhandler_disk_file;
|
friend class fhandler_disk_file;
|
||||||
|
@ -226,6 +226,7 @@ class fhandler_base
|
|||||||
return close_on_exec () ? &sec_none_nih : &sec_none;
|
return close_on_exec () ? &sec_none_nih : &sec_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int fixup_before_fork_exec (DWORD) { return 0; }
|
||||||
virtual void fixup_after_fork (HANDLE);
|
virtual void fixup_after_fork (HANDLE);
|
||||||
virtual void fixup_after_exec ();
|
virtual void fixup_after_exec ();
|
||||||
void create_read_state (LONG n)
|
void create_read_state (LONG n)
|
||||||
@ -270,6 +271,7 @@ class fhandler_base
|
|||||||
|
|
||||||
/* fixup fd possibly non-inherited handles after fork */
|
/* fixup fd possibly non-inherited handles after fork */
|
||||||
bool fork_fixup (HANDLE, HANDLE &, const char *);
|
bool fork_fixup (HANDLE, HANDLE &, const char *);
|
||||||
|
virtual bool need_fixup_before () const {return false;}
|
||||||
|
|
||||||
virtual int open (int, mode_t = 0);
|
virtual int open (int, mode_t = 0);
|
||||||
int open_fs (int, mode_t = 0);
|
int open_fs (int, mode_t = 0);
|
||||||
@ -463,6 +465,12 @@ class fhandler_socket: public fhandler_base
|
|||||||
void rmem (int nrmem) { _rmem = nrmem; }
|
void rmem (int nrmem) { _rmem = nrmem; }
|
||||||
void wmem (int nwmem) { _wmem = nwmem; }
|
void wmem (int nwmem) { _wmem = nwmem; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct _WSAPROTOCOL_INFOW *prot_info_ptr;
|
||||||
|
public:
|
||||||
|
void init_fixup_before ();
|
||||||
|
bool need_fixup_before () const {return prot_info_ptr != NULL;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *sun_path;
|
char *sun_path;
|
||||||
char *peer_sun_path;
|
char *peer_sun_path;
|
||||||
@ -524,7 +532,9 @@ class fhandler_socket: public fhandler_base
|
|||||||
int dup (fhandler_base *child);
|
int dup (fhandler_base *child);
|
||||||
|
|
||||||
void set_close_on_exec (bool val);
|
void set_close_on_exec (bool val);
|
||||||
|
int fixup_before_fork_exec (DWORD);
|
||||||
void fixup_after_fork (HANDLE);
|
void fixup_after_fork (HANDLE);
|
||||||
|
void fixup_after_exec ();
|
||||||
char *get_proc_fd_name (char *buf);
|
char *get_proc_fd_name (char *buf);
|
||||||
|
|
||||||
select_record *select_read (select_stuff *);
|
select_record *select_read (select_stuff *);
|
||||||
|
@ -151,6 +151,7 @@ fhandler_socket::fhandler_socket () :
|
|||||||
wsock_events (NULL),
|
wsock_events (NULL),
|
||||||
wsock_mtx (NULL),
|
wsock_mtx (NULL),
|
||||||
wsock_evt (NULL),
|
wsock_evt (NULL),
|
||||||
|
prot_info_ptr (NULL),
|
||||||
sun_path (NULL),
|
sun_path (NULL),
|
||||||
peer_sun_path (NULL),
|
peer_sun_path (NULL),
|
||||||
status ()
|
status ()
|
||||||
@ -160,6 +161,8 @@ fhandler_socket::fhandler_socket () :
|
|||||||
|
|
||||||
fhandler_socket::~fhandler_socket ()
|
fhandler_socket::~fhandler_socket ()
|
||||||
{
|
{
|
||||||
|
if (prot_info_ptr)
|
||||||
|
cfree (prot_info_ptr);
|
||||||
if (sun_path)
|
if (sun_path)
|
||||||
cfree (sun_path);
|
cfree (sun_path);
|
||||||
if (peer_sun_path)
|
if (peer_sun_path)
|
||||||
@ -631,12 +634,62 @@ fhandler_socket::release_events ()
|
|||||||
NtClose (wsock_mtx);
|
NtClose (wsock_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called from net.cc:fdsock() if a freshly created socket is not
|
||||||
|
inheritable. In that case we use fixup_before_fork_exec. See
|
||||||
|
the comment in fdsock() for a description of the problem. */
|
||||||
|
void
|
||||||
|
fhandler_socket::init_fixup_before ()
|
||||||
|
{
|
||||||
|
prot_info_ptr = (LPWSAPROTOCOL_INFOW)
|
||||||
|
cmalloc_abort (HEAP_BUF, sizeof (WSAPROTOCOL_INFOW));
|
||||||
|
cygheap->fdtab.inc_need_fixup_before ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_socket::fixup_before_fork_exec (DWORD win_pid)
|
||||||
|
{
|
||||||
|
SOCKET ret = WSADuplicateSocketW (get_socket (), win_pid, prot_info_ptr);
|
||||||
|
if (ret)
|
||||||
|
set_winsock_errno ();
|
||||||
|
else
|
||||||
|
debug_printf ("WSADuplicateSocket succeeded");
|
||||||
|
return (int) ret;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_socket::fixup_after_fork (HANDLE parent)
|
fhandler_socket::fixup_after_fork (HANDLE parent)
|
||||||
{
|
{
|
||||||
fork_fixup (parent, wsock_mtx, "wsock_mtx");
|
fork_fixup (parent, wsock_mtx, "wsock_mtx");
|
||||||
fork_fixup (parent, wsock_evt, "wsock_evt");
|
fork_fixup (parent, wsock_evt, "wsock_evt");
|
||||||
fhandler_base::fixup_after_fork (parent);
|
|
||||||
|
if (!need_fixup_before ())
|
||||||
|
{
|
||||||
|
fhandler_base::fixup_after_fork (parent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET new_sock = WSASocketW (FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
|
||||||
|
FROM_PROTOCOL_INFO, prot_info_ptr, 0, 0);
|
||||||
|
if (new_sock == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
set_winsock_errno ();
|
||||||
|
set_io_handle ((HANDLE) INVALID_SOCKET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Even though the original socket was not inheritable, the duplicated
|
||||||
|
socket is potentially inheritable again. */
|
||||||
|
SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
|
||||||
|
set_io_handle ((HANDLE) new_sock);
|
||||||
|
debug_printf ("WSASocket succeeded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_socket::fixup_after_exec ()
|
||||||
|
{
|
||||||
|
if (need_fixup_before () && !close_on_exec ())
|
||||||
|
fixup_after_fork (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -679,13 +732,33 @@ fhandler_socket::dup (fhandler_base *child)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fhs->connect_state (connect_state ());
|
fhs->connect_state (connect_state ());
|
||||||
int ret = fhandler_base::dup (child);
|
|
||||||
if (ret)
|
if (!need_fixup_before ())
|
||||||
{
|
{
|
||||||
NtClose (fhs->wsock_evt);
|
int ret = fhandler_base::dup (child);
|
||||||
NtClose (fhs->wsock_mtx);
|
if (ret)
|
||||||
|
{
|
||||||
|
NtClose (fhs->wsock_evt);
|
||||||
|
NtClose (fhs->wsock_mtx);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
cygheap->user.deimpersonate ();
|
||||||
|
fhs->init_fixup_before ();
|
||||||
|
fhs->set_io_handle (get_io_handle ());
|
||||||
|
if (!fhs->fixup_before_fork_exec (GetCurrentProcessId ()))
|
||||||
|
{
|
||||||
|
cygheap->user.reimpersonate ();
|
||||||
|
fhs->fixup_after_fork (hMainProc);
|
||||||
|
if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cygheap->user.reimpersonate ();
|
||||||
|
cygheap->fdtab.dec_need_fixup_before ();
|
||||||
|
NtClose (fhs->wsock_evt);
|
||||||
|
NtClose (fhs->wsock_mtx);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
|
@ -302,6 +302,13 @@ frok::parent (volatile char * volatile stack_here)
|
|||||||
else
|
else
|
||||||
c_flags |= DETACHED_PROCESS;
|
c_flags |= DETACHED_PROCESS;
|
||||||
|
|
||||||
|
/* Some file types (currently only sockets) need extra effort in the
|
||||||
|
parent after CreateProcess and before copying the datastructures
|
||||||
|
to the child. So we have to start the child in suspend state,
|
||||||
|
unfortunately, to avoid a race condition. */
|
||||||
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
|
c_flags |= CREATE_SUSPENDED;
|
||||||
|
|
||||||
/* Remember if we need to load dynamically linked dlls.
|
/* Remember if we need to load dynamically linked dlls.
|
||||||
We do this here so that this information will be available
|
We do this here so that this information will be available
|
||||||
in the parent and, when the stack is copied, in the child. */
|
in the parent and, when the stack is copied, in the child. */
|
||||||
@ -369,6 +376,12 @@ frok::parent (volatile char * volatile stack_here)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
|
{
|
||||||
|
cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
|
||||||
|
ResumeThread (pi.hThread);
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle (pi.hThread);
|
CloseHandle (pi.hThread);
|
||||||
|
|
||||||
/* Protect the handle but name it similarly to the way it will
|
/* Protect the handle but name it similarly to the way it will
|
||||||
|
@ -495,6 +495,34 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
|
|||||||
fd->uninterruptible_io (true);
|
fd->uninterruptible_io (true);
|
||||||
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc);
|
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc);
|
||||||
|
|
||||||
|
/* Usually sockets are inheritable IFS objects. Unfortunately some virus
|
||||||
|
scanners or other network-oriented software replace normal sockets
|
||||||
|
with their own kind, which is running through a filter driver.
|
||||||
|
|
||||||
|
The result is that these new sockets are not normal kernel objects
|
||||||
|
anymore. They are typically not marked as inheritable, nor are they
|
||||||
|
IFS handles, as normal OS sockets are. They are in fact not inheritable
|
||||||
|
to child processes, and subsequent socket calls in the child process
|
||||||
|
will fail with error 10038, WSAENOTSOCK. And worse, while DuplicateHandle
|
||||||
|
on these sockets mostly works in the process which created the socket,
|
||||||
|
DuplicateHandle does quite often not work anymore in a child process.
|
||||||
|
It does not help to mark them inheritable via SetHandleInformation.
|
||||||
|
|
||||||
|
The only way to make these sockets usable in child processes is to
|
||||||
|
duplicate them via WSADuplicateSocket/WSASocket calls. This requires
|
||||||
|
some incredible amount of extra processing so we only do this on
|
||||||
|
affected systems. If we recognize a non-inheritable socket, or if
|
||||||
|
the XP1_IFS_HANDLES flag is not set in a call to WSADuplicateSocket,
|
||||||
|
we switch to inheritance/dup via WSADuplicateSocket/WSASocket for
|
||||||
|
that socket. */
|
||||||
|
DWORD flags;
|
||||||
|
WSAPROTOCOL_INFOW wpi;
|
||||||
|
if (!GetHandleInformation ((HANDLE) soc, &flags)
|
||||||
|
|| !(flags & HANDLE_FLAG_INHERIT)
|
||||||
|
|| WSADuplicateSocketW (soc, GetCurrentProcessId (), &wpi)
|
||||||
|
|| !(wpi.dwServiceFlags1 & XP1_IFS_HANDLES))
|
||||||
|
((fhandler_socket *) fd)->init_fixup_before ();
|
||||||
|
|
||||||
/* Raise default buffer sizes (instead of WinSock default 8K).
|
/* Raise default buffer sizes (instead of WinSock default 8K).
|
||||||
|
|
||||||
64K appear to have the best size/performance ratio for a default
|
64K appear to have the best size/performance ratio for a default
|
||||||
|
@ -529,7 +529,8 @@ spawn_guts (const char *prog_arg, const char *const *argv,
|
|||||||
and before copying the datastructures to the child. So we have to start
|
and before copying the datastructures to the child. So we have to start
|
||||||
the child in suspend state, unfortunately, to avoid a race condition. */
|
the child in suspend state, unfortunately, to avoid a race condition. */
|
||||||
if (!newargv.win16_exe
|
if (!newargv.win16_exe
|
||||||
&& (!ch.iscygwin () || mode != _P_OVERLAY))
|
&& (!ch.iscygwin () || mode != _P_OVERLAY
|
||||||
|
|| cygheap->fdtab.need_fixup_before ()))
|
||||||
c_flags |= CREATE_SUSPENDED;
|
c_flags |= CREATE_SUSPENDED;
|
||||||
|
|
||||||
/* When ruid != euid we create the new process under the current original
|
/* When ruid != euid we create the new process under the current original
|
||||||
@ -656,6 +657,11 @@ loop:
|
|||||||
if (!(c_flags & CREATE_SUSPENDED))
|
if (!(c_flags & CREATE_SUSPENDED))
|
||||||
strace.write_childpid (ch, pi.dwProcessId);
|
strace.write_childpid (ch, pi.dwProcessId);
|
||||||
|
|
||||||
|
/* Fixup the parent data structures if needed and resume the child's
|
||||||
|
main thread. */
|
||||||
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
|
cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
|
||||||
|
|
||||||
if (mode != _P_OVERLAY)
|
if (mode != _P_OVERLAY)
|
||||||
cygpid = cygwin_pid (pi.dwProcessId);
|
cygpid = cygwin_pid (pi.dwProcessId);
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user