* exceptions.cc (set_console_handler): Don't allocate

console_handler_thread_waiter.  It is obsolete.
(ctrl_c_handler): Don't use console_handler_thread_waiter.
* path.cc (hash_path_name): Fix handling of relative names.  Make case
insensitive.
* path.h (suffix_info): Use initializers.
* pinfo.h (_pinfo): Avoid initializers for null case.
* resource.cc (fill_rusage): Zero rest of rusage structure.
* security.cc (set_process_privileges): Don't reopen parent process.  Just use
hMainProc.
* signal.cc (signal): Track when a signal handler has been used.
(sigaction): Ditto.
* sigproc.cc (pchildren): Use default initializer.
(zombies): Ditto.
(sigproc_terminate): Avoid closing handles that will be closed on exit anyway.
(wait_sig): Send signal to "parent" on EXECing, not FORKing.
(wait_subproc): Send SIGCHLD here rather than in proc_wait to avoid potential
muto conflicts.
* sigproc.h (sigthread): Don't initialize to zero.  It's the default.
* spawn.cc (spawn_guts): Fill in resources from exec parent prior to
termination.
* sync.h (muto): Don't initialize to zero.
* syscalls.cc (close_all_files): Use one lock around entire loop and call
fhandler close/release stuff directly.
(_read): Don't use ready_for_read if there are not signal handlers active.
* dcrt0.cc (dll_crt0_1): Fix display of "title".
(do_exit): Use pinfo exit method to exit.
(__api_fatal): Ditto.
* exceptions.cc (signal_exit): Ditto.
* fork.cc (fork_child): Remove debugging stuff.  Use pinfo_fixup_after fork in
place of exec_fixup_after_fork.
* pinfo.cc (pinfo_fixup_after_fork): New method.
(pinfo_fixup_in_spawned_child): Ditto.
(_pinfo::exit): New method.
(_pinfo::init): Remove recursion.  Detect pathological case where pinfo
structure already exists for new pid.
* pinfo.h (_pinfo): Reorganize slightly.  Add new method and new function
declarations.
* sigproc.cc (proc_exists): Previous simplification was a little to simple.
Try harder to detect if a process exists.
(proc_terminate): Use PID_EXITED setting to determine if process is still
around.
(WFSO): Remove debugging statement.
(WFMO): Ditto.
* spawn.cc (exec_fixup_after_fork): Eliminate.
(spawn_guts): Always set old_title to NULL.  Is it really needed?  Move
hexec_proc to pinfo.cc.  Call pinfo_fixup_in_spawned_child to eliminate handle
link after a spawn.
* include/sys/cygwin.h: Remove PID_NOT_IN_USE.  Add PID_EXITED.
This commit is contained in:
Christopher Faylor 2000-10-15 01:37:07 +00:00
parent fdc614360f
commit 1dc16fc74b
19 changed files with 359 additions and 277 deletions

View File

@ -1,3 +1,60 @@
Sat Oct 14 21:24:16 2000 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (set_console_handler): Don't allocate
console_handler_thread_waiter. It is obsolete.
(ctrl_c_handler): Don't use console_handler_thread_waiter.
* path.cc (hash_path_name): Fix handling of relative names. Make case
insensitive.
* path.h (suffix_info): Use initializers.
* pinfo.h (_pinfo): Avoid initializers for null case.
* resource.cc (fill_rusage): Zero rest of rusage structure.
* security.cc (set_process_privileges): Don't reopen parent process.
Just use hMainProc.
* signal.cc (signal): Track when a signal handler has been used.
(sigaction): Ditto.
* sigproc.cc (pchildren): Use default initializer.
(zombies): Ditto.
(sigproc_terminate): Avoid closing handles that will be closed on exit
anyway.
(wait_sig): Send signal to "parent" on EXECing, not FORKing.
(wait_subproc): Send SIGCHLD here rather than in proc_wait to avoid
potential muto conflicts.
* sigproc.h (sigthread): Don't initialize to zero. It's the default.
* spawn.cc (spawn_guts): Fill in resources from exec parent prior to
termination.
* sync.h (muto): Don't initialize to zero.
* syscalls.cc (close_all_files): Use one lock around entire loop and
call fhandler close/release stuff directly.
(_read): Don't use ready_for_read if there are not signal handlers
active.
Sat Oct 14 12:24:24 2000 Christopher Faylor <cgf@cygnus.com>
* dcrt0.cc (dll_crt0_1): Fix display of "title".
(do_exit): Use pinfo exit method to exit.
(__api_fatal): Ditto.
* exceptions.cc (signal_exit): Ditto.
* fork.cc (fork_child): Remove debugging stuff. Use pinfo_fixup_after
fork in place of exec_fixup_after_fork.
* pinfo.cc (pinfo_fixup_after_fork): New method.
(pinfo_fixup_in_spawned_child): Ditto.
(_pinfo::exit): New method.
(_pinfo::init): Remove recursion. Detect pathological case where pinfo
structure already exists for new pid.
* pinfo.h (_pinfo): Reorganize slightly. Add new method and new
function declarations.
* sigproc.cc (proc_exists): Previous simplification was a little to
simple. Try harder to detect if a process exists.
(proc_terminate): Use PID_EXITED setting to determine if process is
still around.
(WFSO): Remove debugging statement.
(WFMO): Ditto.
* spawn.cc (exec_fixup_after_fork): Eliminate.
(spawn_guts): Always set old_title to NULL. Is it really needed? Move
hexec_proc to pinfo.cc. Call pinfo_fixup_in_spawned_child to eliminate
handle link after a spawn.
* include/sys/cygwin.h: Remove PID_NOT_IN_USE. Add PID_EXITED.
Sat Oct 14 10:54:00 2000 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Add symbol hstrerror.

View File

@ -683,8 +683,8 @@ dll_crt0_1 ()
cygheap_fixup_in_child (spawn_info->parent, 1);
if (!spawn_info->moreinfo->myself_pinfo ||
!DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo,
hMainProc, &h, 0, 0,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
hMainProc, &h, 0, 0,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL;
set_myself (mypid, h);
__argc = spawn_info->moreinfo->argc;
@ -769,18 +769,6 @@ dll_crt0_1 ()
line = strcpy ((char *) alloca (strlen (line) + 1), line);
/* Set new console title if appropriate. */
if (display_title && !dynamically_loaded)
{
char *cp = line;
if (strip_title_path)
for (char *ptr = cp; *ptr && *ptr != ' '; ptr++)
if (isdirsep (*ptr))
cp = ptr + 1;
set_console_title (cp);
}
/* Allocate fdtab */
dtable_init ();
@ -823,6 +811,18 @@ dll_crt0_1 ()
/* Set up __progname for getopt error call. */
__progname = __argv[0];
/* Set new console title if appropriate. */
if (display_title && !dynamically_loaded)
{
char *cp = __progname;
if (strip_title_path)
for (char *ptr = cp; *ptr && *ptr != ' '; ptr++)
if (isdirsep (*ptr))
cp = ptr + 1;
set_console_title (cp);
}
cygwin_finished_initializing = 1;
/* Call init of loaded dlls. */
dlls.init ();
@ -1057,9 +1057,8 @@ do_exit (int status)
shared_terminate ();
sigproc_printf ("calling ExitProcess %d", n);
minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n);
ExitProcess (n);
myself->exit (n);
}
extern "C" void
@ -1099,7 +1098,7 @@ __api_fatal (const char *fmt, ...)
#ifdef DEBUGGING
(void) try_to_debug ();
#endif
ExitProcess (1);
myself->exit (1);
}
extern "C" {

View File

@ -16,12 +16,22 @@ details. */
#endif
extern "C" {
#ifndef DEBUGGING0
DWORD __stdcall WFSO (HANDLE, DWORD);
DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD);
#else
DWORD __stdcall WFSO (const char *fn, int ln, HANDLE, DWORD);
DWORD __stdcall WFMO (const char *fn, int ln, DWORD, CONST HANDLE *, BOOL, DWORD);
#endif
}
#ifndef DEBUGGING0
#define WaitForSingleObject WFSO
#define WaitForMultipleObject WFMO
#else
#define WaitForSingleObject(a, b) WFSO (__FUNCTION__, __LINE__, a, b)
#define WaitForMultipleObject(a, b, c, d) WFMO (__FUNCTION__, __LINE__, a, b, c, d)
#endif
#if !defined(_DEBUG_H_)
#define _DEBUG_H_

View File

@ -47,7 +47,6 @@ static NO_COPY int exit_already = 0;
static NO_COPY muto *mask_sync = NULL;
HMODULE NO_COPY cygwin_hmodule;
HANDLE NO_COPY console_handler_thread_waiter = NULL;
static const struct
{
@ -126,10 +125,6 @@ set_console_handler ()
sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor =
get_null_sd ();
/* Allocate the event needed for ctrl_c_handler synchronization with
wait_sig. */
if (!console_handler_thread_waiter)
CreateEvent (&sec_none_nih, TRUE, TRUE, NULL);
(void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE))
system_printf ("SetConsoleCtrlHandler failed, %E");
@ -825,11 +820,6 @@ ctrl_c_handler (DWORD type)
if (type == CTRL_LOGOFF_EVENT)
return TRUE;
/* Wait for sigproc_init to tell us that it's safe to send something.
This event will always be in a signalled state when wait_sig is
ready to process signals. */
(void) WaitForSingleObject (console_handler_thread_waiter, 5000);
if ((type == CTRL_CLOSE_EVENT) || (type == CTRL_SHUTDOWN_EVENT))
/* Return FALSE to prevent an "End task" dialog box from appearing
for each Cygwin process window that's open when the computer
@ -1005,7 +995,7 @@ signal_exit (int rc)
{
rc = EXIT_SIGNAL | (rc << 8);
if (exit_already++)
ExitProcess (rc);
myself->exit (rc);
/* We'd like to stop the main thread from executing but when we do that it
causes random, inexplicable hangs. So, instead, we set up the priority

View File

@ -225,8 +225,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
{
debug_printf ("child is running. pid %d, ppid %d, stack here %p",
myself->pid, myself->ppid, __builtin_frame_address (0));
child_info_fork ch;
stack_base (ch);
/* Restore the inheritance state as in parent
Don't call setuid here! The flags are already set. */
@ -240,9 +238,8 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
}
sync_with_parent ("after longjmp.", TRUE);
debug_printf ("hParent %p", hParent);
ProtectHandle (hParent);
// small_printf ("child 1 first_dll %p, load_dlls %d\n", first_dll, load_dlls);
sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d\n", hParent, first_dll, load_dlls);
#ifdef DEBUGGING
char c;
@ -270,9 +267,9 @@ debug_printf ("hParent %p", hParent);
MALLOC_CHECK;
pinfo_fixup_after_fork ();
fdtab.fixup_after_fork (hParent);
signal_fixup_after_fork ();
exec_fixup_after_fork ();
MALLOC_CHECK;

View File

@ -66,7 +66,6 @@ typedef enum
/* Flags associated with process_state */
enum
{
PID_NOT_IN_USE = 0x0000, // Free entry.
PID_IN_USE = 0x0001, // Entry in use.
PID_ZOMBIE = 0x0002, // Child exited: no parent wait.
PID_STOPPED = 0x0004, // Waiting for SIGCONT.
@ -86,7 +85,8 @@ enum
// all execed or forked processes.
PID_UNUSED2 = 0x2000, // child has execed
PID_EXECED = 0x4000, // redirect to original pid info block
PID_NOREDIR = 0x8000 // don't redirect if execed
PID_NOREDIR = 0x8000, // don't redirect if execed
PID_EXITED = 0x80000000 // Free entry.
};
#ifdef WINVER

View File

