* 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:
parent
fdc614360f
commit
1dc16fc74b
|
@ -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.
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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' &&
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ struct sigthread
|
|||
DWORD id;
|
||||
DWORD frame;
|
||||
muto *lock;
|
||||
sigthread () : id (0), frame (0), lock (0) {}
|
||||
void init (const char *s);
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue