Change name from commune_recv to commune_process throughout. Change name from
commune_send to commune_request throughout. * pinfo.h (PICOM_EXTRASTR): New flag. (PICOM_FIFO): Define with new flag. (_pinfo::hello_pid): Delete. (_pinfo::tothem): Delete. (_pinfo::fromthem): Delete. (_pinfo::commune_process): Rename from commune_recv. Add a siginfo_t argument to declaration. (_pinfo::commune_request): Rename from commune_send. Change DWORD to __uint32_t in declaration. * pinfo.cc (_pinfo::commune_process): Rename from commune_recv. Add siginfo_t argument. Use information from argument rather than reading from another pipe. Synchronize with other process's commune event. (_pinfo::commune_request): Rename from commune_send. Change DWORD to __uint32 in argument. Fill out information in new siginfo_t element and rely on extended operation of sig_send rather than trying to deal with synchronization issues here. Use process handle and read pipe information filled out by sig_send to gather information from the other process. * sigproc.cc (sig_send): Take special action if "communing" to ensure synchronization with the other process and to return information about the other process to the caller. (talktome): Accept a siginfo_t and handle arguments. Read additional information from the signal pipe when _si_commune._si_code has the PICOM_EXTRASTR flag set. (wait_sig): Pass the transmitted siginfo_t struct and the pipe handle to talktome. Close pipe read handle as soon as possible after we detect that we're exiting.
This commit is contained in:
parent
503490bb9f
commit
0730fa0763
|
@ -1,3 +1,35 @@
|
||||||
|
2005-09-28 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
Change name from commune_recv to commune_process throughout.
|
||||||
|
Change name from commune_send to commune_request throughout.
|
||||||
|
* pinfo.h (PICOM_EXTRASTR): New flag.
|
||||||
|
(PICOM_FIFO): Define with new flag.
|
||||||
|
(_pinfo::hello_pid): Delete.
|
||||||
|
(_pinfo::tothem): Delete.
|
||||||
|
(_pinfo::fromthem): Delete.
|
||||||
|
(_pinfo::commune_process): Rename from commune_recv. Add a siginfo_t
|
||||||
|
argument to declaration.
|
||||||
|
(_pinfo::commune_request): Rename from commune_send. Change DWORD to
|
||||||
|
__uint32_t in declaration.
|
||||||
|
* pinfo.cc (_pinfo::commune_process): Rename from commune_recv. Add
|
||||||
|
siginfo_t argument. Use information from argument rather than reading
|
||||||
|
from another pipe. Synchronize with other process's commune event.
|
||||||
|
(_pinfo::commune_request): Rename from commune_send. Change DWORD to
|
||||||
|
__uint32 in argument. Fill out information in new siginfo_t element
|
||||||
|
and rely on extended operation of sig_send rather than trying to deal
|
||||||
|
with synchronization issues here. Use process handle and read pipe
|
||||||
|
information filled out by sig_send to gather information from the other
|
||||||
|
process.
|
||||||
|
* sigproc.cc (sig_send): Take special action if "communing" to ensure
|
||||||
|
synchronization with the other process and to return information about
|
||||||
|
the other process to the caller.
|
||||||
|
(talktome): Accept a siginfo_t and handle arguments. Read additional
|
||||||
|
information from the signal pipe when _si_commune._si_code has the
|
||||||
|
PICOM_EXTRASTR flag set.
|
||||||
|
(wait_sig): Pass the transmitted siginfo_t struct and the pipe handle
|
||||||
|
to talktome. Close pipe read handle as soon as possible after we
|
||||||
|
detect that we're exiting.
|
||||||
|
|
||||||
2005-09-28 Christopher Faylor <cgf@timesys.com>
|
2005-09-28 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* hookapi.cc (hook_or_detect_cygwin): Correct inverted test for whether
|
* hookapi.cc (hook_or_detect_cygwin): Correct inverted test for whether
|
||||||
|
|
|
@ -99,7 +99,7 @@ fhandler_fifo::open_not_mine (int flags)
|
||||||
commune_result r;
|
commune_result r;
|
||||||
if (p->pid != myself->pid)
|
if (p->pid != myself->pid)
|
||||||
{
|
{
|
||||||
r = p->commune_send (PICOM_FIFO, get_win32_name ());
|
r = p->commune_request (PICOM_FIFO, get_win32_name ());
|
||||||
if (r.handles[0] == NULL)
|
if (r.handles[0] == NULL)
|
||||||
continue; // process doesn't own fifo
|
continue; // process doesn't own fifo
|
||||||
debug_printf ("pid %d, handles[0] %p, handles[1] %p", p->pid,
|
debug_printf ("pid %d, handles[0] %p, handles[1] %p", p->pid,
|
||||||
|
|
|
@ -42,6 +42,20 @@ typedef struct sigevent
|
||||||
} sigevent_t;
|
} sigevent_t;
|
||||||
|
|
||||||
#pragma pack(push,4)
|
#pragma pack(push,4)
|
||||||
|
struct _sigcommune
|
||||||
|
{
|
||||||
|
__uint32_t _si_code;
|
||||||
|
void *_si_read_handle;
|
||||||
|
void *_si_write_handle;
|
||||||
|
void *_si_process_handle;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
int _si_fd;
|
||||||
|
void *_si_pipe_fhandler;
|
||||||
|
char *_si_str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int si_signo; /* signal number */
|
int si_signo; /* signal number */
|
||||||
|
@ -53,6 +67,7 @@ typedef struct
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
__uint32_t __pad[32]; /* plan for future growth */
|
__uint32_t __pad[32]; /* plan for future growth */
|
||||||
|
struct _sigcommune _si_commune; /* cygwin ipc */
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
/* timers */
|
/* timers */
|
||||||
|
|
|
@ -380,58 +380,24 @@ _pinfo::alive ()
|
||||||
extern char **__argv;
|
extern char **__argv;
|
||||||
|
|
||||||
void
|
void
|
||||||
_pinfo::commune_recv ()
|
_pinfo::commune_process (siginfo_t& si)
|
||||||
{
|
{
|
||||||
char path[CYG_MAX_PATH];
|
char path[CYG_MAX_PATH];
|
||||||
DWORD nr;
|
DWORD nr;
|
||||||
DWORD code;
|
HANDLE& tothem = si._si_commune._si_write_handle;
|
||||||
HANDLE hp;
|
HANDLE process_sync =
|
||||||
HANDLE __fromthem = NULL;
|
OpenSemaphore (SYNCHRONIZE, false, shared_name (path, "commune", si.si_pid));
|
||||||
HANDLE __tothem = NULL;
|
if (process_sync) // FIXME: this test shouldn't be necessary
|
||||||
|
ProtectHandle (process_sync);
|
||||||
|
|
||||||
hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId);
|
switch (si._si_commune._si_code)
|
||||||
if (!hp)
|
|
||||||
{
|
|
||||||
sigproc_printf ("couldn't open handle for pid %d(%u)", pid, dwProcessId);
|
|
||||||
hello_pid = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!DuplicateHandle (hp, fromthem, hMainProc, &__fromthem, 0, false, DUPLICATE_SAME_ACCESS))
|
|
||||||
{
|
|
||||||
sigproc_printf ("couldn't duplicate fromthem, %E");
|
|
||||||
CloseHandle (hp);
|
|
||||||
hello_pid = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DuplicateHandle (hp, tothem, hMainProc, &__tothem, 0, false, DUPLICATE_SAME_ACCESS))
|
|
||||||
{
|
|
||||||
sigproc_printf ("couldn't duplicate tothem, %E");
|
|
||||||
CloseHandle (__fromthem);
|
|
||||||
CloseHandle (hp);
|
|
||||||
hello_pid = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hello_pid = 0;
|
|
||||||
|
|
||||||
if (!ReadFile (__fromthem, &code, sizeof code, &nr, NULL) || nr != sizeof code)
|
|
||||||
{
|
|
||||||
CloseHandle (hp);
|
|
||||||
/* __seterrno ();*/ // this is run from the signal thread, so don't set errno
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (code)
|
|
||||||
{
|
{
|
||||||
case PICOM_CMDLINE:
|
case PICOM_CMDLINE:
|
||||||
{
|
{
|
||||||
unsigned n = 1;
|
unsigned n = 1;
|
||||||
CloseHandle (__fromthem); __fromthem = NULL;
|
|
||||||
extern int __argc_safe;
|
extern int __argc_safe;
|
||||||
const char *argv[__argc_safe + 1];
|
const char *argv[__argc_safe + 1];
|
||||||
|
|
||||||
CloseHandle (hp);
|
|
||||||
for (int i = 0; i < __argc_safe; i++)
|
for (int i = 0; i < __argc_safe; i++)
|
||||||
{
|
{
|
||||||
if (IsBadStringPtr (__argv[i], INT32_MAX))
|
if (IsBadStringPtr (__argv[i], INT32_MAX))
|
||||||
|
@ -441,19 +407,19 @@ _pinfo::commune_recv ()
|
||||||
n += strlen (argv[i]) + 1;
|
n += strlen (argv[i]) + 1;
|
||||||
}
|
}
|
||||||
argv[__argc_safe] = NULL;
|
argv[__argc_safe] = NULL;
|
||||||
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
{
|
{
|
||||||
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno
|
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno
|
||||||
sigproc_printf ("WriteFile sizeof argv failed, %E");
|
sigproc_printf ("WriteFile sizeof argv failed, %E");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (const char **a = argv; *a; a++)
|
for (const char **a = argv; *a; a++)
|
||||||
if (!WriteFile (__tothem, *a, strlen (*a) + 1, &nr, NULL))
|
if (!WriteFile (tothem, *a, strlen (*a) + 1, &nr, NULL))
|
||||||
{
|
{
|
||||||
sigproc_printf ("WriteFile arg %d failed, %E", a - argv);
|
sigproc_printf ("WriteFile arg %d failed, %E", a - argv);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!WriteFile (__tothem, "", 1, &nr, NULL))
|
if (!WriteFile (tothem, "", 1, &nr, NULL))
|
||||||
{
|
{
|
||||||
sigproc_printf ("WriteFile null failed, %E");
|
sigproc_printf ("WriteFile null failed, %E");
|
||||||
break;
|
break;
|
||||||
|
@ -462,46 +428,40 @@ _pinfo::commune_recv ()
|
||||||
}
|
}
|
||||||
case PICOM_CWD:
|
case PICOM_CWD:
|
||||||
{
|
{
|
||||||
CloseHandle (__fromthem); __fromthem = NULL;
|
|
||||||
CloseHandle (hp);
|
|
||||||
unsigned int n = strlen (cygheap->cwd.get (path, 1, 1,
|
unsigned int n = strlen (cygheap->cwd.get (path, 1, 1,
|
||||||
CYG_MAX_PATH)) + 1;
|
CYG_MAX_PATH)) + 1;
|
||||||
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile sizeof cwd failed, %E");
|
sigproc_printf ("WriteFile sizeof cwd failed, %E");
|
||||||
else if (!WriteFile (__tothem, path, n, &nr, NULL))
|
else if (!WriteFile (tothem, path, n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile cwd failed, %E");
|
sigproc_printf ("WriteFile cwd failed, %E");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PICOM_ROOT:
|
case PICOM_ROOT:
|
||||||
{
|
{
|
||||||
CloseHandle (__fromthem); __fromthem = NULL;
|
unsigned n;
|
||||||
CloseHandle (hp);
|
|
||||||
unsigned int n;
|
|
||||||
if (cygheap->root.exists ())
|
if (cygheap->root.exists ())
|
||||||
n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1;
|
n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1;
|
||||||
else
|
else
|
||||||
n = strlen (strcpy (path, "/")) + 1;
|
n = strlen (strcpy (path, "/")) + 1;
|
||||||
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile sizeof root failed, %E");
|
sigproc_printf ("WriteFile sizeof root failed, %E");
|
||||||
else if (!WriteFile (__tothem, path, n, &nr, NULL))
|
else if (!WriteFile (tothem, path, n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile root failed, %E");
|
sigproc_printf ("WriteFile root failed, %E");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PICOM_FDS:
|
case PICOM_FDS:
|
||||||
{
|
{
|
||||||
CloseHandle (__fromthem); __fromthem = NULL;
|
|
||||||
CloseHandle (hp);
|
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
int fd;
|
int fd;
|
||||||
cygheap_fdenum cfd;
|
cygheap_fdenum cfd;
|
||||||
while ((fd = cfd.next ()) >= 0)
|
while ((fd = cfd.next ()) >= 0)
|
||||||
n += sizeof (int);
|
n += sizeof (int);
|
||||||
cfd.rewind ();
|
cfd.rewind ();
|
||||||
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile sizeof fds failed, %E");
|
sigproc_printf ("WriteFile sizeof fds failed, %E");
|
||||||
else
|
else
|
||||||
while ((fd = cfd.next ()) >= 0)
|
while ((fd = cfd.next ()) >= 0)
|
||||||
if (!WriteFile (__tothem, &fd, sizeof fd, &nr, NULL))
|
if (!WriteFile (tothem, &fd, sizeof fd, &nr, NULL))
|
||||||
{
|
{
|
||||||
sigproc_printf ("WriteFile fd %d failed, %E", fd);
|
sigproc_printf ("WriteFile fd %d failed, %E", fd);
|
||||||
break;
|
break;
|
||||||
|
@ -510,16 +470,7 @@ _pinfo::commune_recv ()
|
||||||
}
|
}
|
||||||
case PICOM_PIPE_FHANDLER:
|
case PICOM_PIPE_FHANDLER:
|
||||||
{
|
{
|
||||||
HANDLE hdl;
|
HANDLE hdl = si._si_commune._si_pipe_fhandler;
|
||||||
if (!ReadFile (__fromthem, &hdl, sizeof hdl, &nr, NULL)
|
|
||||||
|| nr != sizeof hdl)
|
|
||||||
{
|
|
||||||
sigproc_printf ("ReadFile hdl failed, %E");
|
|
||||||
CloseHandle (hp);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
CloseHandle (__fromthem); __fromthem = NULL;
|
|
||||||
CloseHandle (hp);
|
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
cygheap_fdenum cfd;
|
cygheap_fdenum cfd;
|
||||||
while (cfd.next () >= 0)
|
while (cfd.next () >= 0)
|
||||||
|
@ -527,59 +478,34 @@ _pinfo::commune_recv ()
|
||||||
{
|
{
|
||||||
fhandler_pipe *fh = cfd;
|
fhandler_pipe *fh = cfd;
|
||||||
n = sizeof *fh;
|
n = sizeof *fh;
|
||||||
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile sizeof hdl failed, %E");
|
sigproc_printf ("WriteFile sizeof hdl failed, %E");
|
||||||
else if (!WriteFile (__tothem, fh, n, &nr, NULL))
|
else if (!WriteFile (tothem, fh, n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile hdl failed, %E");
|
sigproc_printf ("WriteFile hdl failed, %E");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!n && !WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!n && !WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile sizeof hdl failed, %E");
|
sigproc_printf ("WriteFile sizeof hdl failed, %E");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PICOM_FD:
|
case PICOM_FD:
|
||||||
{
|
{
|
||||||
int fd;
|
int fd = si._si_commune._si_fd;
|
||||||
if (!ReadFile (__fromthem, &fd, sizeof fd, &nr, NULL)
|
|
||||||
|| nr != sizeof fd)
|
|
||||||
{
|
|
||||||
sigproc_printf ("ReadFile fd failed, %E");
|
|
||||||
CloseHandle (hp);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
CloseHandle (__fromthem); __fromthem = NULL;
|
|
||||||
CloseHandle (hp);
|
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
cygheap_fdget cfd (fd);
|
cygheap_fdget cfd (fd);
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
n = strlen (strcpy (path, "")) + 1;
|
n = strlen (strcpy (path, "")) + 1;
|
||||||
else
|
else
|
||||||
n = strlen (cfd->get_proc_fd_name (path)) + 1;
|
n = strlen (cfd->get_proc_fd_name (path)) + 1;
|
||||||
if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
|
if (!WriteFile (tothem, &n, sizeof n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile sizeof fd failed, %E");
|
sigproc_printf ("WriteFile sizeof fd failed, %E");
|
||||||
else if (!WriteFile (__tothem, path, n, &nr, NULL))
|
else if (!WriteFile (tothem, path, n, &nr, NULL))
|
||||||
sigproc_printf ("WriteFile fd failed, %E");
|
sigproc_printf ("WriteFile fd failed, %E");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PICOM_FIFO:
|
case PICOM_FIFO:
|
||||||
{
|
{
|
||||||
unsigned len;
|
fhandler_fifo *fh = cygheap->fdtab.find_fifo (si._si_commune._si_str);
|
||||||
if (!ReadFile (__fromthem, &len, sizeof len, &nr, NULL)
|
|
||||||
|| nr != sizeof len)
|
|
||||||
{
|
|
||||||
CloseHandle (hp);
|
|
||||||
/* __seterrno ();*/ // this is run from the signal thread, so don't set errno
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* Get null-terminated path */
|
|
||||||
if (!ReadFile (__fromthem, path, len, &nr, NULL)
|
|
||||||
|| nr != len)
|
|
||||||
{
|
|
||||||
CloseHandle (hp);
|
|
||||||
/* __seterrno ();*/ // this is run from the signal thread, so don't set errno
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fhandler_fifo *fh = cygheap->fdtab.find_fifo (path);
|
|
||||||
HANDLE it[2];
|
HANDLE it[2];
|
||||||
if (fh == NULL)
|
if (fh == NULL)
|
||||||
it[0] = it[1] = NULL;
|
it[0] = it[1] = NULL;
|
||||||
|
@ -587,46 +513,40 @@ _pinfo::commune_recv ()
|
||||||
{
|
{
|
||||||
it[0] = fh->get_handle ();
|
it[0] = fh->get_handle ();
|
||||||
it[1] = fh->get_output_handle ();
|
it[1] = fh->get_output_handle ();
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
if (!DuplicateHandle (hMainProc, it[i], hp, &it[i], 0, false,
|
|
||||||
DUPLICATE_SAME_ACCESS))
|
|
||||||
{
|
|
||||||
it[0] = it[1] = NULL; /* FIXME: possibly left a handle open in child? */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
debug_printf ("fifo found %p, %p", it[0], it[1]);
|
|
||||||
fh->close_one_end (); /* FIXME: not quite right - need more handshaking */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle (hp);
|
debug_printf ("fifo %sfound %p, %p", fh ? "" : "not ", it[0], it[1]);
|
||||||
if (!WriteFile (__tothem, it, sizeof (it), &nr, NULL))
|
if (!WriteFile (tothem, it, sizeof (it), &nr, NULL))
|
||||||
{
|
{
|
||||||
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno
|
/*__seterrno ();*/ // this is run from the signal thread, so don't set errno
|
||||||
sigproc_printf ("WriteFile read handle failed, %E");
|
sigproc_printf ("WriteFile read handle failed, %E");
|
||||||
}
|
}
|
||||||
|
WaitForSingleObject (process_sync, INFINITE);
|
||||||
ReadFile (__fromthem, &nr, sizeof (nr), &nr, NULL);
|
process_sync = NULL;
|
||||||
|
if (fh)
|
||||||
|
fh->close_one_end ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (process_sync)
|
||||||
out:
|
{
|
||||||
if (__fromthem)
|
WaitForSingleObject (process_sync, INFINITE);
|
||||||
CloseHandle (__fromthem);
|
ForceCloseHandle (process_sync);
|
||||||
if (__tothem)
|
}
|
||||||
CloseHandle (__tothem);
|
CloseHandle (tothem);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PIPEBUFSIZE (4096 * sizeof (DWORD))
|
|
||||||
|
|
||||||
commune_result
|
commune_result
|
||||||
_pinfo::commune_send (DWORD code, ...)
|
_pinfo::commune_request (__uint32_t code, ...)
|
||||||
{
|
{
|
||||||
HANDLE fromthem = NULL, tome = NULL;
|
|
||||||
HANDLE fromme = NULL, tothem = NULL;
|
|
||||||
DWORD nr;
|
DWORD nr;
|
||||||
commune_result res;
|
commune_result res;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
siginfo_t si = {0};
|
||||||
|
HANDLE& hp = si._si_commune._si_process_handle;
|
||||||
|
HANDLE& fromthem = si._si_commune._si_read_handle;
|
||||||
|
HANDLE request_sync = NULL;
|
||||||
|
bool locked = false;
|
||||||
|
|
||||||
va_start (args, code);
|
va_start (args, code);
|
||||||
|
|
||||||
|
@ -638,86 +558,45 @@ _pinfo::commune_send (DWORD code, ...)
|
||||||
set_errno (ESRCH);
|
set_errno (ESRCH);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!CreatePipe (&fromthem, &tome, &sec_all_nih, PIPEBUFSIZE))
|
|
||||||
{
|
|
||||||
sigproc_printf ("first CreatePipe failed, %E");
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!CreatePipe (&fromme, &tothem, &sec_all_nih, PIPEBUFSIZE))
|
|
||||||
{
|
|
||||||
sigproc_printf ("second CreatePipe failed, %E");
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
myself.lock ();
|
|
||||||
myself->tothem = tome;
|
|
||||||
myself->fromthem = fromme;
|
|
||||||
myself->hello_pid = pid;
|
|
||||||
if (!WriteFile (tothem, &code, sizeof code, &nr, NULL) || nr != sizeof code)
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig_send (this, __SIGCOMMUNE))
|
si._si_commune._si_code = code;
|
||||||
goto err;
|
switch (code)
|
||||||
|
{
|
||||||
/* FIXME: Need something better than an busy loop here */
|
case PICOM_PIPE_FHANDLER:
|
||||||
bool isalive;
|
si._si_commune._si_pipe_fhandler = va_arg (args, HANDLE);
|
||||||
for (int i = 0; (isalive = alive ()) && (i < 10000); i++)
|
|
||||||
if (myself->hello_pid <= 0)
|
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
low_priority_sleep (0);
|
|
||||||
|
|
||||||
CloseHandle (tome);
|
case PICOM_FD:
|
||||||
tome = NULL;
|
si._si_commune._si_fd = va_arg (args, int);
|
||||||
CloseHandle (fromme);
|
break;
|
||||||
fromme = NULL;
|
|
||||||
|
|
||||||
if (!isalive)
|
case PICOM_FIFO:
|
||||||
{
|
si._si_commune._si_str = va_arg (args, char *);
|
||||||
set_errno (ESRCH);
|
break;
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myself->hello_pid < 0)
|
myself.lock ();
|
||||||
{
|
locked = true;
|
||||||
set_errno (ENOSYS);
|
char name_buf[CYG_MAX_PATH];
|
||||||
goto err;
|
request_sync = CreateSemaphore (&sec_none_nih, 0, LONG_MAX,
|
||||||
}
|
shared_name (name_buf, "commune", myself->pid));
|
||||||
|
if (!request_sync)
|
||||||
|
goto err;
|
||||||
|
ProtectHandle (request_sync);
|
||||||
|
|
||||||
|
si.si_signo = __SIGCOMMUNE;
|
||||||
|
if (sig_send (this, si))
|
||||||
|
goto err;
|
||||||
|
|
||||||
size_t n;
|
size_t n;
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case PICOM_PIPE_FHANDLER:
|
|
||||||
{
|
|
||||||
HANDLE hdl = va_arg (args, HANDLE);
|
|
||||||
if (!WriteFile (tothem, &hdl, sizeof hdl, &nr, NULL)
|
|
||||||
|| nr != sizeof hdl)
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto business_as_usual;
|
|
||||||
case PICOM_FD:
|
|
||||||
{
|
|
||||||
int fd = va_arg (args, int);
|
|
||||||
if (!WriteFile (tothem, &fd, sizeof fd, &nr, NULL)
|
|
||||||
|| nr != sizeof fd)
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto business_as_usual;
|
|
||||||
case PICOM_CMDLINE:
|
case PICOM_CMDLINE:
|
||||||
case PICOM_CWD:
|
case PICOM_CWD:
|
||||||
case PICOM_ROOT:
|
case PICOM_ROOT:
|
||||||
case PICOM_FDS:
|
case PICOM_FDS:
|
||||||
business_as_usual:
|
case PICOM_FD:
|
||||||
|
case PICOM_PIPE_FHANDLER:
|
||||||
if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n)
|
if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n)
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
|
@ -741,51 +620,42 @@ _pinfo::commune_send (DWORD code, ...)
|
||||||
break;
|
break;
|
||||||
case PICOM_FIFO:
|
case PICOM_FIFO:
|
||||||
{
|
{
|
||||||
char *path = va_arg (args, char *);
|
|
||||||
size_t len = strlen (path) + 1;
|
|
||||||
if (!WriteFile (tothem, &len, sizeof (len), &nr, NULL)
|
|
||||||
|| nr != sizeof (len))
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!WriteFile (tothem, path, len, &nr, NULL) || nr != len)
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD x = ReadFile (fromthem, res.handles, sizeof (res.handles), &nr, NULL);
|
DWORD x = ReadFile (fromthem, res.handles, sizeof (res.handles), &nr, NULL);
|
||||||
WriteFile (tothem, &x, sizeof (x), &x, NULL);
|
if (!x || nr != sizeof (res.handles))
|
||||||
if (!x)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (nr != sizeof (res.handles))
|
|
||||||
{
|
{
|
||||||
set_errno (EPIPE);
|
__seterrno ();
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
if (!DuplicateHandle (hp, res.handles[i], hMainProc, &res.handles[i],
|
||||||
|
0, false, DUPLICATE_SAME_ACCESS))
|
||||||
|
{
|
||||||
|
if (i)
|
||||||
|
CloseHandle (res.handles[0]);
|
||||||
|
res.handles[0] = res.handles[1] = NULL; /* FIXME: possibly left a handle open in child? */
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CloseHandle (tothem);
|
|
||||||
CloseHandle (fromthem);
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (tome)
|
|
||||||
CloseHandle (tome);
|
|
||||||
if (fromthem)
|
|
||||||
CloseHandle (fromthem);
|
|
||||||
if (tothem)
|
|
||||||
CloseHandle (tothem);
|
|
||||||
if (fromme)
|
|
||||||
CloseHandle (fromme);
|
|
||||||
memset (&res, 0, sizeof (res));
|
memset (&res, 0, sizeof (res));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
myself->hello_pid = 0;
|
if (request_sync)
|
||||||
myself.unlock ();
|
{
|
||||||
|
LONG res;
|
||||||
|
ReleaseSemaphore (request_sync, 1, &res);
|
||||||
|
ForceCloseHandle (request_sync);
|
||||||
|
}
|
||||||
|
if (locked)
|
||||||
|
myself.unlock ();
|
||||||
|
if (hp)
|
||||||
|
CloseHandle (hp);
|
||||||
|
if (fromthem)
|
||||||
|
CloseHandle (fromthem);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +666,7 @@ _pinfo::pipe_fhandler (HANDLE hdl, size_t &n)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid == myself->pid)
|
if (pid == myself->pid)
|
||||||
return NULL;
|
return NULL;
|
||||||
commune_result cr = commune_send (PICOM_PIPE_FHANDLER, hdl);
|
commune_result cr = commune_request (PICOM_PIPE_FHANDLER, hdl);
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
return (fhandler_pipe *) cr.s;
|
return (fhandler_pipe *) cr.s;
|
||||||
}
|
}
|
||||||
|
@ -809,7 +679,7 @@ _pinfo::fd (int fd, size_t &n)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid != myself->pid)
|
if (pid != myself->pid)
|
||||||
{
|
{
|
||||||
commune_result cr = commune_send (PICOM_FD, fd);
|
commune_result cr = commune_request (PICOM_FD, fd);
|
||||||
s = cr.s;
|
s = cr.s;
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
}
|
}
|
||||||
|
@ -833,7 +703,7 @@ _pinfo::fds (size_t &n)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid != myself->pid)
|
if (pid != myself->pid)
|
||||||
{
|
{
|
||||||
commune_result cr = commune_send (PICOM_FDS);
|
commune_result cr = commune_request (PICOM_FDS);
|
||||||
s = cr.s;
|
s = cr.s;
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
}
|
}
|
||||||
|
@ -861,7 +731,7 @@ _pinfo::root (size_t& n)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid != myself->pid)
|
if (pid != myself->pid)
|
||||||
{
|
{
|
||||||
commune_result cr = commune_send (PICOM_ROOT);
|
commune_result cr = commune_request (PICOM_ROOT);
|
||||||
s = cr.s;
|
s = cr.s;
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
}
|
}
|
||||||
|
@ -884,7 +754,7 @@ _pinfo::cwd (size_t& n)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid != myself->pid)
|
if (pid != myself->pid)
|
||||||
{
|
{
|
||||||
commune_result cr = commune_send (PICOM_CWD);
|
commune_result cr = commune_request (PICOM_CWD);
|
||||||
s = cr.s;
|
s = cr.s;
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
}
|
}
|
||||||
|
@ -905,7 +775,7 @@ _pinfo::cmdline (size_t& n)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pid != myself->pid)
|
if (pid != myself->pid)
|
||||||
{
|
{
|
||||||
commune_result cr = commune_send (PICOM_CMDLINE);
|
commune_result cr = commune_request (PICOM_CMDLINE);
|
||||||
s = cr.s;
|
s = cr.s;
|
||||||
n = cr.n;
|
n = cr.n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,9 @@ struct commune_result
|
||||||
|
|
||||||
enum picom
|
enum picom
|
||||||
{
|
{
|
||||||
|
PICOM_EXTRASTR = 0x80000000,
|
||||||
PICOM_CMDLINE = 1,
|
PICOM_CMDLINE = 1,
|
||||||
PICOM_FIFO = 2,
|
PICOM_FIFO = PICOM_EXTRASTR | 2,
|
||||||
PICOM_CWD = 3,
|
PICOM_CWD = 3,
|
||||||
PICOM_ROOT = 4,
|
PICOM_ROOT = 4,
|
||||||
PICOM_FDS = 5,
|
PICOM_FDS = 5,
|
||||||
|
@ -57,9 +58,8 @@ public:
|
||||||
pid_t ppid;
|
pid_t ppid;
|
||||||
|
|
||||||
/* dwProcessId contains the processid used for sending signals. It
|
/* dwProcessId contains the processid used for sending signals. It
|
||||||
* will be reset in a child process when it is capable of receiving
|
will be reset in a child process when it is capable of receiving
|
||||||
* signals.
|
signals. */
|
||||||
*/
|
|
||||||
DWORD dwProcessId;
|
DWORD dwProcessId;
|
||||||
|
|
||||||
/* Used to spawn a child for fork(), among other things. */
|
/* Used to spawn a child for fork(), among other things. */
|
||||||
|
@ -87,11 +87,6 @@ public:
|
||||||
/* Non-zero if process was stopped by a signal. */
|
/* Non-zero if process was stopped by a signal. */
|
||||||
char stopsig;
|
char stopsig;
|
||||||
|
|
||||||
/* commune */
|
|
||||||
pid_t hello_pid;
|
|
||||||
HANDLE tothem;
|
|
||||||
HANDLE fromthem;
|
|
||||||
|
|
||||||
inline void set_has_pgid_children ()
|
inline void set_has_pgid_children ()
|
||||||
{
|
{
|
||||||
if (pgid == pid)
|
if (pgid == pid)
|
||||||
|
@ -110,10 +105,10 @@ public:
|
||||||
sig_mask = mask;
|
sig_mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void commune_recv ();
|
void commune_process (siginfo_t&);
|
||||||
commune_result commune_send (DWORD, ...);
|
commune_result commune_request (__uint32_t, ...);
|
||||||
bool alive ();
|
bool alive ();
|
||||||
fhandler_pipe *pipe_fhandler (HANDLE hdl, size_t &);
|
fhandler_pipe *pipe_fhandler (HANDLE, size_t &);
|
||||||
char *fd (int fd, size_t &);
|
char *fd (int fd, size_t &);
|
||||||
char *fds (size_t &);
|
char *fds (size_t &);
|
||||||
char *root (size_t &);
|
char *root (size_t &);
|
||||||
|
@ -156,7 +151,6 @@ public:
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
CRITICAL_SECTION _lock;
|
CRITICAL_SECTION _lock;
|
||||||
bool waiter_ready;
|
bool waiter_ready;
|
||||||
/* Handle associated with initial Windows pid which started it all. */
|
|
||||||
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 () {}
|
pinfo () {}
|
||||||
|
|
|
@ -526,6 +526,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||||
bool its_me;
|
bool its_me;
|
||||||
HANDLE sendsig;
|
HANDLE sendsig;
|
||||||
sigpacket pack;
|
sigpacket pack;
|
||||||
|
bool communing = si.si_signo == __SIGCOMMUNE;
|
||||||
|
|
||||||
pack.wakeup = NULL;
|
pack.wakeup = NULL;
|
||||||
bool wait_for_completion;
|
bool wait_for_completion;
|
||||||
|
@ -598,8 +599,29 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||||
CloseHandle (hp);
|
CloseHandle (hp);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
CloseHandle (hp);
|
|
||||||
VerifyHandle (sendsig);
|
VerifyHandle (sendsig);
|
||||||
|
if (!communing)
|
||||||
|
CloseHandle (hp);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
si._si_commune._si_process_handle = hp;
|
||||||
|
|
||||||
|
HANDLE& tome = si._si_commune._si_write_handle;
|
||||||
|
HANDLE& fromthem = si._si_commune._si_read_handle;
|
||||||
|
if (!CreatePipe (&fromthem, &tome, &sec_all_nih, 0))
|
||||||
|
{
|
||||||
|
sigproc_printf ("CreatePipe for __SIGCOMMUNE failed, %E");
|
||||||
|
__seterrno ();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!DuplicateHandle (hMainProc, tome, hp, &tome, false, 0,
|
||||||
|
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
||||||
|
{
|
||||||
|
sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
|
||||||
|
__seterrno ();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, si.si_signo, its_me);
|
sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, si.si_signo, its_me);
|
||||||
|
@ -628,8 +650,25 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||||
ProtectHandle (pack.wakeup);
|
ProtectHandle (pack.wakeup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *leader;
|
||||||
|
size_t packsize;
|
||||||
|
if (!communing || !(si._si_commune._si_code & PICOM_EXTRASTR))
|
||||||
|
{
|
||||||
|
leader = (char *) &pack;
|
||||||
|
packsize = sizeof (pack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t n = strlen (si._si_commune._si_str);
|
||||||
|
char *p = leader = (char *) alloca (sizeof (pack) + sizeof (n) + n);
|
||||||
|
memcpy (p, &pack, sizeof (pack)); p += sizeof (pack);
|
||||||
|
memcpy (p, &n, sizeof (n)); p += sizeof (n);
|
||||||
|
memcpy (p, si._si_commune._si_str, n); p += n;
|
||||||
|
packsize = p - leader;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD nb;
|
DWORD nb;
|
||||||
if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
|
if (!WriteFile (sendsig, leader, packsize, &nb, NULL) || nb != packsize)
|
||||||
{
|
{
|
||||||
/* Couldn't send to the pipe. This probably means that the
|
/* Couldn't send to the pipe. This probably means that the
|
||||||
process is exiting. */
|
process is exiting. */
|
||||||
|
@ -687,8 +726,16 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||||
|
|
||||||
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
||||||
_my_tls.call_signal_handler ();
|
_my_tls.call_signal_handler ();
|
||||||
|
goto out;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (communing && rc)
|
||||||
|
{
|
||||||
|
if (si._si_commune._si_process_handle)
|
||||||
|
CloseHandle (si._si_commune._si_process_handle);
|
||||||
|
if (si._si_commune._si_read_handle)
|
||||||
|
CloseHandle (si._si_commune._si_read_handle);
|
||||||
|
}
|
||||||
if (pack.wakeup)
|
if (pack.wakeup)
|
||||||
ForceCloseHandle (pack.wakeup);
|
ForceCloseHandle (pack.wakeup);
|
||||||
if (si.si_signo != __SIGPENDING)
|
if (si.si_signo != __SIGPENDING)
|
||||||
|
@ -921,11 +968,23 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
talktome (siginfo_t& si)
|
talktome (siginfo_t& si, HANDLE readsig)
|
||||||
{
|
{
|
||||||
pinfo p (si.si_pid, PID_MAP_RW);
|
pinfo pi (si.si_pid);
|
||||||
if (p)
|
if (si._si_commune._si_code & PICOM_EXTRASTR)
|
||||||
p->commune_recv ();
|
{
|
||||||
|
size_t n;
|
||||||
|
DWORD nb;
|
||||||
|
if (!ReadFile (readsig, &n, sizeof (n), &nb, NULL) || nb != sizeof (n))
|
||||||
|
return;
|
||||||
|
// FIXME: Is alloca here?
|
||||||
|
si._si_commune._si_str = (char *) alloca (n + 1);
|
||||||
|
if (!ReadFile (readsig, si._si_commune._si_str, n, &nb, NULL) || nb != n)
|
||||||
|
return;
|
||||||
|
si._si_commune._si_str[n] = '\0';
|
||||||
|
}
|
||||||
|
if (pi)
|
||||||
|
pi->commune_process (si);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1039,7 +1098,7 @@ wait_sig (VOID *)
|
||||||
switch (pack.si.si_signo)
|
switch (pack.si.si_signo)
|
||||||
{
|
{
|
||||||
case __SIGCOMMUNE:
|
case __SIGCOMMUNE:
|
||||||
talktome (pack.si);
|
talktome (pack.si, readsig);
|
||||||
break;
|
break;
|
||||||
case __SIGSTRACE:
|
case __SIGSTRACE:
|
||||||
strace.hello ();
|
strace.hello ();
|
||||||
|
|
Loading…
Reference in New Issue