@ -2396,8 +2396,8 @@ hash_path_name (unsigned long hash, const char *name)
{
char *nn, *newname = (char *) alloca (strlen (name) + 2);
nn = strncpy (newname, name, 2);
if (islower (*nn))
*newname = toupper (*nn);
if (isupper (*nn))
*newname = tolower (*nn);
*(nn += 2) = '\0';
name += 2;
if (*name != '\\')
@ -2415,12 +2415,12 @@ hash_path_name (unsigned long hash, const char *name)
Otherwise the inodes same will differ depending on whether a file is
referenced with an absolute value or relatively. */
if (*name != '\\')
if (!hash && !isabspath (name))
{
hash = cygcwd.get_hash ();
if (name[0] == '.' && name[1] == '\0')
return hash;
hash = hash_path_name (hash, "\\");
hash += hash_path_name (hash, "\\");
}
}
@ -2429,7 +2429,8 @@ hashit:
\a\b\. but allow a single \ if that's all there is. */
do
{
hash += *name + (*name << 17);
int ch = tolower(*name);
hash += ch + (ch << 17);
hash ^= hash >> 2;
}
while (*++name != '\0' &&

View File

@ -12,7 +12,7 @@ struct suffix_info
{
const char *name;
int addon;
suffix_info (const char *s, int addit = 0) {name = s, addon = addit;}
suffix_info (const char *s, int addit = 0): name (s), addon (addit) {}
};
enum pathconv_arg

View File

@ -24,11 +24,41 @@ details. */
#include "perprocess.h"
#include "environ.h"
#include "security.h"
#include <assert.h>
static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
static HANDLE hexec_proc = NULL;
void __stdcall
pinfo_fixup_after_fork ()
{
if (hexec_proc)
CloseHandle (hexec_proc);
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hexec_proc, 0,
TRUE, DUPLICATE_SAME_ACCESS))
{
system_printf ("couldn't save current process handle %p, %E", hMainProc);
hexec_proc = NULL;
}
}
void __stdcall
pinfo_fixup_in_spawned_child (HANDLE hchild)
{
HANDLE h;
if (!hexec_proc)
return;
if (!DuplicateHandle (hchild, hexec_proc, hMainProc, &h, 0, TRUE,
DUPLICATE_CLOSE_SOURCE))
system_printf ("couldn't close handle %p in child, %E", hexec_proc);
else
CloseHandle (h);
}
/* Initialize the process table.
This is done once when the dll is first loaded. */
@ -96,6 +126,14 @@ pinfo_init (char **envp)
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
}
void
_pinfo::exit (UINT n)
{
process_state = PID_EXITED;
sigproc_printf ("Calling ExitProcess %d", n);
ExitProcess (n);
}
struct sigaction&
_pinfo::getsig(int sig)
{
@ -185,66 +223,82 @@ pinfo::init (pid_t n, DWORD create, HANDLE in_h)
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 (in_h)
for (int i = 0; i < 10; i++)
{
h = in_h;
created = 0;
}
else 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_all_nih,
PAGE_READWRITE, 0, mapsize, mapname);
created = h && GetLastError () != ERROR_ALREADY_EXISTS;
}
int created;
char mapname[MAX_PATH];
__small_sprintf (mapname, "cygpid.%x", n);
if (!h)
{
if (create)
__seterrno ();
procinfo = NULL;
return;
}
int mapsize;
if (create & PID_EXECED)
mapsize = PINFO_REDIR_SIZE;
else
mapsize = sizeof (_pinfo);
ProtectHandle1 (h, pinfo_shared_handle);
procinfo = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (in_h)
{
h = in_h;
created = 0;
}
else 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_all_nih,
PAGE_READWRITE, 0, mapsize, mapname);
created = h && GetLastError () != ERROR_ALREADY_EXISTS;
}
if (procinfo->process_state & PID_EXECED)
{
pid_t realpid = procinfo->pid;
debug_printf ("execed process windows pid %d, cygwin pid %d", n, realpid);
release ();
if (realpid == n)
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
return init (realpid);
}
if (!h)
{
if (create)
__seterrno ();
procinfo = NULL;
return;
}
if (created)
{
if (!(create & PID_EXECED))
procinfo = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
ProtectHandle1 (h, pinfo_shared_handle);
if (procinfo->process_state & PID_EXECED)
{
assert (!i);
pid_t realpid = procinfo->pid;
debug_printf ("execed process windows pid %d, cygwin pid %d", n, realpid);
if (realpid == n)
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
n = realpid;
release ();
continue;
}
/* In certain rare, pathological cases, it is possible for the shared
memory region to exist for a while after a process has exited. This
should only be a brief occurrence, so rather than introduce some kind
of locking mechanism, just loop. FIXME: I'm sure I'll regret doing it
this way at some point. */
if (i < 9 && !created && create && (procinfo->process_state & PID_EXITED))
{
Sleep (5);
release ();
continue;
}
if (!created)
/* nothing */;
else if (!(create & PID_EXECED))
procinfo->pid = n;
else
{
procinfo->pid = myself->pid;
procinfo->process_state |= PID_IN_USE | PID_EXECED;
}
break;
}
destroy = 1;
}

View File

@ -94,6 +94,13 @@ public:
char root[MAX_PATH+1];
size_t rootlen;
/* Resources used by process. */
long start_time;
struct rusage rusage_self;
struct rusage rusage_children;
/* Pointer to mmap'ed areas for this process. Set up by fork. */
void *mmap_ptr;
/* Non-zero if process was stopped by a signal. */
char stopsig;
@ -104,21 +111,13 @@ public:
LONG* getsigtodo (int);
HANDLE getthread2signal ();
void setthread2signal (void *);
/* Resources used by process. */
long start_time;
struct rusage rusage_self;
struct rusage rusage_children;
void exit (UINT n) __attribute__ ((noreturn));
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;
};
class pinfo
@ -128,7 +127,7 @@ class pinfo
int destroy;
public:
void init (pid_t n, DWORD create = 0, HANDLE h = NULL);
pinfo (): h (NULL), procinfo (0), destroy (0) {}
pinfo () {}
pinfo (_pinfo *x): procinfo (x) {}
pinfo (pid_t n) {init (n);}
pinfo (pid_t n, int create) {init (n, create);}
@ -181,7 +180,8 @@ extern pinfo myself;
extern "C" int _spawnve (HANDLE hToken, int mode, const char *path,
const char *const *argv, const char *const *envp);
extern void __stdcall exec_fixup_after_fork ();
extern void __stdcall pinfo_fixup_after_fork ();
extern void __stdcall pinfo_fixup_in_spawned_child (HANDLE hchild);
/* For mmaps across fork(). */
int __stdcall recreate_mmaps_after_fork (void *);

View File

@ -65,6 +65,7 @@ fill_rusage (struct rusage *r, HANDLE h)
struct timeval tv;
memset (r, 0, sizeof (*r));
GetProcessTimes (h, &creation_time, &exit_time, &kernel_time, &user_time);
totimeval (&tv, &kernel_time, 0, 0);
add_timeval (&r->ru_stime, &tv);

