* 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:
Christopher Faylor 2000-07-29 16:24:59 +00:00
parent 53211514a0
commit 84c7d40932
29 changed files with 774 additions and 646 deletions

View File

@ -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.

View File

@ -8,7 +8,7 @@ __infinity
__main
__srget
__swbuf
__vc__10pinfo_listi
; __vc__10pinfo_listi
@ALLOCA@
cygwin_stackdump
abort

View File

@ -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

View File

@ -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)

View File

@ -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));

View File

@ -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;
}

View File

@ -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;

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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>

View File

@ -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;

View File

@ -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);
}

168
winsup/cygwin/pinfo.h Normal file
View File

@ -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);

View File

@ -12,7 +12,6 @@
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "winsup.h"

View File

@ -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"

View File

@ -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 ();

View File

@ -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;

View File

@ -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;

View File

@ -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))

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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");

View File

@ -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);

View File

@ -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. */