* include/cygwin/version.h: Bump DLL minor version number to 5 due to all of
the changes below. Redefine process structure to avoid a fixed size table. Redefine pinfo/_pinfo classes. Use these throughout. * dcrt0.cc (dll_crt0_1): Accomodate set_myself argument change. (__api_fatal): Accomodate _pinfo::record_death argument change. * exceptions.cc (really_exit): Ditto. (sig_handle_tty_stop): Use pinfo constructor to access process info. (events_init): Don't create pinfo_mutex since it is no longer required. * external.cc (fillout_pinfo): Use winpids class to iterate over all system pids. (cygwin_internal): lock_pinfo_for_update and unlock_pinfo are now noops. * fhandler_termios.cc (fhandler_termios::set_ctty): Use pinfo constructor to access process info. * fork.cc (fork): Reorganize to initialize child info after the child has started since that is when we know the child's winpid, which is necessary to allocate the pinfo shared memory. * mmap.cc (recreate_mmaps_after_fork): Change arg type to _pinfo. * pinfo.cc: Rename pinfo methods to _pinfo throughout. Eliminate pinfo_list stuff. (set_myself): Accept a pid argument now. Call pinfo initializer to initialize myself. Detect when this is an "execed" process and create an "indirect" pid block. (pinfo_init): Accomodate set_myself arg change. (procinfo): Remove. (pinfo::lock_pinfo): Remove. (pinfo::unlock_pinfo): Remove. (pinfo::init): New method. Allocates shared memory space for process pinfo structure. (pinfo::record_death): Don't call locking functions. (cygwin_winpid_to_pid): Simplify by using new pinfo constructor. (EnumProcessesW95): New function for iterating over processes on Windows 95. (winpids::winpids): New constructor for winpids class. Sets up a list of process ids. (enum_init): Initialize w95/wnt pid enumerators. * shared.cc (shared-info::initialize): Remove pid initialization. * shared.h: Move pinfo stuff into pinfo.h. (class shared_info): Remove pinfo_list element. * signal.cc (kill_worker): Use pinfo constructor to access process info. (kill_pgrp): Ditto. Use winpids methods to access list of processes. * sigproc.cc: Throughout, modify to use _pinfo where appropriate. (proc_exists (pid_t)): New function. Determines if a process exists based on the pid. (proc_exists (_pinfo *p): Use new proc_exists function above. (proc_subproc): Copy pinfo stuff around rather than _pinfo pointers. Try to be careful about releasing shared memory when we don't need it anymore. Remove pinfo locks. (remove_zombies): Remove pinfo memory when zombie is going away. * sigproc.h: Reflect _pinfo/pinfo changes in sigproc.cc. * spawn.cc (spawn_guts): Eliminate pinfo *child argument. Reorganize to only initialize child pinfo after process has been started and we know the windows pid. (_spawnve): Reflect spawn_guts changes. * syscalls.cc (setpgid): Use pinfo constructor to access process info. (getpgid): Ditto. (internal_getlogin): Use _pinfo. * winsup.h: Eliminate pinfo_mutex. Eliminate spawn_guts declaration since it is static now. Reflect set_myself argument change. * include/sys/cygwin.h: Add some PID_* enums to accomodate new pinfo stuff. * include/cygwin/version.h: Update minor version for cygdrive changes below.
This commit is contained in:
@@ -223,13 +223,24 @@ linebuf::prepend (const char *what, int len)
|
||||
ix = newix;
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
static HANDLE hexec_proc = NULL;
|
||||
|
||||
void __stdcall
|
||||
exec_fixup_after_fork ()
|
||||
{
|
||||
if (hexec_proc)
|
||||
CloseHandle (hexec_proc);
|
||||
hexec_proc = NULL;
|
||||
}
|
||||
|
||||
static int __stdcall
|
||||
spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
||||
const char *const envp[], pinfo *child, int mode)
|
||||
const char *const envp[], int mode)
|
||||
{
|
||||
int i;
|
||||
BOOL rc;
|
||||
int argc;
|
||||
pid_t cygpid;
|
||||
|
||||
hExeced = NULL;
|
||||
|
||||
@@ -474,7 +485,7 @@ skip_arg_parsing:
|
||||
chtype = PROC_EXEC;
|
||||
}
|
||||
|
||||
init_child_info (chtype, ciresrv, child->pid, spr);
|
||||
init_child_info (chtype, ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
|
||||
|
||||
LPBYTE resrv = si.lpReserved2 + sizeof *ciresrv;
|
||||
# undef ciresrv
|
||||
@@ -509,6 +520,11 @@ skip_arg_parsing:
|
||||
if (!hToken && myself->token != INVALID_HANDLE_VALUE)
|
||||
hToken = myself->token;
|
||||
|
||||
if (mode == _P_OVERLAY && !hexec_proc &&
|
||||
!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS))
|
||||
system_printf ("couldn't save current process handle %p, %E", hMainProc);
|
||||
|
||||
if (hToken)
|
||||
{
|
||||
/* allow the child to interact with our window station/desktop */
|
||||
@@ -549,12 +565,6 @@ skip_arg_parsing:
|
||||
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
|
||||
seteuid (myself->orig_uid);
|
||||
|
||||
/* Set child->uid to USHRT_MAX to force calling internal_getlogin()
|
||||
from child process. Clear username and psid to play it safe. */
|
||||
child->uid = USHRT_MAX;
|
||||
child->username[0] = '\0';
|
||||
child->psid = NULL;
|
||||
|
||||
/* Load users registry hive. */
|
||||
load_registry_hive (sid);
|
||||
|
||||
@@ -599,15 +609,14 @@ skip_arg_parsing:
|
||||
if (!rc)
|
||||
__seterrno ();
|
||||
|
||||
MALLOC_CHECK;
|
||||
/* Name the handle similarly to proc_subproc. */
|
||||
ProtectHandle1 (pi.hProcess, childhProc);
|
||||
ProtectHandle (pi.hThread);
|
||||
MALLOC_CHECK;
|
||||
if (mode == _P_OVERLAY)
|
||||
cygpid = myself->pid;
|
||||
else
|
||||
cygpid = cygwin_pid (pi.dwProcessId);
|
||||
|
||||
/* We print the original program name here so the user can see that too. */
|
||||
syscall_printf ("%d = spawn_guts (%s, %.132s)",
|
||||
rc ? pi.dwProcessId : (unsigned int) -1,
|
||||
rc ? cygpid : (unsigned int) -1,
|
||||
prog_arg, one_line.buf);
|
||||
|
||||
if (!rc)
|
||||
@@ -617,27 +626,73 @@ skip_arg_parsing:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set up child's signal handlers */
|
||||
for (i = 0; i < NSIG; i++)
|
||||
{
|
||||
child->getsig(i).sa_mask = 0;
|
||||
if (myself->getsig(i).sa_handler != SIG_IGN || (mode != _P_OVERLAY))
|
||||
child->getsig(i).sa_handler = SIG_DFL;
|
||||
}
|
||||
MALLOC_CHECK;
|
||||
/* Name the handle similarly to proc_subproc. */
|
||||
ProtectHandle1 (pi.hProcess, childhProc);
|
||||
ProtectHandle (pi.hThread);
|
||||
MALLOC_CHECK;
|
||||
|
||||
if (mode == _P_OVERLAY)
|
||||
{
|
||||
close_all_files ();
|
||||
strcpy (child->progname, real_path_buf);
|
||||
strcpy (myself->progname, real_path_buf);
|
||||
proc_terminate ();
|
||||
hExeced = pi.hProcess;
|
||||
|
||||
/* Set up child's signal handlers */
|
||||
/* CGF FIXME - consolidate with signal stuff below */
|
||||
for (i = 0; i < NSIG; i++)
|
||||
{
|
||||
myself->getsig(i).sa_mask = 0;
|
||||
if (myself->getsig(i).sa_handler != SIG_IGN || (mode != _P_OVERLAY))
|
||||
myself->getsig(i).sa_handler = SIG_DFL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pinfo child (cygpid, 1);
|
||||
if (!child)
|
||||
{
|
||||
set_errno (EAGAIN);
|
||||
syscall_printf ("-1 = spawnve (), process table full");
|
||||
return -1;
|
||||
}
|
||||
child->username[0] = '\0';
|
||||
child->progname[0] = '\0';
|
||||
// CGF FIXME -- need to do this? strcpy (child->progname, path);
|
||||
// CGF FIXME -- need to do this? memcpy (child->username, myself->username, MAX_USER_NAME);
|
||||
child->ppid = myself->pid;
|
||||
child->uid = myself->uid;
|
||||
child->gid = myself->gid;
|
||||
child->pgid = myself->pgid;
|
||||
child->sid = myself->sid;
|
||||
child->ctty = myself->ctty;
|
||||
child->umask = myself->umask;
|
||||
child->process_state |= PID_INITIALIZING;
|
||||
memcpy (child->sidbuf, myself->sidbuf, MAX_SID_LEN);
|
||||
if (myself->psid)
|
||||
child->psid = child->sidbuf;
|
||||
memcpy (child->logsrv, myself->logsrv, MAX_HOST_NAME);
|
||||
memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
|
||||
memcpy (child->root, myself->root, MAX_PATH+1);
|
||||
child->rootlen = myself->rootlen;
|
||||
child->dwProcessId = pi.dwProcessId;
|
||||
child->hProcess = pi.hProcess;
|
||||
child->process_state |= PID_INITIALIZING;
|
||||
proc_register (child);
|
||||
for (i = 0; i < NSIG; i++)
|
||||
{
|
||||
child->getsig(i).sa_mask = 0;
|
||||
if (child->getsig(i).sa_handler != SIG_IGN || (mode != _P_OVERLAY))
|
||||
child->getsig(i).sa_handler = SIG_DFL;
|
||||
}
|
||||
if (hToken)
|
||||
{
|
||||
/* Set child->uid to USHRT_MAX to force calling internal_getlogin()
|
||||
from child process. Clear username and psid to play it safe. */
|
||||
child->uid = USHRT_MAX;
|
||||
child->psid = NULL;
|
||||
}
|
||||
child.remember ();
|
||||
}
|
||||
|
||||
sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
|
||||
@@ -735,13 +790,14 @@ skip_arg_parsing:
|
||||
* EXIT_REPARENTING status. Wait() syscall in parent will then wait
|
||||
* for newly created child.
|
||||
*/
|
||||
if (my_parent_is_alive ())
|
||||
pinfo parent (myself->ppid);
|
||||
if (!parent)
|
||||
/* nothing */;
|
||||
else
|
||||
{
|
||||
pinfo *parent = procinfo (myself->ppid);
|
||||
sigproc_printf ("parent = %p", parent);
|
||||
HANDLE hP = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
|
||||
parent->dwProcessId);
|
||||
sigproc_printf ("parent's handle = %d", hP);
|
||||
sigproc_printf ("parent handle %p, pid %d", hP, parent->dwProcessId);
|
||||
if (hP == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
|
||||
res = 1;
|
||||
else if (hP)
|
||||
@@ -778,18 +834,11 @@ skip_arg_parsing:
|
||||
}
|
||||
|
||||
if (mode == _P_WAIT)
|
||||
{
|
||||
waitpid (child->pid, (int *) &res, 0);
|
||||
}
|
||||
waitpid (cygpid, (int *) &res, 0);
|
||||
else if (mode == _P_DETACH)
|
||||
{
|
||||
/* Lose all memory of this child. */
|
||||
res = 0;
|
||||
}
|
||||
res = 0; /* Lose all memory of this child. */
|
||||
else if ((mode == _P_NOWAIT) || (mode == _P_NOWAITO))
|
||||
{
|
||||
res = child->pid;
|
||||
}
|
||||
res = cygpid;
|
||||
|
||||
return (int) res;
|
||||
}
|
||||
@@ -810,7 +859,6 @@ extern "C" int
|
||||
_spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
|
||||
const char *const *envp)
|
||||
{
|
||||
pinfo *child;
|
||||
int ret;
|
||||
vfork_save *vf = vfork_storage.val ();
|
||||
|
||||
@@ -826,7 +874,7 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
|
||||
case _P_OVERLAY:
|
||||
/* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
|
||||
/* Just act as an exec if _P_OVERLAY set. */
|
||||
spawn_guts (hToken, path, argv, envp, myself, mode);
|
||||
spawn_guts (hToken, path, argv, envp, mode);
|
||||
/* Errno should be set by spawn_guts. */
|
||||
ret = -1;
|
||||
break;
|
||||
@@ -834,38 +882,11 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
|
||||
case _P_NOWAITO:
|
||||
case _P_WAIT:
|
||||
case _P_DETACH:
|
||||
child = cygwin_shared->p.allocate_pid ();
|
||||
if (!child)
|
||||
{
|
||||
set_errno (EAGAIN);
|
||||
syscall_printf ("-1 = spawnve (), process table full");
|
||||
return -1;
|
||||
}
|
||||
strcpy (child->progname, path);
|
||||
child->ppid = myself->pid;
|
||||
child->uid = myself->uid;
|
||||
child->gid = myself->gid;
|
||||
child->pgid = myself->pgid;
|
||||
child->sid = myself->sid;
|
||||
child->ctty = myself->ctty;
|
||||
child->umask = myself->umask;
|
||||
child->process_state |= PID_INITIALIZING;
|
||||
memcpy (child->username, myself->username, MAX_USER_NAME);
|
||||
memcpy (child->sidbuf, myself->sidbuf, MAX_SID_LEN);
|
||||
if (myself->psid)
|
||||
child->psid = child->sidbuf;
|
||||
memcpy (child->logsrv, myself->logsrv, MAX_HOST_NAME);
|
||||
memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
|
||||
memcpy (child->root, myself->root, MAX_PATH+1);
|
||||
child->rootlen = myself->rootlen;
|
||||
subproc_init ();
|
||||
ret = spawn_guts (hToken, path, argv, envp, child, mode);
|
||||
if (ret == -1)
|
||||
child->process_state = PID_NOT_IN_USE;
|
||||
|
||||
ret = spawn_guts (hToken, path, argv, envp, mode);
|
||||
if (vf)
|
||||
{
|
||||
vf->pid = child->pid;
|
||||
vf->pid = ret;
|
||||
longjmp (vf->j, 1);
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user