View File

@ -602,7 +602,6 @@ write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size)
int
set_process_privileges ()
{
HANDLE hProcess = NULL;
HANDLE hToken = NULL;
LUID restore_priv;
LUID backup_priv;
@ -610,14 +609,7 @@ set_process_privileges ()
TOKEN_PRIVILEGES *new_priv = (TOKEN_PRIVILEGES *) buf;
int ret = -1;
hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId ());
if (! hProcess)
{
__seterrno ();
goto out;
}
if (! OpenProcessToken (hProcess,
if (! OpenProcessToken (hMainProc,
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
&hToken))
{
@ -656,8 +648,6 @@ set_process_privileges ()
out:
if (hToken)
CloseHandle (hToken);
if (hProcess)
CloseHandle (hProcess);
syscall_printf ("%d = set_process_privileges ()", ret);
return ret;

View File

@ -19,6 +19,10 @@ details. */
#include "sigproc.h"
#include "pinfo.h"
int sigcatchers; /* FIXME: Not thread safe. */
#define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL)
extern "C" _sig_func_ptr
signal (int sig, _sig_func_ptr func)
{
@ -35,6 +39,11 @@ signal (int sig, _sig_func_ptr func)
prev = myself->getsig (sig).sa_handler;
myself->getsig (sig).sa_handler = func;
myself->getsig (sig).sa_mask = 0;
if (!sigtrapped (prev) && sigtrapped (func))
sigcatchers++;
else if (sigtrapped (prev) && !sigtrapped (func))
sigcatchers--;
syscall_printf ("%p = signal (%d, %p)", prev, sig, func);
return prev;
}
@ -224,12 +233,8 @@ killpg (int pgrp, int sig)
}
extern "C" int
sigaction (int sig,
const struct sigaction *newaction,
struct sigaction *oldaction)
sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
{
struct sigaction out_oldaction;
/* check that sig is in right range */
if (sig < 0 || sig >= NSIG)
{
@ -238,25 +243,28 @@ sigaction (int sig,
return -1;
}
if (oldaction)
out_oldaction = myself->getsig (sig);
struct sigaction oa = myself->getsig (sig);
if (newaction)
if (newact)
{
if ((sig == SIGKILL || sig == SIGSTOP) && newaction->sa_handler != SIG_DFL)
if ((sig == SIGKILL || sig == SIGSTOP) && newact->sa_handler != SIG_DFL)
{
set_errno (EINVAL);
return -1;
}
myself->getsig (sig) = *newaction;
if (newaction->sa_handler == SIG_IGN)
myself->getsig (sig) = *newact;
if (newact->sa_handler == SIG_IGN)
sig_clear (sig);
if (newaction->sa_handler == SIG_DFL && sig == SIGCHLD)
if (newact->sa_handler == SIG_DFL && sig == SIGCHLD)
sig_clear (sig);
if (!sigtrapped (oa.sa_handler) && sigtrapped (newact->sa_handler))
sigcatchers++;
else if (sigtrapped (oa.sa_handler) && !sigtrapped (newact->sa_handler))
sigcatchers--;
}
if (oldaction)
*oldaction = out_oldaction;
if (oldact)
*oldact = oa;
return 0;
}

View File

@ -97,8 +97,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] = {pinfo ()};// All my children info
Static pinfo zombies[PSIZE] = {pinfo ()}; // All my deceased children info
Static pinfo pchildren[PSIZE]; // All my children info
Static pinfo zombies[PSIZE]; // All my deceased children info
Static int nchildren = 0; // Number of active children
Static int nzombies = 0; // Number of deceased children
@ -195,18 +195,12 @@ pid_exists (pid_t pid)
return proc_exists (p);
}
/* Test to determine if a process really exists and is processing
* signals.
/* Test to determine if a process really exists and is processing signals.
*/
BOOL __stdcall
proc_exists (_pinfo *p)
{
HANDLE h;
if (p == NULL)
return FALSE;
else
return TRUE;
return p && !(p->process_state & (PID_INITIALIZING | PID_EXITED));
}
/* Return 1 if this is one of our children, zero otherwise.
@ -266,7 +260,7 @@ proc_subproc (DWORD what, DWORD val)
hchildren[nchildren] = vchild->hProcess;
ProtectHandle1 (vchild->hProcess, childhProc);
if (!DuplicateHandle (hMainProc, vchild->hProcess, hMainProc, &vchild->pid_handle,
0, 0, DUPLICATE_SAME_ACCESS))
0, 0, DUPLICATE_SAME_ACCESS))
system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid);
ProtectHandle1 (vchild->pid_handle, pid_handle);
sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
@ -301,11 +295,6 @@ proc_subproc (DWORD what, DWORD val)
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
/* Send a SIGCHLD to myself. */
rc = sig_send (myself_nowait, SIGCHLD); // Send a SIGCHLD
break;
/* A child is in the stopped state. Scan wait() queue to see if anyone
@ -445,15 +434,13 @@ proc_terminate (void)
ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle);
}
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
zombies[i]->process_state = PID_EXITED; /* CGF FIXME - still needed? */
zombies[i].release(); // FIXME: this breaks older gccs for some reason
}
/* Disassociate my subprocesses */
for (i = 0; i < nchildren; i++)
{
if (pchildren[i]->process_state == PID_NOT_IN_USE)
continue; // Should never happen
if (!pchildren[i]->hProcess)
sigproc_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid,
pchildren[i]->dwProcessId);
@ -596,10 +583,10 @@ sigproc_terminate (void)
ForceCloseHandle (sigcomplete_main);
for (int i = 0; i < 20; i++)
(void) ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
ForceCloseHandle (sigcomplete_nonmain);
ForceCloseHandle (sigcatch_main);
ForceCloseHandle (sigcatch_nonmain);
ForceCloseHandle (sigcatch_nosync);
// ForceCloseHandle (sigcomplete_nonmain);
// ForceCloseHandle (sigcatch_main);
// ForceCloseHandle (sigcatch_nonmain);
// ForceCloseHandle (sigcatch_nosync);
}
proc_terminate (); // Terminate process handling thread
@ -610,19 +597,19 @@ sigproc_terminate (void)
sigproc_printf ("entering");
sig_loop_wait = 0; // Tell wait_sig to exit when it is
// finished with anything it is doing
sig_dispatch_pending (TRUE); // wake up and die
// sig_dispatch_pending (TRUE); // wake up and die
/* In case of a sigsuspend */
SetEvent (signal_arrived);
/* If !hwait_sig, then the process probably hasn't even finished
* its initialization phase.
*/
if (hwait_sig)
if (0 && hwait_sig)
{
if (GetCurrentThreadId () != sigtid)
WaitForSingleObject (h, 10000);
ForceCloseHandle1 (h, hwait_sig);
/* In case of a sigsuspend */
SetEvent (signal_arrived);
if (GetCurrentThreadId () != sigtid)
{
@ -636,9 +623,11 @@ sigproc_terminate (void)
sigproc_printf ("done");
}
#if 0
/* Set this so that subsequent tests will succeed. */
if (!myself->dwProcessId)
myself->dwProcessId = GetCurrentProcessId ();
#endif
return;
}
@ -1128,7 +1117,7 @@ wait_sig (VOID *)
* Signalling subproc_ready indicates that we are a cygwin process.
*/
if (child_proc_info &&
(child_proc_info->type == PROC_FORK || child_proc_info->type == PROC_SPAWN))
(child_proc_info->type == PROC_EXEC || child_proc_info->type == PROC_SPAWN))
{
debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
if (!SetEvent (child_proc_info->subproc_ready))
@ -1144,13 +1133,6 @@ wait_sig (VOID *)
SetEvent (wait_sig_inited);
sigtid = GetCurrentThreadId ();
/* If we got something like a SIGINT while we were initializing, the
signal thread should be waiting for this event. This signals the
thread that it's ok to send the signal since the wait_sig thread
is now active. */
extern HANDLE console_handler_thread_waiter;
SetEvent (console_handler_thread_waiter);
HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId);
for (;;)
@ -1306,7 +1288,14 @@ wait_subproc (VOID *)
errloop = 0;
rc -= WAIT_OBJECT_0;
if (rc-- != 0)
(void)proc_subproc (PROC_CHILDTERMINATED, rc);
{
(void) proc_subproc (PROC_CHILDTERMINATED, rc);
if (!proc_loop_wait) // Don't bother if wait_subproc is
break; // exiting
/* Send a SIGCHLD to myself. */
rc = sig_send (myself_nowait, SIGCHLD);
}
sigproc_printf ("looping");
}
@ -1327,7 +1316,6 @@ WFSO (HANDLE hHandle, DWORD dwMilliseconds)
DWORD ret;
sigframe thisframe (mainthread);
ret = WaitForSingleObject (hHandle, dwMilliseconds);
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
return ret;
}
@ -1339,7 +1327,6 @@ WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds
DWORD ret;
sigframe thisframe (mainthread);
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
return ret;
}
}

