* 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:
parent
53211514a0
commit
84c7d40932
|
@ -1,3 +1,77 @@
|
|||
Sat Jul 29 12:11:33 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* include/cygwin/version.h: Bump DLL minor version number to 5 due
|
||||
to all of the changes below.
|
||||
|
||||
Sat Jul 29 12:01:32 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
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.
|
||||
|
||||
Sat Jul 29 12:13:27 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* include/cygwin/version.h: Update minor version for cygdrive changes
|
||||
below.
|
||||
|
||||
Sat Jul 29 11:59:29 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* environ.cc (parse_thing): Make binmode a DWORD.
|
||||
|
@ -5,6 +79,16 @@ Sat Jul 29 11:59:29 2000 Christopher Faylor <cgf@cygnus.com>
|
|||
determine default open mode.
|
||||
* winsup.h: Declare binmode.
|
||||
|
||||
Sat Jul 29 00:16:35 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* include/cygwin/cygwin_dll.h: Update for modern compilers.
|
||||
* lib/cygwin_crt0.c: Inexplicably need to define alloca for newer
|
||||
compilers.
|
||||
* fhandler.h (fhandler_console): Add new method.
|
||||
* fhandler.cc (fhandler_console::set_cursor_maybe): New method.
|
||||
(fhandler_console::read): Set cursor if it has moved to make it
|
||||
visible.
|
||||
|
||||
Thu Jul 27 22:54:28 2000 Jason Tishler <jt@dothill.com>
|
||||
|
||||
* dcrt0.cc (dummy_autoload): Add load statement for RegDeleteValueA.
|
||||
|
|
|
@ -8,7 +8,7 @@ __infinity
|
|||
__main
|
||||
__srget
|
||||
__swbuf
|
||||
__vc__10pinfo_listi
|
||||
; __vc__10pinfo_listi
|
||||
@ALLOCA@
|
||||
cygwin_stackdump
|
||||
abort
|
||||
|
|
|
@ -657,7 +657,7 @@ dll_crt0_1 ()
|
|||
// should be blocked.
|
||||
|
||||
if (mypid)
|
||||
set_myself (cygwin_shared->p[mypid]);
|
||||
set_myself ((pid_t) mypid);
|
||||
|
||||
(void) SetErrorMode (SEM_FAILCRITICALERRORS);
|
||||
|
||||
|
@ -1047,7 +1047,7 @@ __api_fatal (const char *fmt, ...)
|
|||
/* We are going down without mercy. Make sure we reset
|
||||
our process_state. */
|
||||
sigproc_terminate ();
|
||||
myself->record_death (FALSE);
|
||||
myself->record_death ();
|
||||
#ifdef DEBUGGING
|
||||
(void) try_to_debug ();
|
||||
#endif
|
||||
|
|
|
@ -627,7 +627,7 @@ winenv (const char * const *envp, int keep_posix)
|
|||
did not seem to know about importing data variables from the DLL.
|
||||
So, we have to synchronize cygwin's idea of the environment with the
|
||||
main program's with each reference to the environment. */
|
||||
char ** __stdcall
|
||||
extern "C" char ** __stdcall
|
||||
cur_environ ()
|
||||
{
|
||||
if (*main_environ != __cygwin_environ)
|
||||
|
|
|
@ -315,7 +315,6 @@ try_to_debug ()
|
|||
/* if any of these mutexes is owned, we will fail to start any cygwin app
|
||||
until trapped app exits */
|
||||
|
||||
ReleaseMutex (pinfo_mutex);
|
||||
ReleaseMutex (title_mutex);
|
||||
|
||||
/* prevent recursive exception handling */
|
||||
|
@ -877,7 +876,7 @@ sig_handle_tty_stop (int sig)
|
|||
*/
|
||||
if (my_parent_is_alive ())
|
||||
{
|
||||
pinfo *parent = procinfo (myself->ppid);
|
||||
pinfo parent (myself->ppid);
|
||||
sig_send (parent, __SIGCHILDSTOPPED);
|
||||
}
|
||||
sigproc_printf ("process %d stopped by signal %d, parent_alive %p",
|
||||
|
@ -1007,27 +1006,18 @@ signal_exit (int rc)
|
|||
if (exit_already++)
|
||||
{
|
||||
/* We are going down - reset our process_state without locking. */
|
||||
myself->record_death (FALSE);
|
||||
myself->record_death ();
|
||||
ExitProcess (rc);
|
||||
}
|
||||
|
||||
do_exit (rc);
|
||||
}
|
||||
|
||||
HANDLE NO_COPY pinfo_mutex = NULL;
|
||||
HANDLE NO_COPY title_mutex = NULL;
|
||||
|
||||
void
|
||||
events_init (void)
|
||||
{
|
||||
/* pinfo_mutex protects access to process table */
|
||||
|
||||
if (!(pinfo_mutex = CreateMutex (&sec_all_nih, FALSE,
|
||||
shared_name ("pinfo_mutex", 0))))
|
||||
api_fatal ("catastrophic failure - unable to create pinfo_mutex, %E");
|
||||
|
||||
ProtectHandle (pinfo_mutex);
|
||||
|
||||
/* title_mutex protects modification of console title. It's neccessary
|
||||
while finding console window handle */
|
||||
|
||||
|
@ -1056,12 +1046,11 @@ events_init (void)
|
|||
void
|
||||
events_terminate (void)
|
||||
{
|
||||
//CloseHandle (pinfo_mutex); // Use implicit close on exit to avoid race
|
||||
ForceCloseHandle (title_mutex);
|
||||
exit_already = 1;
|
||||
}
|
||||
|
||||
#define pid_offset (unsigned)(((pinfo *)NULL)->pid)
|
||||
#define pid_offset (unsigned)(((_pinfo *)NULL)->pid)
|
||||
extern "C" {
|
||||
static void __stdcall
|
||||
reset_signal_arrived () __attribute__ ((unused));
|
||||
|
|
|
@ -13,53 +13,80 @@ details. */
|
|||
#include "winsup.h"
|
||||
|
||||
static external_pinfo *
|
||||
fillout_pinfo (DWORD pid)
|
||||
fillout_pinfo (pid_t pid, int winpid)
|
||||
{
|
||||
BOOL nextpid;
|
||||
pinfo *p = NULL;
|
||||
int i;
|
||||
static external_pinfo ep;
|
||||
|
||||
if ((nextpid = !!(pid & CW_NEXTPID)))
|
||||
pid ^= CW_NEXTPID;
|
||||
for (i = 0; i < cygwin_shared->p.size(); i++, p = NULL)
|
||||
|
||||
static winpids pids (0);
|
||||
|
||||
if (!pids.npids)
|
||||
pids.init ();
|
||||
|
||||
memset (&ep, 0, sizeof ep);
|
||||
for (unsigned i = 0; i < pids.npids; i++)
|
||||
{
|
||||
p = cygwin_shared->p.vec + i;
|
||||
if (!pid || (DWORD) p->pid == pid)
|
||||
if (!pids[i])
|
||||
continue;
|
||||
pinfo p (pids[i]);
|
||||
pid_t thispid;
|
||||
|
||||
if (p)
|
||||
thispid = p->pid;
|
||||
else if (winpid)
|
||||
thispid = pids[i];
|
||||
else
|
||||
continue;
|
||||
|
||||
if (!pid || thispid == pid)
|
||||
{
|
||||
if (nextpid && pid)
|
||||
{
|
||||
pid = 0;
|
||||
nextpid = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!p)
|
||||
{
|
||||
ep.pid = pids[i];
|
||||
ep.dwProcessId = cygwin_pid (pids[i]);
|
||||
ep.process_state = PID_IN_USE;
|
||||
ep.ctty = -1;
|
||||
}
|
||||
else if (p->pid && NOTSTATE(p, PID_CLEAR))
|
||||
break;
|
||||
{
|
||||
ep.ctty = tty_attached (p) ? p->ctty : -1;
|
||||
ep.pid = p->pid;
|
||||
ep.ppid = p->ppid;
|
||||
ep.hProcess = p->hProcess;
|
||||
ep.dwProcessId = p->dwProcessId;
|
||||
ep.uid = p->uid;
|
||||
ep.gid = p->gid;
|
||||
ep.pgid = p->pgid;
|
||||
ep.sid = p->sid;
|
||||
ep.umask = p->umask;
|
||||
ep.start_time = p->start_time;
|
||||
ep.rusage_self = p->rusage_self;
|
||||
ep.rusage_children = p->rusage_children;
|
||||
strcpy (ep.progname, p->progname);
|
||||
ep.strace_mask = 0;
|
||||
ep.strace_file = 0;
|
||||
|
||||
ep.process_state = p->process_state;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
|
||||
memset (&ep, 0, sizeof ep);
|
||||
ep.ctty = tty_attached (p) ? p->ctty : -1;
|
||||
ep.pid = p->pid;
|
||||
ep.ppid = p->ppid;
|
||||
ep.hProcess = p->hProcess;
|
||||
ep.dwProcessId = p->dwProcessId;
|
||||
//ep.dwSpawnedProcessId = p->dwSpawnedProcessId;
|
||||
ep.uid = p->uid;
|
||||
ep.gid = p->gid;
|
||||
ep.pgid = p->pgid;
|
||||
ep.sid = p->sid;
|
||||
ep.umask = p->umask;
|
||||
ep.start_time = p->start_time;
|
||||
ep.rusage_self = p->rusage_self;
|
||||
ep.rusage_children = p->rusage_children;
|
||||
strcpy (ep.progname, p->progname);
|
||||
ep.strace_mask = 0;
|
||||
ep.strace_file = 0;
|
||||
|
||||
ep.process_state = p->process_state;
|
||||
if (!ep.pid)
|
||||
{
|
||||
pids.reset ();
|
||||
return 0;
|
||||
}
|
||||
return &ep;
|
||||
}
|
||||
|
||||
|
@ -80,11 +107,9 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||
switch (t)
|
||||
{
|
||||
case CW_LOCK_PINFO:
|
||||
return lock_pinfo_for_update (va_arg (arg, DWORD));
|
||||
break;
|
||||
return 1;
|
||||
|
||||
case CW_UNLOCK_PINFO:
|
||||
unlock_pinfo ();
|
||||
return 1;
|
||||
|
||||
case CW_GETTHREADNAME:
|
||||
|
@ -98,7 +123,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||
}
|
||||
|
||||
case CW_GETPINFO:
|
||||
return (DWORD) fillout_pinfo (va_arg (arg, DWORD));
|
||||
return (DWORD) fillout_pinfo (va_arg (arg, DWORD), 0);
|
||||
|
||||
case CW_GETVERSIONINFO:
|
||||
return (DWORD) cygwin_version_strings;
|
||||
|
@ -122,6 +147,9 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||
return get_cygdrive_prefixes (user, system);
|
||||
}
|
||||
|
||||
case CW_GETPINFO_FULL:
|
||||
return (DWORD) fillout_pinfo (va_arg (arg, pid_t), 1);
|
||||
|
||||
default:
|
||||
return (DWORD) -1;
|
||||
}
|
||||
|
|
|
@ -110,6 +110,23 @@ set_console_state_for_spawn ()
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_console::set_cursor_maybe ()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO now;
|
||||
static CONSOLE_SCREEN_BUFFER_INFO last = {{0, 0}, {-1, -1}, 0, {0, 0}, {0, 0}};
|
||||
|
||||
if (!GetConsoleScreenBufferInfo (get_output_handle(), &now))
|
||||
return;
|
||||
|
||||
if (last.dwCursorPosition.X != now.dwCursorPosition.X ||
|
||||
last.dwCursorPosition.Y != now.dwCursorPosition.Y)
|
||||
{
|
||||
SetConsoleCursorPosition (get_output_handle (), now.dwCursorPosition);
|
||||
last.dwCursorPosition = now.dwCursorPosition;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_console::read (void *pv, size_t buflen)
|
||||
{
|
||||
|
@ -147,7 +164,7 @@ fhandler_console::read (void *pv, size_t buflen)
|
|||
if ((bgres = bg_check (SIGTTIN)) <= 0)
|
||||
return bgres;
|
||||
|
||||
cursor_rel (0,0); /* to make cursor appear on the screen immediately */
|
||||
set_cursor_maybe (); /* to make cursor appear on the screen immediately */
|
||||
switch (WaitForMultipleObjects (nwait, w4, FALSE, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
|
@ -1244,6 +1261,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
syscall_printf ("%d = write_console (,..%d)", len, len);
|
||||
|
||||
return len;
|
||||
|
|
|
@ -84,7 +84,7 @@ fhandler_termios::set_ctty (int ttynum, int flags)
|
|||
syscall_printf ("attached tty%d sid %d, pid %d, tty->pgid %d, tty->sid %d",
|
||||
ttynum, myself->sid, myself->pid, tc->pgid, tc->getsid ());
|
||||
|
||||
pinfo *p = procinfo (tc->getsid ());
|
||||
pinfo p (tc->getsid ());
|
||||
if (myself->sid == myself->pid &&
|
||||
(p == myself || !proc_exists (p)))
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ fhandler_termios::bg_check (int sig)
|
|||
|
||||
/* If the process group is no more or if process is ignoring or blocks 'sig',
|
||||
return with error */
|
||||
int pgid_gone = !proc_exists (procinfo (myself->pgid));
|
||||
int pgid_gone = !proc_exists (myself->pgid);
|
||||
int sigs_ignored =
|
||||
((void *) myself->getsig(sig).sa_handler == (void *) SIG_IGN) ||
|
||||
(myself->getsigmask () & SIGTOMASK (sig));
|
||||
|
|
|
@ -241,11 +241,11 @@ fork ()
|
|||
int res;
|
||||
DWORD rc;
|
||||
HANDLE hParent;
|
||||
pinfo *child;
|
||||
HANDLE subproc_ready, forker_finished;
|
||||
void *stack_here;
|
||||
int x;
|
||||
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
|
||||
static NO_COPY HANDLE last_fork_proc = NULL;
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
||||
|
@ -271,15 +271,6 @@ fork ()
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Don't start the fork until we have the lock. */
|
||||
child = cygwin_shared->p.allocate_pid ();
|
||||
if (!child)
|
||||
{
|
||||
set_errno (EAGAIN);
|
||||
syscall_printf ("-1 = fork (), process table full");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Remember the address of the first loaded dll and decide
|
||||
if we need to load dlls. We do this here so that this
|
||||
information will be available in the parent and, when
|
||||
|
@ -292,12 +283,9 @@ fork ()
|
|||
|
||||
if (x == 0)
|
||||
{
|
||||
|
||||
/* This will help some of the confusion. */
|
||||
fflush (stdout);
|
||||
|
||||
debug_printf ("parent pid %d, child pid %d", myself->pid, child->pid);
|
||||
|
||||
subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||
forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||
ProtectHandle (subproc_ready);
|
||||
|
@ -326,7 +314,7 @@ fork ()
|
|||
free (malloc (4096));
|
||||
#endif
|
||||
|
||||
init_child_info (PROC_FORK1, &ch, child->pid, subproc_ready);
|
||||
init_child_info (PROC_FORK1, &ch, 1, subproc_ready);
|
||||
|
||||
ch.forker_finished = forker_finished;
|
||||
ch.heaptop = user_data->heaptop;
|
||||
|
@ -335,10 +323,6 @@ fork ()
|
|||
|
||||
stack_base (ch);
|
||||
|
||||
/* Initialize things that are done later in dll_crt0_1 that aren't done
|
||||
for the forkee. */
|
||||
strcpy(child->progname, myself->progname);
|
||||
|
||||
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
|
||||
|
||||
si.cb = sizeof (STARTUPINFO);
|
||||
|
@ -393,7 +377,6 @@ fork ()
|
|||
{
|
||||
__seterrno ();
|
||||
syscall_printf ("-1 = fork(), CreateProcessA failed");
|
||||
child->process_state = PID_NOT_IN_USE;
|
||||
ForceCloseHandle(subproc_ready);
|
||||
ForceCloseHandle(forker_finished);
|
||||
subproc_ready = forker_finished = NULL;
|
||||
|
@ -403,6 +386,12 @@ fork ()
|
|||
return -1;
|
||||
}
|
||||
|
||||
pinfo forked (cygwin_pid (pi.dwProcessId), 1);
|
||||
|
||||
/* Initialize things that are done later in dll_crt0_1 that aren't done
|
||||
for the forkee. */
|
||||
strcpy(forked->progname, myself->progname);
|
||||
|
||||
/* Restore impersonation */
|
||||
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
|
||||
seteuid (uid);
|
||||
|
@ -411,35 +400,43 @@ fork ()
|
|||
/* Protect the handle but name it similarly to the way it will
|
||||
be called in subproc handling. */
|
||||
ProtectHandle1 (pi.hProcess, childhProc);
|
||||
if (os_being_run != winNT)
|
||||
{
|
||||
if (last_fork_proc)
|
||||
CloseHandle (last_fork_proc);
|
||||
if (!DuplicateHandle (hMainProc, pi.hProcess, hMainProc, &last_fork_proc,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
system_printf ("couldn't create last_fork_proc, %E");
|
||||
}
|
||||
|
||||
/* Fill in fields in the child's process table entry. */
|
||||
child->ppid = myself->pid;
|
||||
child->hProcess = pi.hProcess;
|
||||
child->dwProcessId = pi.dwProcessId;
|
||||
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->copysigs(myself);
|
||||
child->process_state |= PID_INITIALIZING |
|
||||
forked->ppid = myself->pid;
|
||||
forked->hProcess = pi.hProcess;
|
||||
forked->dwProcessId = pi.dwProcessId;
|
||||
forked->uid = myself->uid;
|
||||
forked->gid = myself->gid;
|
||||
forked->pgid = myself->pgid;
|
||||
forked->sid = myself->sid;
|
||||
forked->ctty = myself->ctty;
|
||||
forked->umask = myself->umask;
|
||||
forked->copysigs(myself);
|
||||
forked->process_state |= PID_INITIALIZING |
|
||||
(myself->process_state & PID_USETTY);
|
||||
memcpy (child->username, myself->username, MAX_USER_NAME);
|
||||
memcpy (child->sidbuf, myself->sidbuf, MAX_SID_LEN);
|
||||
memcpy (forked->username, myself->username, MAX_USER_NAME);
|
||||
memcpy (forked->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);
|
||||
child->token = myself->token;
|
||||
child->impersonated = myself->impersonated;
|
||||
child->orig_uid = myself->orig_uid;
|
||||
child->orig_gid = myself->orig_gid;
|
||||
child->real_uid = myself->real_uid;
|
||||
child->real_gid = myself->real_gid;
|
||||
memcpy (child->root, myself->root, MAX_PATH+1);
|
||||
child->rootlen = myself->rootlen;
|
||||
set_child_mmap_ptr (child);
|
||||
forked->psid = forked->sidbuf;
|
||||
memcpy (forked->logsrv, myself->logsrv, MAX_HOST_NAME);
|
||||
memcpy (forked->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
|
||||
forked->token = myself->token;
|
||||
forked->impersonated = myself->impersonated;
|
||||
forked->orig_uid = myself->orig_uid;
|
||||
forked->orig_gid = myself->orig_gid;
|
||||
forked->real_uid = myself->real_uid;
|
||||
forked->real_gid = myself->real_gid;
|
||||
strcpy (forked->root, myself->root);
|
||||
forked->rootlen = myself->rootlen;
|
||||
set_child_mmap_ptr (forked);
|
||||
|
||||
/* Wait for subproc to initialize itself. */
|
||||
if (!sync_with_child(pi, subproc_ready, TRUE, "waiting for longjmp"))
|
||||
|
@ -476,7 +473,7 @@ fork ()
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
proc_register (child);
|
||||
forked.remember ();
|
||||
|
||||
/* Start thread, and wait for it to reload dlls. */
|
||||
if (!resume_child (pi, forker_finished) ||
|
||||
|
@ -508,7 +505,7 @@ fork ()
|
|||
forker_finished = NULL;
|
||||
pi.hThread = NULL;
|
||||
|
||||
res = child->pid;
|
||||
res = forked->pid;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -518,8 +515,7 @@ fork ()
|
|||
(void) stack_dummy (0); // Just to make sure
|
||||
debug_printf ("child is running %d", x);
|
||||
|
||||
debug_printf ("self %p, pid %d, ppid %d",
|
||||
myself, x, myself ? myself->ppid : -1);
|
||||
debug_printf ("pid %d, ppid %d", x, myself->ppid);
|
||||
|
||||
/* Restore the inheritance state as in parent
|
||||
Don't call setuid here! The flags are already set. */
|
||||
|
@ -563,6 +559,7 @@ fork ()
|
|||
|
||||
dtable.fixup_after_fork (hParent);
|
||||
signal_fixup_after_fork ();
|
||||
exec_fixup_after_fork ();
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
||||
|
@ -605,7 +602,6 @@ fork ()
|
|||
/* Common cleanup code for failure cases */
|
||||
cleanup:
|
||||
/* Remember to de-allocate the fd table. */
|
||||
child->process_state = PID_NOT_IN_USE;
|
||||
if (pi.hProcess)
|
||||
ForceCloseHandle1 (pi.hProcess, childhProc);
|
||||
if (pi.hThread)
|
||||
|
@ -614,7 +610,7 @@ cleanup:
|
|||
ForceCloseHandle (subproc_ready);
|
||||
if (forker_finished)
|
||||
ForceCloseHandle (forker_finished);
|
||||
forker_finished = subproc_ready = child->hProcess = NULL;
|
||||
forker_finished = subproc_ready = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ details. */
|
|||
/* The current cygwin version is 1.1.0 */
|
||||
|
||||
#define CYGWIN_VERSION_DLL_MAJOR 1001
|
||||
#define CYGWIN_VERSION_DLL_MINOR 4
|
||||
#define CYGWIN_VERSION_DLL_MINOR 5
|
||||
|
||||
/* Major numbers before CYGWIN_VERSION_DLL_EPOCH are
|
||||
incompatible. */
|
||||
|
@ -115,10 +115,12 @@ details. */
|
|||
with crt0 startup code.
|
||||
24: Export poll and _poll.
|
||||
25: Export getmode and _getmode.
|
||||
26: CW_GET_CYGDRIVE_PREFIXES addition to external.cc
|
||||
27: CW_GETPINFO_FULL addition to external.cc
|
||||
*/
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 24
|
||||
#define CYGWIN_VERSION_API_MINOR 28
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -60,7 +60,8 @@ typedef enum
|
|||
CW_READ_V1_MOUNT_TABLES,
|
||||
CW_USER_DATA,
|
||||
CW_PERFILE,
|
||||
CW_GET_CYGDRIVE_PREFIXES
|
||||
CW_GET_CYGDRIVE_PREFIXES,
|
||||
CW_GETPINFO_FULL
|
||||
} cygwin_getinfo_types;
|
||||
|
||||
#define CW_NEXTPID 0x80000000 // or with pid to get next one
|
||||
|
@ -86,7 +87,9 @@ enum
|
|||
PID_USETTY = 0x1000, // Setting this enables or disables cygwin's
|
||||
// tty support. This is inherited by
|
||||
// all execed or forked processes.
|
||||
PID_REPARENT = 0x2000 // child has execed
|
||||
PID_REPARENT = 0x2000, // child has execed
|
||||
PID_EXECED = 0x4000, // redirect to original pid info block
|
||||
PID_NOREDIR = 0x8000 // don't redirect if execed
|
||||
};
|
||||
|
||||
#ifdef WINVER
|
||||
|
|
|
@ -172,4 +172,5 @@ fi
|
|||
|
||||
echo "Version $cygwin_ver"
|
||||
set -$- $builddate
|
||||
set -x
|
||||
exec $windres --include-dir $dir/../w32api/include --include-dir $dir/include --define CYGWIN_BUILD_DATE="$1" --define CYGWIN_BUILD_TIME="$2" --define CYGWIN_VERSION='"'"$cygwin_ver"'"' $rcfile winver.o
|
||||
|
|
|
@ -468,7 +468,7 @@ recreate_mmaps_after_fork (void *param)
|
|||
pointer for fork. */
|
||||
|
||||
void __stdcall
|
||||
set_child_mmap_ptr (pinfo *child)
|
||||
set_child_mmap_ptr (_pinfo *child)
|
||||
{
|
||||
child->mmap_ptr = (void *) mmapped_areas;
|
||||
}
|
||||
|
|
|
@ -16,11 +16,12 @@ details. */
|
|||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define Win32_Winsock
|
||||
#include "winsup.h"
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "autoload.h"
|
||||
#include <winsock.h>
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ details. */
|
|||
#include <winsup.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Default to not using NTEA information */
|
||||
BOOL allow_ntea = FALSE;
|
||||
|
|
|
@ -14,33 +14,27 @@ details. */
|
|||
#include <limits.h>
|
||||
#include "winsup.h"
|
||||
|
||||
/* The first pid used; also the lowest value allowed. */
|
||||
#define PBASE 1000
|
||||
|
||||
static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
|
||||
|
||||
pinfo NO_COPY *myself = (pinfo *)&pinfo_dummy; // Avoid myself != NULL checks
|
||||
pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
|
||||
static pinfo NO_COPY myself_identity ((_pinfo *)&pinfo_dummy);
|
||||
|
||||
/* Initialize the process table.
|
||||
This is done once when the dll is first loaded. */
|
||||
|
||||
void
|
||||
pinfo_list::init (void)
|
||||
void __stdcall
|
||||
set_myself (pid_t pid)
|
||||
{
|
||||
next_pid = PBASE; /* Next pid to try to allocate. */
|
||||
|
||||
/* We assume the shared data area is already initialized to zeros.
|
||||
Note that SIG_DFL is zero. */
|
||||
}
|
||||
|
||||
pinfo * __stdcall
|
||||
set_myself (pinfo *p)
|
||||
{
|
||||
myself = p;
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
DWORD winpid = GetCurrentProcessId ();
|
||||
if (pid == 1)
|
||||
pid = cygwin_pid (winpid);
|
||||
myself.init (pid, 1);
|
||||
myself->dwProcessId = winpid;
|
||||
myself->process_state |= PID_IN_USE;
|
||||
myself->start_time = time (NULL); /* Register our starting time. */
|
||||
pid_t myself_cyg_pid = cygwin_pid (myself->dwProcessId);
|
||||
if (pid != myself_cyg_pid)
|
||||
myself_identity.init (myself_cyg_pid, PID_EXECED);
|
||||
|
||||
char buf[30];
|
||||
__small_sprintf (buf, "cYg%8x %x", _STRACE_INTERFACE_ACTIVATE_ADDR,
|
||||
|
@ -65,7 +59,7 @@ set_myself (pinfo *p)
|
|||
strace.prntf (1, "**********************************************");
|
||||
}
|
||||
|
||||
return myself;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize the process table entry for the current task.
|
||||
|
@ -94,9 +88,9 @@ pinfo_init (LPBYTE info)
|
|||
{
|
||||
/* Invent our own pid. */
|
||||
|
||||
if (!set_myself (cygwin_shared->p.allocate_pid ()))
|
||||
api_fatal ("No more processes");
|
||||
myself->ppid = myself->pgid = myself->sid = myself->pid;
|
||||
set_myself (1);
|
||||
myself->ppid = 1;
|
||||
myself->pgid = myself->sid = myself->pid;
|
||||
myself->ctty = -1;
|
||||
myself->uid = USHRT_MAX;
|
||||
|
||||
|
@ -106,25 +100,8 @@ pinfo_init (LPBYTE info)
|
|||
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
|
||||
}
|
||||
|
||||
/* [] operator. This is the mechanism for table lookups. */
|
||||
/* Returns the index into the pinfo_list table for pid arg */
|
||||
|
||||
pinfo *
|
||||
pinfo_list::operator[] (pid_t pid)
|
||||
{
|
||||
if (pid <= 0)
|
||||
return NULL;
|
||||
|
||||
pinfo *p = vec + (pid % size ());
|
||||
|
||||
if (p->pid != pid || p->process_state == PID_NOT_IN_USE)
|
||||
return NULL;
|
||||
else
|
||||
return p;
|
||||
}
|
||||
|
||||
struct sigaction&
|
||||
pinfo::getsig(int sig)
|
||||
_pinfo::getsig(int sig)
|
||||
{
|
||||
#ifdef _MT_SAFE
|
||||
if ( thread2signal )
|
||||
|
@ -136,7 +113,7 @@ pinfo::getsig(int sig)
|
|||
};
|
||||
|
||||
sigset_t&
|
||||
pinfo::getsigmask ()
|
||||
_pinfo::getsigmask ()
|
||||
{
|
||||
#ifdef _MT_SAFE
|
||||
if ( thread2signal )
|
||||
|
@ -148,7 +125,7 @@ pinfo::getsigmask ()
|
|||
};
|
||||
|
||||
void
|
||||
pinfo::setsigmask (sigset_t _mask)
|
||||
_pinfo::setsigmask (sigset_t _mask)
|
||||
{
|
||||
#ifdef _MT_SAFE
|
||||
if ( thread2signal )
|
||||
|
@ -160,7 +137,7 @@ pinfo::setsigmask (sigset_t _mask)
|
|||
}
|
||||
|
||||
LONG *
|
||||
pinfo::getsigtodo(int sig)
|
||||
_pinfo::getsigtodo(int sig)
|
||||
{
|
||||
#ifdef _MT_SAFE
|
||||
if ( thread2signal )
|
||||
|
@ -174,7 +151,7 @@ pinfo::getsigtodo(int sig)
|
|||
extern HANDLE hMainThread;
|
||||
|
||||
HANDLE
|
||||
pinfo::getthread2signal()
|
||||
_pinfo::getthread2signal()
|
||||
{
|
||||
#ifdef _MT_SAFE
|
||||
if ( thread2signal )
|
||||
|
@ -186,7 +163,7 @@ pinfo::getthread2signal()
|
|||
}
|
||||
|
||||
void
|
||||
pinfo::setthread2signal(void *_thr)
|
||||
_pinfo::setthread2signal(void *_thr)
|
||||
{
|
||||
#ifdef _MT_SAFE
|
||||
// assert has myself lock
|
||||
|
@ -196,190 +173,87 @@ pinfo::setthread2signal(void *_thr)
|
|||
}
|
||||
|
||||
void
|
||||
pinfo::copysigs(pinfo *_other)
|
||||
_pinfo::copysigs(_pinfo *_other)
|
||||
{
|
||||
sigs = _other->sigs;
|
||||
}
|
||||
|
||||
pinfo * __stdcall
|
||||
procinfo (int pid)
|
||||
{
|
||||
return cygwin_shared->p[pid];
|
||||
}
|
||||
|
||||
#ifdef DEBUGGING
|
||||
/*
|
||||
* Code to lock/unlock the process table.
|
||||
*/
|
||||
|
||||
int __stdcall
|
||||
lpfu (const char *func, int ln, DWORD timeout)
|
||||
{
|
||||
int rc;
|
||||
DWORD t;
|
||||
|
||||
debug_printf ("timeout %d, pinfo_mutex %p", timeout, pinfo_mutex);
|
||||
t = (timeout == INFINITE) ? 10000 : timeout;
|
||||
SetLastError(0);
|
||||
while ((rc = WaitForSingleObject (pinfo_mutex, t)) != WAIT_OBJECT_0)
|
||||
{
|
||||
if (rc == WAIT_ABANDONED_0)
|
||||
break;
|
||||
system_printf ("%s:%d having problems getting lock", func, ln);
|
||||
system_printf ("*** %s, rc %d, %E", cygwin_shared->p.lock_info, rc);
|
||||
if (t == timeout)
|
||||
break;
|
||||
}
|
||||
|
||||
__small_sprintf (cygwin_shared->p.lock_info, "%s(%d), pid %d ", func, ln,
|
||||
(user_data && myself) ? (int)myself->dwProcessId : -1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
unlock_pinfo (void)
|
||||
_pinfo::record_death ()
|
||||
{
|
||||
|
||||
debug_printf ("handle %d", pinfo_mutex);
|
||||
|
||||
if (!cygwin_shared->p.lock_info[0])
|
||||
system_printf ("lock_info not set?");
|
||||
else
|
||||
strcat (cygwin_shared->p.lock_info, " unlocked");
|
||||
if (!ReleaseMutex (pinfo_mutex))
|
||||
system_printf ("ReleaseMutext (pinfo_mutex<%p>) failed, %E", pinfo_mutex);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Code to lock/unlock the process table.
|
||||
*/
|
||||
|
||||
int __stdcall
|
||||
lock_pinfo_for_update (DWORD timeout)
|
||||
{
|
||||
DWORD rc;
|
||||
DWORD t;
|
||||
|
||||
debug_printf ("timeout %d, pinfo_mutex %p", timeout, pinfo_mutex);
|
||||
t = (timeout == INFINITE) ? 10000 : timeout;
|
||||
SetLastError(0);
|
||||
while ((rc = WaitForSingleObject (pinfo_mutex, t)) != WAIT_OBJECT_0)
|
||||
{
|
||||
if (rc == WAIT_ABANDONED_0)
|
||||
break;
|
||||
system_printf ("rc %d, pinfo_mutex %p, %E", pinfo_mutex, rc);
|
||||
if (t == timeout)
|
||||
break;
|
||||
if (rc == WAIT_FAILED)
|
||||
/* sigh, must be properly fixed up later. */
|
||||
return rc;
|
||||
Sleep(10); /* to prevent 100% CPU in those rare cases */
|
||||
}
|
||||
|
||||
return (int)rc;
|
||||
}
|
||||
|
||||
void
|
||||
unlock_pinfo (void)
|
||||
{
|
||||
|
||||
debug_printf ("handle %d", pinfo_mutex);
|
||||
|
||||
ReleaseMutex (pinfo_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Allocate a process table entry by finding an empty slot in the
|
||||
fixed-size process table. We could use a linked list, but this
|
||||
would probably be too slow.
|
||||
|
||||
Try to allocate next_pid, incrementing next_pid and trying again
|
||||
up to size() times at which point we reach the conclusion that
|
||||
table is full. Eventually at this point we would grow the table
|
||||
by size() and start over. If we find a pid to use,
|
||||
|
||||
If all else fails, sweep through the loop looking for processes that
|
||||
may have died abnormally without registering themselves as "dead".
|
||||
Clear out these pinfo structures. Then scan the table again.
|
||||
|
||||
Note that the process table is in the shared data space and thus
|
||||
is susceptible to corruption. The amount of time spent scanning the
|
||||
table is presumably quite small compared with the total time to
|
||||
create a process.
|
||||
*/
|
||||
|
||||
pinfo *
|
||||
pinfo_list::allocate_pid (void)
|
||||
{
|
||||
|
||||
pinfo *newp;
|
||||
|
||||
lock_pinfo_for_update (INFINITE);
|
||||
for (int tries = 0; ; tries++)
|
||||
{
|
||||
for (int i = next_pid; i < (next_pid + size ()); i++)
|
||||
{
|
||||
/* i mod size() gives place to check */
|
||||
newp = vec + (i % size());
|
||||
if (newp->process_state == PID_NOT_IN_USE)
|
||||
{
|
||||
debug_printf ("found empty slot %d for pid %d",
|
||||
(i % size ()), i);
|
||||
next_pid = i;
|
||||
goto gotit;
|
||||
}
|
||||
}
|
||||
|
||||
if (tries > 0)
|
||||
break;
|
||||
|
||||
/* try once to remove bogus dead processes */
|
||||
debug_printf ("clearing out deadwood");
|
||||
for (newp = vec; newp < vec + size(); newp++)
|
||||
proc_exists (newp);
|
||||
}
|
||||
|
||||
/* The process table is full. */
|
||||
debug_printf ("process table is full");
|
||||
unlock_pinfo ();
|
||||
|
||||
return NULL;
|
||||
|
||||
gotit:
|
||||
|
||||
/* Set new pid based on the position of this element in the pinfo list */
|
||||
newp->pid = next_pid;
|
||||
|
||||
/* Determine next slot to consider, wrapping if we hit the end of
|
||||
* the array. Since allocation involves looping through size () pids,
|
||||
* don't allow next_pid to be greater than SHRT_MAX - size ().
|
||||
*/
|
||||
if (next_pid < (SHRT_MAX - size ()))
|
||||
next_pid++;
|
||||
else
|
||||
next_pid = PBASE;
|
||||
|
||||
newp->process_state = PID_IN_USE;
|
||||
unlock_pinfo ();
|
||||
|
||||
memset (newp, 0, PINFO_ZERO);
|
||||
debug_printf ("pid %d, state %x", newp->pid, newp->process_state);
|
||||
return newp;
|
||||
}
|
||||
|
||||
void
|
||||
pinfo::record_death (int lock)
|
||||
{
|
||||
int unlock = lock ? 0 : lock_pinfo_for_update (999);
|
||||
/* CGF FIXME - needed? */
|
||||
if (dwProcessId == GetCurrentProcessId () && !my_parent_is_alive ())
|
||||
{
|
||||
process_state = PID_NOT_IN_USE;
|
||||
hProcess = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlock)
|
||||
unlock_pinfo ();
|
||||
void
|
||||
pinfo::init (pid_t n, DWORD create)
|
||||
{
|
||||
if (n == myself->pid)
|
||||
{
|
||||
child = myself;
|
||||
destroy = 0;
|
||||
h = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
int created;
|
||||
char mapname[MAX_PATH];
|
||||
__small_sprintf (mapname, "cygpid.%x", n);
|
||||
|
||||
int mapsize;
|
||||
if (create & PID_EXECED)
|
||||
mapsize = PINFO_REDIR_SIZE;
|
||||
else
|
||||
mapsize = sizeof (_pinfo);
|
||||
|
||||
if (!create)
|
||||
{
|
||||
/* CGF FIXME -- deal with inheritance after an exec */
|
||||
h = OpenFileMappingA (FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapname);
|
||||
created = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = CreateFileMapping ((HANDLE) 0xffffffff, &sec_none_nih,
|
||||
PAGE_READWRITE, 0, mapsize, mapname);
|
||||
created = h && GetLastError () != ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
if (!h)
|
||||
{
|
||||
if (create)
|
||||
__seterrno ();
|
||||
child = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
child = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
|
||||
if (child->process_state & PID_EXECED)
|
||||
{
|
||||
pid_t realpid = child->pid;
|
||||
release ();
|
||||
if (realpid == n)
|
||||
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
|
||||
return init (realpid);
|
||||
}
|
||||
|
||||
if (created)
|
||||
{
|
||||
if (!(create & PID_EXECED))
|
||||
child->pid = n;
|
||||
else
|
||||
{
|
||||
child->pid = myself->pid;
|
||||
child->process_state |= PID_IN_USE | PID_EXECED;
|
||||
}
|
||||
}
|
||||
|
||||
destroy = 1;
|
||||
}
|
||||
|
||||
/* DOCTOOL-START
|
||||
|
@ -412,18 +286,92 @@ a cygwin pid.</para>
|
|||
extern "C" pid_t
|
||||
cygwin_winpid_to_pid (int winpid)
|
||||
{
|
||||
for (int i = 0; i < cygwin_shared->p.size (); i++)
|
||||
{
|
||||
pinfo *p = &cygwin_shared->p.vec[i];
|
||||
|
||||
if (p->process_state == PID_NOT_IN_USE)
|
||||
continue;
|
||||
|
||||
/* FIXME: signed vs unsigned comparison: winpid can be < 0 !!! */
|
||||
if (p->dwProcessId == (DWORD)winpid)
|
||||
return p->pid;
|
||||
}
|
||||
pinfo p (winpid);
|
||||
if (p)
|
||||
return p->pid;
|
||||
|
||||
set_errno (ESRCH);
|
||||
return (pid_t) -1;
|
||||
}
|
||||
|
||||
#include <tlhelp32.h>
|
||||
#include <psapi.h>
|
||||
|
||||
typedef BOOL (WINAPI * ENUMPROCESSES) (DWORD *, DWORD, DWORD *);
|
||||
typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD, DWORD);
|
||||
typedef BOOL (WINAPI * PROCESSWALK) (HANDLE, LPPROCESSENTRY32);
|
||||
typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE);
|
||||
|
||||
static NO_COPY CREATESNAPSHOT myCreateToolhelp32Snapshot = NULL;
|
||||
static NO_COPY PROCESSWALK myProcess32First = NULL;
|
||||
static NO_COPY PROCESSWALK myProcess32Next = NULL;
|
||||
static BOOL WINAPI enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded);
|
||||
|
||||
static NO_COPY ENUMPROCESSES myEnumProcesses = enum_init;
|
||||
|
||||
static BOOL WINAPI
|
||||
EnumProcessesW95 (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
*cbneeded = 0;
|
||||
h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
|
||||
if (!h)
|
||||
return 0;
|
||||
|
||||
PROCESSENTRY32 proc;
|
||||
int i = 0;
|
||||
proc.dwSize = sizeof (proc);
|
||||
if (myProcess32First(h, &proc))
|
||||
do
|
||||
lpidProcess[i++] = cygwin_pid (proc.th32ProcessID);
|
||||
while (myProcess32Next (h, &proc));
|
||||
CloseHandle (h);
|
||||
if (i == 0)
|
||||
return 0;
|
||||
*cbneeded = i * sizeof (DWORD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
winpids::init ()
|
||||
{
|
||||
DWORD n;
|
||||
if (!myEnumProcesses (pidlist, sizeof (pidlist) / sizeof (pidlist[0]), &n))
|
||||
npids = 0;
|
||||
else
|
||||
npids = n / sizeof (pidlist[0]);
|
||||
|
||||
pidlist[npids] = 0;
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
|
||||
{
|
||||
HINSTANCE h;
|
||||
if (os_being_run == winNT)
|
||||
{
|
||||
h = LoadLibrary ("psapi.dll");
|
||||
if (!h)
|
||||
return 0;
|
||||
myEnumProcesses = (ENUMPROCESSES) GetProcAddress (h, "EnumProcesses");
|
||||
if (!myEnumProcesses)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = GetModuleHandle("kernel32.dll");
|
||||
myCreateToolhelp32Snapshot = (CREATESNAPSHOT)
|
||||
GetProcAddress(h, "CreateToolhelp32Snapshot");
|
||||
myProcess32First = (PROCESSWALK)
|
||||
GetProcAddress(h, "Process32First");
|
||||
myProcess32Next = (PROCESSWALK)
|
||||
GetProcAddress(h, "Process32Next");
|
||||
if (!myCreateToolhelp32Snapshot || !myProcess32First || !myProcess32Next)
|
||||
return 0;
|
||||
|
||||
myEnumProcesses = EnumProcessesW95;
|
||||
}
|
||||
|
||||
return myEnumProcesses (lpidProcess, cb, cbneeded);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/******** Process Table ********/
|
||||
|
||||
/* Signal constants (have to define them here, unfortunately) */
|
||||
|
||||
enum
|
||||
{
|
||||
__SIGFLUSH = -2,
|
||||
__SIGSTRACE = -1,
|
||||
__SIGCHILDSTOPPED = 0,
|
||||
__SIGOFFSET = 3
|
||||
};
|
||||
|
||||
#define PSIZE 1024
|
||||
class _pinfo
|
||||
{
|
||||
public:
|
||||
/* Cygwin pid */
|
||||
pid_t pid;
|
||||
|
||||
/* Various flags indicating the state of the process. See PID_
|
||||
constants below. */
|
||||
DWORD process_state;
|
||||
|
||||
/* If hProcess is set, it's because it came from a
|
||||
CreateProcess call. This means it's process relative
|
||||
to the thing which created the process. That's ok because
|
||||
we only use this handle from the parent. */
|
||||
HANDLE hProcess;
|
||||
|
||||
#define PINFO_REDIR_SIZE ((DWORD) &(((_pinfo *)NULL)->hProcess) + sizeof (DWORD))
|
||||
|
||||
/* Parent process id. */
|
||||
pid_t ppid;
|
||||
|
||||
/* dwProcessId contains the processid used for sending signals. It
|
||||
* will be reset in a child process when it is capable of receiving
|
||||
* signals.
|
||||
*/
|
||||
DWORD dwProcessId;
|
||||
|
||||
/* Used to spawn a child for fork(), among other things. */
|
||||
char progname[MAX_PATH];
|
||||
|
||||
HANDLE parent_alive;
|
||||
|
||||
/* User information.
|
||||
The information is derived from the GetUserName system call,
|
||||
with the name looked up in /etc/passwd and assigned a default value
|
||||
if not found. This data resides in the shared data area (allowing
|
||||
tasks to store whatever they want here) so it's for informational
|
||||
purposes only. */
|
||||
uid_t uid; /* User ID */
|
||||
gid_t gid; /* Group ID */
|
||||
pid_t pgid; /* Process group ID */
|
||||
pid_t sid; /* Session ID */
|
||||
int ctty; /* Control tty */
|
||||
mode_t umask;
|
||||
char username[MAX_USER_NAME]; /* user's name */
|
||||
|
||||
/* Extendend user information.
|
||||
The information is derived from the internal_getlogin call
|
||||
when on a NT system. */
|
||||
PSID psid; /* user's SID */
|
||||
char sidbuf[MAX_SID_LEN]; /* buffer for user's SID */
|
||||
char logsrv[MAX_HOST_NAME]; /* Logon server, may be FQDN */
|
||||
char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
|
||||
|
||||
/* token is needed if sexec should be called. It can be set by a call
|
||||
to `set_impersonation_token()'. */
|
||||
HANDLE token;
|
||||
BOOL impersonated;
|
||||
uid_t orig_uid; /* Remains intact also after impersonation */
|
||||
uid_t orig_gid; /* Ditto */
|
||||
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
|
||||
gid_t real_gid; /* Ditto */
|
||||
|
||||
/* Filled when chroot() is called by the process or one of it's parents.
|
||||
Saved without trailing backslash. */
|
||||
char root[MAX_PATH+1];
|
||||
size_t rootlen;
|
||||
|
||||
/* Non-zero if process was stopped by a signal. */
|
||||
char stopsig;
|
||||
|
||||
struct sigaction& getsig (int);
|
||||
void copysigs (_pinfo* );
|
||||
sigset_t& getsigmask ();
|
||||
void setsigmask (sigset_t);
|
||||
LONG* getsigtodo (int);
|
||||
HANDLE getthread2signal ();
|
||||
void setthread2signal (void *);
|
||||
|
||||
/* Resources used by process. */
|
||||
long start_time;
|
||||
struct rusage rusage_self;
|
||||
struct rusage rusage_children;
|
||||
|
||||
private:
|
||||
struct sigaction sigs[NSIG];
|
||||
sigset_t sig_mask; /* one set for everything to ignore. */
|
||||
LONG _sigtodo[NSIG + __SIGOFFSET];
|
||||
ThreadItem* thread2signal; // NULL means means thread any other means a pthread
|
||||
|
||||
public:
|
||||
/* Pointer to mmap'ed areas for this process. Set up by fork. */
|
||||
void *mmap_ptr;
|
||||
|
||||
void record_death ();
|
||||
};
|
||||
|
||||
class pinfo
|
||||
{
|
||||
HANDLE h;
|
||||
_pinfo *child;
|
||||
int destroy;
|
||||
public:
|
||||
void init (pid_t n, DWORD create = 0);
|
||||
pinfo () {}
|
||||
pinfo (_pinfo *x): child (x) {}
|
||||
pinfo (pid_t n) {init (n);}
|
||||
pinfo (pid_t n, int create) {init (n, create);}
|
||||
void release ()
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
UnmapViewOfFile (child);
|
||||
CloseHandle (h);
|
||||
h = NULL;
|
||||
}
|
||||
}
|
||||
~pinfo ()
|
||||
{
|
||||
if (destroy && child)
|
||||
release ();
|
||||
}
|
||||
|
||||
_pinfo *operator -> () const {return child;}
|
||||
int operator == (pinfo *x) const {return x->child == child;}
|
||||
int operator == (pinfo &x) const {return x.child == child;}
|
||||
int operator == (void *x) const {return child == x;}
|
||||
int operator == (int x) const {return (int) child == (int) x;}
|
||||
int operator == (char *x) const {return (char *) child == x;}
|
||||
_pinfo *operator * () const {return child;}
|
||||
operator _pinfo * () const {return child;}
|
||||
void remember () {destroy = 0; proc_subproc (PROC_ADDCHILD, (DWORD) this);}
|
||||
};
|
||||
|
||||
#define ISSTATE(p, f) (!!((p)->process_state & f))
|
||||
#define NOTSTATE(p, f) (!((p)->process_state & f))
|
||||
|
||||
class winpids
|
||||
{
|
||||
DWORD pidlist[16384];
|
||||
public:
|
||||
DWORD npids;
|
||||
void reset () { npids = 0; }
|
||||
winpids (int) { reset (); }
|
||||
winpids () { init (); };
|
||||
void init ();
|
||||
int operator [] (int i) const {return pidlist[i];}
|
||||
};
|
||||
|
||||
extern __inline pid_t
|
||||
cygwin_pid (pid_t pid)
|
||||
{
|
||||
return (pid_t) (os_being_run == winNT) ? pid : -(int) pid;
|
||||
}
|
||||
void __stdcall pinfo_init (PBYTE);
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "winsup.h"
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@ details. */
|
|||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "winsup.h"
|
||||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "winsup.h"
|
||||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
#include <winsock.h>
|
||||
#include "select.h"
|
||||
|
||||
|
|
|
@ -119,9 +119,6 @@ shared_info::initialize ()
|
|||
/* Initialize the mount table. */
|
||||
mount.init ();
|
||||
|
||||
/* Initialize the process table. */
|
||||
p.init ();
|
||||
|
||||
/* Initialize the queue of deleted files. */
|
||||
delqueue.init ();
|
||||
|
||||
|
|
|
@ -41,140 +41,6 @@ public:
|
|||
void process_queue ();
|
||||
};
|
||||
|
||||
/******** Process Table ********/
|
||||
|
||||
/* Signal constants (have to define them here, unfortunately) */
|
||||
|
||||
enum
|
||||
{
|
||||
__SIGFLUSH = -2,
|
||||
__SIGSTRACE = -1,
|
||||
__SIGCHILDSTOPPED = 0,
|
||||
__SIGOFFSET = 3
|
||||
};
|
||||
|
||||
class pinfo
|
||||
{
|
||||
public:
|
||||
|
||||
/* If hProcess is set, it's because it came from a
|
||||
CreateProcess call. This means it's process relative
|
||||
to the thing which created the process. That's ok because
|
||||
we only use this handle from the parent. */
|
||||
HANDLE hProcess;
|
||||
|
||||
HANDLE parent_alive;
|
||||
|
||||
/* dwProcessId contains the processid used for sending signals. It
|
||||
* will be reset in a child process when it is capable of receiving
|
||||
* signals.
|
||||
*/
|
||||
DWORD dwProcessId;
|
||||
|
||||
/* User information.
|
||||
The information is derived from the GetUserName system call,
|
||||
with the name looked up in /etc/passwd and assigned a default value
|
||||
if not found. This data resides in the shared data area (allowing
|
||||
tasks to store whatever they want here) so it's for informational
|
||||
purposes only. */
|
||||
uid_t uid; /* User ID */
|
||||
gid_t gid; /* Group ID */
|
||||
pid_t pgid; /* Process group ID */
|
||||
pid_t sid; /* Session ID */
|
||||
int ctty; /* Control tty */
|
||||
mode_t umask;
|
||||
char username[MAX_USER_NAME]; /* user's name */
|
||||
|
||||
/* Extendend user information.
|
||||
The information is derived from the internal_getlogin call
|
||||
when on a NT system. */
|
||||
PSID psid; /* user's SID */
|
||||
char sidbuf[MAX_SID_LEN]; /* buffer for user's SID */
|
||||
char logsrv[MAX_HOST_NAME]; /* Logon server, may be FQDN */
|
||||
char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
|
||||
|
||||
/* token is needed if sexec should be called. It can be set by a call
|
||||
to `set_impersonation_token()'. */
|
||||
HANDLE token;
|
||||
BOOL impersonated;
|
||||
uid_t orig_uid; /* Remains intact also after impersonation */
|
||||
uid_t orig_gid; /* Ditto */
|
||||
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
|
||||
gid_t real_gid; /* Ditto */
|
||||
|
||||
/* Filled when chroot() is called by the process or one of it's parents.
|
||||
Saved without trailing backslash. */
|
||||
char root[MAX_PATH+1];
|
||||
size_t rootlen;
|
||||
|
||||
/* Non-zero if process was stopped by a signal. */
|
||||
char stopsig;
|
||||
|
||||
struct sigaction& getsig (int);
|
||||
void copysigs (pinfo *);
|
||||
sigset_t& getsigmask ();
|
||||
void setsigmask (sigset_t);
|
||||
LONG* getsigtodo (int);
|
||||
HANDLE getthread2signal ();
|
||||
void setthread2signal (void *);
|
||||
|
||||
/* Resources used by process. */
|
||||
long start_time;
|
||||
struct rusage rusage_self;
|
||||
struct rusage rusage_children;
|
||||
|
||||
private:
|
||||
struct sigaction sigs[NSIG];
|
||||
sigset_t sig_mask; /* one set for everything to ignore. */
|
||||
LONG _sigtodo[NSIG + __SIGOFFSET];
|
||||
#ifdef _MT_SAFE
|
||||
ThreadItem* thread2signal; // NULL means means thread any other means a pthread
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/* Pointer to mmap'ed areas for this process. Set up by fork. */
|
||||
void *mmap_ptr;
|
||||
|
||||
/* Used to spawn a child for fork(), among other things. */
|
||||
char progname[MAX_PATH];
|
||||
|
||||
#define PINFO_ZERO ((((pinfo *) NULL)->progname + 1) - ((char *) NULL))
|
||||
|
||||
/* Anything below this point is not zeroed automatically by allocate_pid */
|
||||
|
||||
/* The pid stays the same, while the hProcess moves due to execs. */
|
||||
pid_t pid;
|
||||
/* Parent process id. */
|
||||
pid_t ppid;
|
||||
|
||||
/* Various flags indicating the state of the process. See PID_
|
||||
constants below. */
|
||||
DWORD process_state;
|
||||
|
||||
void record_death (int lock = 1);
|
||||
};
|
||||
|
||||
#define ISSTATE(p, f) (!!((p)->process_state & f))
|
||||
#define NOTSTATE(p, f) (!((p)->process_state & f))
|
||||
|
||||
#define PSIZE 128
|
||||
|
||||
class pinfo_list
|
||||
{
|
||||
public:
|
||||
int next_pid;
|
||||
pinfo vec[PSIZE];
|
||||
char lock_info[MAX_PATH + 1];
|
||||
pinfo * operator[] (pid_t x);
|
||||
int size (void) { return PSIZE; }
|
||||
pinfo *allocate_pid (void);
|
||||
void init (void);
|
||||
};
|
||||
|
||||
void __stdcall pinfo_init (PBYTE);
|
||||
pinfo *__stdcall procinfo (int n);
|
||||
|
||||
enum
|
||||
{
|
||||
PROC_MAGIC = 0xaf08f000,
|
||||
|
@ -221,7 +87,7 @@ void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
|
|||
extern child_info_fork *child_proc_info;
|
||||
|
||||
/* Process info for this process */
|
||||
extern pinfo *myself;
|
||||
extern pinfo myself;
|
||||
|
||||
/* non-NULL if this process is a child of a cygwin process */
|
||||
extern HANDLE parent_alive;
|
||||
|
@ -499,8 +365,6 @@ class shared_info
|
|||
DWORD inited;
|
||||
|
||||
public:
|
||||
pinfo_list p;
|
||||
|
||||
/* FIXME: Doesn't work if more than one user on system. */
|
||||
mount_info mount;
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ static int
|
|||
kill_worker (pid_t pid, int sig)
|
||||
{
|
||||
int res = 0;
|
||||
pinfo *dest = procinfo (pid);
|
||||
pinfo dest (pid);
|
||||
BOOL sendSIGCONT;
|
||||
|
||||
if (!dest)
|
||||
|
@ -171,9 +171,10 @@ kill_pgrp (pid_t pid, int sig)
|
|||
|
||||
sigproc_printf ("pid %d, sig %d", pid, sig);
|
||||
|
||||
for (int i = 0; i < cygwin_shared->p.size (); i++)
|
||||
winpids pids;
|
||||
for (unsigned i = 0; i < pids.npids; i++)
|
||||
{
|
||||
pinfo *p = &cygwin_shared->p.vec[i];
|
||||
pinfo p = pids[i];
|
||||
|
||||
if (!proc_exists (p))
|
||||
continue;
|
||||
|
|
|
@ -90,8 +90,8 @@ Static HANDLE wait_sig_inited = NULL; // Control synchronization of
|
|||
*/
|
||||
Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
|
||||
#define hchildren (events + 1) // Where the children handles begin
|
||||
Static pinfo *pchildren[PSIZE] = {NULL};// All my children info
|
||||
Static pinfo *zombies[PSIZE] = {NULL}; // All my deceased children info
|
||||
Static pinfo pchildren[PSIZE] = {pinfo ()};// All my children info
|
||||
Static pinfo zombies[PSIZE] = {pinfo ()}; // All my deceased children info
|
||||
Static int nchildren = 0; // Number of active children
|
||||
Static int nzombies = 0; // Number of deceased children
|
||||
|
||||
|
@ -108,11 +108,11 @@ int NO_COPY pending_signals = 0; // TRUE if signals pending
|
|||
*/
|
||||
static int __stdcall checkstate (waitq *);
|
||||
static __inline__ BOOL get_proc_lock (DWORD, DWORD);
|
||||
static HANDLE __stdcall getsem (pinfo *, const char *, int, int);
|
||||
static HANDLE __stdcall getsem (_pinfo *, const char *, int, int);
|
||||
static void __stdcall remove_child (int);
|
||||
static void __stdcall remove_zombie (int);
|
||||
static DWORD WINAPI wait_sig (VOID *arg);
|
||||
static int __stdcall stopped_or_terminated (waitq *, pinfo *);
|
||||
static int __stdcall stopped_or_terminated (waitq *, _pinfo *);
|
||||
static DWORD WINAPI wait_subproc (VOID *);
|
||||
|
||||
/* Determine if the parent process is alive.
|
||||
|
@ -168,7 +168,7 @@ wait_for_me ()
|
|||
}
|
||||
|
||||
static BOOL __stdcall
|
||||
proc_can_be_signalled (pinfo *p)
|
||||
proc_can_be_signalled (_pinfo *p)
|
||||
{
|
||||
if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
|
||||
{
|
||||
|
@ -181,11 +181,18 @@ proc_can_be_signalled (pinfo *p)
|
|||
(PID_ACTIVE | PID_IN_USE));
|
||||
}
|
||||
|
||||
BOOL __stdcall
|
||||
proc_exists (pid_t pid)
|
||||
{
|
||||
pinfo p (pid);
|
||||
return proc_exists (p);
|
||||
}
|
||||
|
||||
/* Test to determine if a process really exists and is processing
|
||||
* signals.
|
||||
*/
|
||||
BOOL __stdcall
|
||||
proc_exists (pinfo *p)
|
||||
proc_exists (_pinfo *p)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
|
@ -225,7 +232,7 @@ proc_exists (pinfo *p)
|
|||
/* If the parent pid does not exist, clean this process out of the pinfo
|
||||
* table. It must have died abnormally.
|
||||
*/
|
||||
if ((p->pid == p->ppid) || (p->ppid == 1) || !proc_exists (procinfo (p->ppid)))
|
||||
if ((p->pid == p->ppid) || (p->ppid == 1) || !proc_exists (p->ppid))
|
||||
{
|
||||
p->hProcess = NULL;
|
||||
p->process_state = PID_NOT_IN_USE;
|
||||
|
@ -235,14 +242,14 @@ proc_exists (pinfo *p)
|
|||
|
||||
/* Handle all subprocess requests
|
||||
*/
|
||||
#define vchild ((pinfo *) val)
|
||||
#define vchild (*((pinfo *) val))
|
||||
int __stdcall
|
||||
proc_subproc (DWORD what, DWORD val)
|
||||
{
|
||||
int rc = 1;
|
||||
int potential_match;
|
||||
DWORD exitcode;
|
||||
pinfo *child;
|
||||
_pinfo *child;
|
||||
int clearing;
|
||||
waitq *w;
|
||||
|
||||
|
@ -292,23 +299,22 @@ proc_subproc (DWORD what, DWORD val)
|
|||
*/
|
||||
case PROC_CHILDTERMINATED:
|
||||
rc = 0;
|
||||
child = pchildren[val];
|
||||
if (GetExitCodeProcess (hchildren[val], &exitcode) &&
|
||||
hchildren[val] != child->hProcess)
|
||||
hchildren[val] != pchildren[val]->hProcess)
|
||||
{
|
||||
sip_printf ("pid %d[%d], reparented old hProcess %p, new %p",
|
||||
child->pid, val, hchildren[val], child->hProcess);
|
||||
pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
|
||||
ForceCloseHandle1 (hchildren[val], childhProc);
|
||||
hchildren[val] = child->hProcess; /* Filled out by child */
|
||||
ProtectHandle1 (child->hProcess, childhProc);
|
||||
hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */
|
||||
ProtectHandle1 (pchildren[val]->hProcess, childhProc);
|
||||
break; // This was an exec()
|
||||
}
|
||||
|
||||
sip_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
|
||||
child->pid, val, hchildren[val], nchildren, nzombies);
|
||||
remove_child (val); // Remove from children arrays
|
||||
zombies[nzombies++] = child; // Add to zombie array
|
||||
child->process_state = PID_ZOMBIE;// Walking dead
|
||||
pchildren[val]->pid, val, hchildren[val], nchildren, nzombies);
|
||||
zombies[nzombies] = pchildren[val]; // Add to zombie array
|
||||
zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
|
||||
remove_child (val); // Remove from children array
|
||||
if (!proc_loop_wait) // Don't bother if wait_subproc is
|
||||
break; // exiting
|
||||
|
||||
|
@ -381,7 +387,7 @@ proc_subproc (DWORD what, DWORD val)
|
|||
|
||||
if (wval->pid <= 0)
|
||||
child = NULL; // Not looking for a specific pid
|
||||
else if ((child = procinfo (wval->pid)) == NULL)
|
||||
else if (!proc_exists (wval->pid)) /* CGF FIXME -- test that this is one of mine */
|
||||
goto out; // invalid pid. flag no such child
|
||||
|
||||
wval->status = 0; // Don't know status yet
|
||||
|
@ -480,50 +486,49 @@ proc_terminate (void)
|
|||
sync_proc_subproc->acquire(WPSP);
|
||||
(void) proc_subproc (PROC_CLEARWAIT, 1);
|
||||
|
||||
lock_pinfo_for_update (INFINITE);
|
||||
/* Clean out zombie processes from the pid list. */
|
||||
int i;
|
||||
for (i = 0; i < nzombies; i++)
|
||||
{
|
||||
pinfo *child;
|
||||
if ((child = zombies[i])->hProcess)
|
||||
if (zombies[i]->hProcess)
|
||||
{
|
||||
ForceCloseHandle1 (child->hProcess, childhProc);
|
||||
child->hProcess = NULL;
|
||||
ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
|
||||
zombies[i]->hProcess = NULL;
|
||||
}
|
||||
child->process_state = PID_NOT_IN_USE;
|
||||
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
|
||||
zombies[i].release();
|
||||
}
|
||||
|
||||
/* Disassociate my subprocesses */
|
||||
for (i = 0; i < nchildren; i++)
|
||||
{
|
||||
pinfo *child;
|
||||
if ((child = pchildren[i])->process_state == PID_NOT_IN_USE)
|
||||
pinfo child; /* CGF FIXME */
|
||||
if (pchildren[i]->process_state == PID_NOT_IN_USE)
|
||||
continue; // Should never happen
|
||||
if (!child->hProcess)
|
||||
sip_printf ("%d(%d) hProcess cleared already?", child->pid,
|
||||
child->dwProcessId);
|
||||
if (!pchildren[i]->hProcess)
|
||||
sip_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid,
|
||||
pchildren[i]->dwProcessId);
|
||||
else
|
||||
{
|
||||
ForceCloseHandle1 (child->hProcess, childhProc);
|
||||
child->hProcess = NULL;
|
||||
if (!proc_exists (child))
|
||||
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
|
||||
pchildren[i]->hProcess = NULL;
|
||||
if (!proc_exists (pchildren[i]))
|
||||
{
|
||||
sip_printf ("%d(%d) doesn't exist", child->pid,
|
||||
child->dwProcessId);
|
||||
child->process_state = PID_NOT_IN_USE; /* a reaped child */
|
||||
sip_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
|
||||
pchildren[i]->dwProcessId);
|
||||
pchildren[i]->process_state = PID_NOT_IN_USE; /* a reaped child CGF FIXME -- still needed? */
|
||||
}
|
||||
else
|
||||
{
|
||||
sip_printf ("%d(%d) closing active child handle", child->pid,
|
||||
child->dwProcessId);
|
||||
child->ppid = 1;
|
||||
if (child->pgid == myself->pid)
|
||||
child->process_state |= PID_ORPHANED;
|
||||
sip_printf ("%d(%d) closing active child handle", pchildren[i]->pid,
|
||||
pchildren[i]->dwProcessId);
|
||||
pchildren[i]->ppid = 1;
|
||||
if (pchildren[i]->pgid == myself->pid)
|
||||
pchildren[i]->process_state |= PID_ORPHANED;
|
||||
}
|
||||
}
|
||||
pchildren[i].release ();
|
||||
}
|
||||
unlock_pinfo ();
|
||||
nchildren = nzombies = 0;
|
||||
|
||||
/* Attempt to close and release sync_proc_subproc in a
|
||||
|
@ -706,7 +711,7 @@ sigproc_terminate (void)
|
|||
* completed before returning.
|
||||
*/
|
||||
int __stdcall
|
||||
sig_send (pinfo *p, int sig, DWORD ebp)
|
||||
sig_send (_pinfo *p, int sig, DWORD ebp)
|
||||
{
|
||||
int rc = 1;
|
||||
DWORD tid = GetCurrentThreadId ();
|
||||
|
@ -717,7 +722,7 @@ sig_send (pinfo *p, int sig, DWORD ebp)
|
|||
sigframe thisframe;
|
||||
|
||||
if (p == myself_nowait_nonmain)
|
||||
p = (tid == mainthread.id) ? myself : myself_nowait;
|
||||
p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait;
|
||||
if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
|
||||
wait_for_completion = FALSE;
|
||||
else
|
||||
|
@ -888,7 +893,7 @@ subproc_init (void)
|
|||
by fork/spawn/exec. */
|
||||
|
||||
void __stdcall
|
||||
init_child_info (DWORD chtype, child_info *ch, int pid, HANDLE subproc_ready)
|
||||
init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
|
||||
{
|
||||
subproc_init ();
|
||||
memset (ch, 0, sizeof *ch);
|
||||
|
@ -912,7 +917,7 @@ static int __stdcall
|
|||
checkstate (waitq *w)
|
||||
{
|
||||
int i, x, potential_match = 0;
|
||||
pinfo *child;
|
||||
_pinfo *child;
|
||||
|
||||
sip_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
|
||||
|
||||
|
@ -949,7 +954,7 @@ out:
|
|||
/* Get or create a process specific semaphore used in message passing.
|
||||
*/
|
||||
static HANDLE __stdcall
|
||||
getsem (pinfo *p, const char *str, int init, int max)
|
||||
getsem (_pinfo *p, const char *str, int init, int max)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
|
@ -1047,6 +1052,10 @@ remove_zombie (int ci)
|
|||
{
|
||||
sip_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
|
||||
nzombies);
|
||||
|
||||
if (zombies[ci])
|
||||
zombies[ci].release ();
|
||||
|
||||
if (ci < --nzombies)
|
||||
zombies[ci] = zombies[nzombies];
|
||||
|
||||
|
@ -1064,7 +1073,7 @@ remove_zombie (int ci)
|
|||
* 0 if child does not match parent_w->next criteria
|
||||
*/
|
||||
static int __stdcall
|
||||
stopped_or_terminated (waitq *parent_w, pinfo *child)
|
||||
stopped_or_terminated (waitq *parent_w, _pinfo *child)
|
||||
{
|
||||
int potential_match;
|
||||
waitq *w = parent_w->next;
|
||||
|
@ -1096,7 +1105,7 @@ stopped_or_terminated (waitq *parent_w, pinfo *child)
|
|||
w->status = (child->stopsig << 8) | 0x7f;
|
||||
child->stopsig = 0;
|
||||
}
|
||||
else
|
||||
else /* Should only get here when child has been moved to the zombies array */
|
||||
{
|
||||
DWORD status;
|
||||
if (!GetExitCodeProcess (child->hProcess, &status))
|
||||
|
|
|
@ -92,13 +92,17 @@ void __stdcall sig_clear (int);
|
|||
void __stdcall sig_set_pending (int);
|
||||
int __stdcall handle_sigsuspend (sigset_t);
|
||||
|
||||
int __stdcall proc_subproc (DWORD, DWORD);
|
||||
|
||||
#include "pinfo.h"
|
||||
|
||||
void __stdcall proc_terminate ();
|
||||
void __stdcall sigproc_init ();
|
||||
void __stdcall subproc_init ();
|
||||
void __stdcall sigproc_terminate ();
|
||||
BOOL __stdcall proc_exists (pinfo *);
|
||||
int __stdcall proc_subproc (DWORD, DWORD);
|
||||
int __stdcall sig_send (pinfo *, int, DWORD ebp = 0);
|
||||
BOOL __stdcall proc_exists (_pinfo *);
|
||||
BOOL __stdcall proc_exists (pid_t);
|
||||
int __stdcall sig_send (_pinfo *, int, DWORD ebp = 0);
|
||||
void __stdcall signal_fixup_after_fork ();
|
||||
|
||||
extern char myself_nowait_dummy[];
|
||||
|
@ -110,7 +114,5 @@ extern HANDLE hExeced; // Process handle of new window
|
|||
|
||||
#define allow_sig_dispatch(n) __allow_sig_dispatch (__FILE__, __LINE__, (n))
|
||||
|
||||
#define myself_nowait ((pinfo *)myself_nowait_dummy)
|
||||
#define myself_nowait_nonmain ((pinfo *)myself_nowait_nonmain_dummy)
|
||||
#define proc_register(child) \
|
||||
proc_subproc (PROC_ADDCHILD, (DWORD) (child))
|
||||
#define myself_nowait ((_pinfo *)myself_nowait_dummy)
|
||||
#define myself_nowait_nonmain ((_pinfo *)myself_nowait_nonmain_dummy)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -21,9 +21,9 @@ details. */
|
|||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include "winsup.h"
|
||||
#include <unistd.h>
|
||||
#include <winnls.h>
|
||||
#include <lmcons.h> /* for UNLEN */
|
||||
#include <unistd.h>
|
||||
|
||||
extern BOOL allow_ntsec;
|
||||
|
||||
|
@ -1413,8 +1413,7 @@ pathconf (const char *file, int v)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
char *
|
||||
extern "C" char *
|
||||
ctermid (char *str)
|
||||
{
|
||||
static NO_COPY char buf[16];
|
||||
|
@ -1714,23 +1713,25 @@ setpgid (pid_t pid, pid_t pgid)
|
|||
set_errno (EINVAL);
|
||||
goto out;
|
||||
}
|
||||
pinfo *p;
|
||||
p = procinfo (pid);
|
||||
if (p == NULL)
|
||||
{
|
||||
set_errno (ESRCH);
|
||||
goto out;
|
||||
}
|
||||
/* A process may only change the process group of itself and its children */
|
||||
if (p == myself || p->ppid == myself->pid)
|
||||
{
|
||||
p->pgid = pgid;
|
||||
res = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (EPERM);
|
||||
goto out;
|
||||
pinfo p (pid);
|
||||
if (!p)
|
||||
{
|
||||
set_errno (ESRCH);
|
||||
goto out;
|
||||
}
|
||||
/* A process may only change the process group of itself and its children */
|
||||
if (p == myself || p->ppid == myself->pid)
|
||||
{
|
||||
p->pgid = pgid;
|
||||
res = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (EPERM);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
syscall_printf ("pid %d, pgid %d, res %d", pid, pgid, res);
|
||||
|
@ -1744,7 +1745,7 @@ getpgid (pid_t pid)
|
|||
if (pid == 0)
|
||||
pid = getpid ();
|
||||
|
||||
pinfo *p = procinfo (pid);
|
||||
pinfo p (pid);
|
||||
if (p == 0)
|
||||
{
|
||||
set_errno (ESRCH);
|
||||
|
@ -1824,7 +1825,7 @@ setuid (uid_t uid)
|
|||
return ret;
|
||||
}
|
||||
|
||||
extern char *internal_getlogin (struct pinfo *pi);
|
||||
extern char *internal_getlogin (_pinfo *pi);
|
||||
|
||||
/* seteuid: standards? */
|
||||
extern "C"
|
||||
|
@ -1863,7 +1864,7 @@ seteuid (uid_t uid)
|
|||
myself->impersonated = TRUE;
|
||||
}
|
||||
|
||||
struct pinfo pi;
|
||||
struct _pinfo pi;
|
||||
pi.psid = (PSID) pi.sidbuf;
|
||||
/* pi.token is used in internal_getlogin() to determine if
|
||||
impersonation is active. If so, the token is used for
|
||||
|
|
|
@ -10,17 +10,17 @@ details. */
|
|||
|
||||
#include <pwd.h>
|
||||
#include "winsup.h"
|
||||
#include <unistd.h>
|
||||
#include <winnls.h>
|
||||
#include <utmp.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include "autoload.h"
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <lm.h>
|
||||
|
||||
char *
|
||||
internal_getlogin (struct pinfo *pi)
|
||||
internal_getlogin (_pinfo *pi)
|
||||
{
|
||||
if (! pi)
|
||||
api_fatal ("pinfo pointer is NULL!\n");
|
||||
|
|
|
@ -47,6 +47,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||
waitq *w;
|
||||
HANDLE waitfor;
|
||||
|
||||
sigproc_printf ("here");
|
||||
if (options & ~(WNOHANG | WUNTRACED))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
|
|
|
@ -178,11 +178,8 @@ class host_dependent_constants
|
|||
extern host_dependent_constants host_dependent;
|
||||
|
||||
/* Events/mutexes */
|
||||
extern HANDLE pinfo_mutex;
|
||||
extern HANDLE title_mutex;
|
||||
|
||||
|
||||
|
||||
/*************************** Per Thread ******************************/
|
||||
|
||||
#define PER_THREAD_FORK_CLEAR ((void *)0xffffffff)
|
||||
|
@ -283,7 +280,7 @@ extern unsigned int signal_shift_subtract;
|
|||
#endif
|
||||
|
||||
#define api_fatal(fmt, args...) \
|
||||
__api_fatal ("%P: *** " fmt, ## args)
|
||||
__api_fatal ("%P: *** " fmt,##args)
|
||||
|
||||
#undef issep
|
||||
#define issep(ch) (strchr (" \t\n\r", (ch)) != NULL)
|
||||
|
@ -378,13 +375,12 @@ void __stdcall mark (const char *, int);
|
|||
|
||||
extern "C" int _spawnve (HANDLE hToken, int mode, const char *path,
|
||||
const char *const *argv, const char *const *envp);
|
||||
int __stdcall spawn_guts (HANDLE hToken, const char *prog_arg,
|
||||
const char *const *argv, const char *const envp[],
|
||||
pinfo *child, int mode);
|
||||
|
||||
extern void __stdcall exec_fixup_after_fork ();
|
||||
|
||||
/* For mmaps across fork(). */
|
||||
int __stdcall recreate_mmaps_after_fork (void *);
|
||||
void __stdcall set_child_mmap_ptr (pinfo *);
|
||||
void __stdcall set_child_mmap_ptr (_pinfo *);
|
||||
|
||||
/* String manipulation */
|
||||
char *__stdcall strccpy (char *s1, const char **s2, char c);
|
||||
|
@ -401,7 +397,7 @@ long __stdcall to_time_t (FILETIME * ptr);
|
|||
int __stdcall lock_pinfo_for_update (DWORD timeout);
|
||||
#endif
|
||||
void unlock_pinfo (void);
|
||||
pinfo *__stdcall set_myself (pinfo *);
|
||||
void _stdcall set_myself (pid_t pid);
|
||||
|
||||
/* Retrieve a security descriptor that allows all access */
|
||||
SECURITY_DESCRIPTOR *__stdcall get_null_sd (void);
|
||||
|
@ -500,7 +496,7 @@ win_env * __stdcall getwinenv (const char *name, const char *posix = NULL);
|
|||
void __stdcall update_envptrs ();
|
||||
char * __stdcall winenv (const char * const *, int);
|
||||
extern char **__cygwin_environ, ***main_environ;
|
||||
extern char __stdcall **cur_environ ();
|
||||
extern "C" char __stdcall **cur_environ ();
|
||||
#define environ (cur_environ ())
|
||||
|
||||
/* The title on program start. */
|
||||
|
|
Loading…
Reference in New Issue