View File

@ -39,7 +39,6 @@ struct sigthread
DWORD id;
DWORD frame;
muto *lock;
sigthread () : id (0), frame (0), lock (0) {}
void init (const char *s);
};

View File

@ -219,16 +219,6 @@ linebuf::prepend (const char *what, int len)
ix = newix;
}
static HANDLE hexec_proc = NULL;
void __stdcall
exec_fixup_after_fork ()
{
if (hexec_proc)
CloseHandle (hexec_proc);
hexec_proc = NULL;
}
class av
{
char **argv;
@ -351,7 +341,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
}
ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
ciresrv.moreinfo->old_title = old_title ? cstrdup (old_title) : NULL;
ciresrv.moreinfo->old_title = NULL;
ciresrv.moreinfo->fds = fdtab;
ciresrv.moreinfo->nfds = fdtab.size;
@ -562,14 +552,6 @@ skip_arg_parsing:
if (!hToken && myself->token != INVALID_HANDLE_VALUE)
hToken = myself->token;
/* FIXME: This leaves a handle to the process open so that the pid is not
duplicated. However, if a process execs another process two handles are
left open, which is unnecessary. */
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 */
@ -631,18 +613,18 @@ skip_arg_parsing:
seteuid (uid);
}
else
rc = CreateProcessA (real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */
rc = CreateProcess (real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */
/* process security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
/* thread security attrs */
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
TRUE, /* inherit handles from parent */
flags,
envblock,/* environment */
0, /* use current drive/directory */
&si,
&pi);
allow_ntsec ? sec_user (sa_buf) : &sec_all_nih,
TRUE, /* inherit handles from parent */
flags,
envblock,/* environment */
0, /* use current drive/directory */
&si,
&pi);
MALLOC_CHECK;
if (envblock)
@ -691,6 +673,7 @@ skip_arg_parsing:
}
else
{
pinfo_fixup_in_spawned_child (pi.hProcess);
pinfo child (cygpid, 1);
if (!child)
{
@ -859,6 +842,9 @@ skip_arg_parsing:
{
case _P_OVERLAY:
proc_terminate ();
struct rusage r;
fill_rusage (&r, hMainProc);
add_rusage (&myself->rusage_self, &r);
ExitProcess (0);
break;
case _P_WAIT:

View File

@ -27,10 +27,8 @@ public:
void operator delete (void *) {;} /* can't handle allocated mutos
currently */
/* This simple constructor is used for cases where no bruteforce
event handling is required. */
muto(): sync(0), visits(0), waiters(-1), bruteforce(0), tid(0), next (NULL) {;}
/* A more complicated constructor. */
muto() {}
/* The real constructor. */
muto(int inh, const char *name);
~muto ();
int acquire (DWORD ms = INFINITE); /* Acquire the lock. */

View File

@ -53,10 +53,16 @@ extern BOOL allow_ntsec;
void __stdcall
close_all_files (void)
{
for (int i = 0; i < (int)fdtab.size; i++)
if (!fdtab.not_open (i))
_close (i);
SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK," close");
for (int i = 0; i < (int) fdtab.size; i++)
if (!fdtab.not_open (i))
{
fdtab[i]->close ();
fdtab.release (i);
}
ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK," close");
cygwin_shared->delqueue.process_queue ();
}
@ -200,6 +206,7 @@ extern "C" int
_read (int fd, void *ptr, size_t len)
{
sigframe thisframe (mainthread);
extern int sigcatchers;
if (fdtab.not_open (fd))
{
set_errno (EBADF);
@ -211,10 +218,10 @@ _read (int fd, void *ptr, size_t len)
DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE;
/* Could block, so let user know we at least got here. */
syscall_printf ("read (%d, %p, %d) %sblocking", fd, ptr, len, wait ? "" : "non");
syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers);
int res;
if (wait && (!fh->is_slow () || fh->get_r_no_interrupt ()))
if (wait && (!sigcatchers || !fh->is_slow () || fh->get_r_no_interrupt ()))
debug_printf ("non-interruptible read\n");
else if (!fh->ready_for_read (fd, wait, 0))
{
@ -236,7 +243,6 @@ _read (int fd, void *ptr, size_t len)
myself->process_state &= ~PID_TTYIN;
}
out:
syscall_printf ("%d = read (%d<%s>, %p, %d), errno %d", res, fd, fh->get_name (),
ptr, len, get_errno ());
@ -988,7 +994,7 @@ suffix_info stat_suffixes[] =
/* Cygwin internal */
static int
stat_worker (const char *caller, const char *name, struct stat *buf,
int nofollow)
int nofollow)
{
int res = -1;
int oret = 1;

View File

@ -29,7 +29,7 @@ extern "C"
#if defined (_CYG_THREAD_FAILSAFE) && defined (_MT_SAFE)
void AssertResourceOwner (int, int);
#else
#define AssertResourceOwner(i,ii)
# define AssertResourceOwner(i,ii)
#endif
}
@ -126,17 +126,17 @@ class pinfo;
class ResourceLocks
{
public:
ResourceLocks ():inited (false) {};
LPCRITICAL_SECTION Lock (int);
void Init ();
void Delete ();
ResourceLocks () {};
LPCRITICAL_SECTION Lock (int);
void Init ();
void Delete ();
#ifdef _CYG_THREAD_FAILSAFE
DWORD owner;
DWORD count;
DWORD owner;
DWORD count;
#endif
private:
CRITICAL_SECTION lock;
bool inited;
private:
CRITICAL_SECTION lock;
bool inited;
};
@ -146,100 +146,99 @@ bool inited;
class MTitem
{
public:
HANDLE win32_obj_id;
UINT return_value;
bool used;
char joinable; // for thread only
bool HandleOke () {return win32_obj_id;}
virtual void Destroy ();
virtual int Id () {return (int) win32_obj_id;}
public:
HANDLE win32_obj_id;
UINT return_value;
bool used;
char joinable; // for thread only
bool HandleOke () {return win32_obj_id;}
virtual void Destroy ();
virtual int Id () {return (int) win32_obj_id;}
};
class ThreadItem:public MTitem
class ThreadItem: public MTitem
{
public:
pthread_attr_t attr;
TFD (function);
void *arg;
void *return_ptr;
bool suspended;
DWORD thread_id;
DWORD GetThreadId () {return thread_id;}
pthread_attr_t attr;
TFD (function);
void *arg;
void *return_ptr;
bool suspended;
DWORD thread_id;
DWORD GetThreadId () {return thread_id;}
/* signal handling */
struct sigaction *sigs;
sigset_t *sigmask;
LONG *sigtodo;
/* signal handling */
struct sigaction *sigs;
sigset_t *sigmask;
LONG *sigtodo;
};
class MutexItem:public MTitem
class MutexItem: public MTitem
{
public:
int Lock ();
int TryLock ();
int UnLock ();
int Lock ();
int TryLock ();
int UnLock ();
};
class SemaphoreItem:public MTitem
class SemaphoreItem: public MTitem
{
public:
int shared;
int Wait ();
int Post ();
int TryWait ();
int shared;
int Wait ();
int Post ();
int TryWait ();
};
typedef struct
{
MTitem *items[MT_MAX_ITEMS];
int index;
}
MTList;
MTitem *items[MT_MAX_ITEMS];
int index;
} MTList;
class MTinterface
{
public:
// General
DWORD reent_index;
DWORD thread_key;
// General
DWORD reent_index;
DWORD thread_key;
// Used for main thread data, and sigproc thread
struct __reent_t reents;
struct _winsup_t winsup_reent;
ThreadItem mainthread;
// Used for main thread data, and sigproc thread
struct __reent_t reents;
struct _winsup_t winsup_reent;
ThreadItem mainthread;
void Init0 ();
void Init1 ();
void ClearReent ();
void Init0 ();
void Init1 ();
void ClearReent ();
void ReleaseItem (MTitem *);
void ReleaseItem (MTitem *);
// Thread functions
ThreadItem *CreateThread (pthread_t *, TFD (func), void *, pthread_attr_t);
ThreadItem *GetCallingThread ();
ThreadItem *GetThread (pthread_t *);
// Thread functions
ThreadItem *CreateThread (pthread_t *, TFD (func), void *, pthread_attr_t);
ThreadItem *GetCallingThread ();
ThreadItem *GetThread (pthread_t *);
// Mutex functions
MutexItem *CreateMutex (pthread_mutex_t *);
MutexItem *GetMutex (pthread_mutex_t *);
// Mutex functions
MutexItem *CreateMutex (pthread_mutex_t *);
MutexItem *GetMutex (pthread_mutex_t *);
// Semaphore functions
SemaphoreItem *CreateSemaphore (sem_t *, int, int);
SemaphoreItem *GetSemaphore (sem_t * t);
// Semaphore functions
SemaphoreItem *CreateSemaphore (sem_t *, int, int);
SemaphoreItem *GetSemaphore (sem_t * t);
private:
// General Administration
MTitem * Find (void *, int (*compare) (void *, void *), int &, MTList *);
MTitem *GetItem (int, MTList *);
MTitem *SetItem (int, MTitem *, MTList *);
int Find (MTitem &, MTList *);
int FindNextUnused (MTList *);
// General Administration
MTitem * Find (void *, int (*compare) (void *, void *), int &, MTList *);
MTitem *GetItem (int, MTList *);
MTitem *SetItem (int, MTitem *, MTList *);
int Find (MTitem &, MTList *);
int FindNextUnused (MTList *);
MTList threadlist;
MTList mutexlist;
MTList semalist;
MTList threadlist;
MTList mutexlist;
MTList semalist;
};