From 166b2571ce446b4085d4c2067b0d0d36c608f131 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 16 Oct 2000 23:55:58 +0000 Subject: [PATCH] * Makefile.in: Remove some obsolete stuff. * dcrt0.cc (dll_crt0_1): Call signal_fixup_after_exec where appropriate. Set myself->uid from parent version. Just use ThreadItem Init method. Close or store hexec_proc as appropriate. (_dll_crt0): Store user_data->forkee here so that proper tests can be made subsequently. (do_exit): Remove hExeced stuff. * environ.cc (environ_init): Accept environ count as well as environ pointer. * environ.h: Reflect above change. * pinfo.cc (pinfo_init): Ditto. Accept environ count. (fixup_in_spawned_child): Remove. * spawn.cc (spawn_guts): Move signal code to dll_crt0_1. Don't suspend execing process since it is no longer necessary. Store envc. * exceptions.cc (signal_fixup_after_exec): New function. (call_handler): Remove hExeced test. * child_info.h (cygheap_exec_info): Store envc as well as envp. (child_info_spawn): Store hexec_proc so that it can be closed in child. * path.cc (normalize_posix_path): Avoid intermediate use of temporary cwd buf. (normalize_win32_path): Ditto. (cwdstuff::get_initial): Always set lock. * sigproc.h: Remove hExeced. * strace.cc (strace::vsprntf): Modify to accomodate for lack of hExeced. * thread.cc (MTinterface::Init): Merge Init1 and ClearReent into this method. (MTinterface::Init1): Eliminate. (MTinterface::ClearReent): Eliminate. * thread.h: Reflect above changes. * include/sys/strace.h (strace): Make microseconds() public. Make various functions 'regparm', throughout. * pinfo.h (_pinfo): Inline simple signal manipulation functions. Requires inclusion of thread.h which was removed from .cc files, where appropriate. throughout. * pinfo.cc: Eliminate signal manipulation functions. (_pinfo::exit): Calculate total rusage for exiting process here. * cygheap.cc (size2bucket): Eliminate. (init_buckets): Ditto. (_cmalloc): Calculate size and bits in a loop rather than going through a function call. (_crealloc): Use stored array index to calculate allocated size. * spawn.cc (spawn_guts): Use _pinfo exit method to exit, calculating cpu usage. --- winsup/cygwin/ChangeLog | 46 ++++++++++ winsup/cygwin/Makefile.in | 26 ++---- winsup/cygwin/child_info.h | 11 ++- winsup/cygwin/cygerrno.h | 6 +- winsup/cygwin/cygheap.cc | 46 +++------- winsup/cygwin/cygheap.h | 12 +-- winsup/cygwin/dcrt0.cc | 74 ++++++++-------- winsup/cygwin/debug.h | 16 +--- winsup/cygwin/dtable.cc | 3 +- winsup/cygwin/dtable.h | 4 +- winsup/cygwin/environ.cc | 16 ++-- winsup/cygwin/environ.h | 2 +- winsup/cygwin/exceptions.cc | 17 +++- winsup/cygwin/fhandler.cc | 4 +- winsup/cygwin/fork.cc | 1 + winsup/cygwin/grp.cc | 1 - winsup/cygwin/include/sys/strace.h | 2 +- winsup/cygwin/mmap.cc | 1 - winsup/cygwin/net.cc | 1 - winsup/cygwin/passwd.cc | 1 - winsup/cygwin/path.cc | 25 +++--- winsup/cygwin/pinfo.cc | 112 +++--------------------- winsup/cygwin/pinfo.h | 45 +++++++--- winsup/cygwin/sigproc.cc | 13 --- winsup/cygwin/sigproc.h | 3 +- winsup/cygwin/spawn.cc | 101 ++++++++------------- winsup/cygwin/strace.cc | 4 +- winsup/cygwin/syscalls.cc | 1 - winsup/cygwin/thread.cc | 135 ++++++++++++++--------------- winsup/cygwin/thread.h | 8 +- winsup/cygwin/times.cc | 1 - winsup/cygwin/uinfo.cc | 1 - winsup/cygwin/winsup.h | 14 +-- 33 files changed, 322 insertions(+), 431 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bdc040099..695ada4a9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,49 @@ +Mon Oct 16 18:37:22 2000 Christopher Faylor + + * Makefile.in: Remove some obsolete stuff. + * dcrt0.cc (dll_crt0_1): Call signal_fixup_after_exec where appropriate. + Set myself->uid from parent version. + Just use ThreadItem Init method. Close or store hexec_proc as appropriate. + (_dll_crt0): Store user_data->forkee here so that proper tests can be made + subsequently. + (do_exit): Remove hExeced stuff. + * environ.cc (environ_init): Accept environ count as well as environ pointer. + * environ.h: Reflect above change. + * pinfo.cc (pinfo_init): Ditto. Accept environ count. + (fixup_in_spawned_child): Remove. + * spawn.cc (spawn_guts): Move signal code to dll_crt0_1. Don't suspend + execing process since it is no longer necessary. Store envc. + * exceptions.cc (signal_fixup_after_exec): New function. + (call_handler): Remove hExeced test. + * child_info.h (cygheap_exec_info): Store envc as well as envp. + (child_info_spawn): Store hexec_proc so that it can be closed in child. + * path.cc (normalize_posix_path): Avoid intermediate use of temporary cwd buf. + (normalize_win32_path): Ditto. + (cwdstuff::get_initial): Always set lock. + * sigproc.h: Remove hExeced. + * strace.cc (strace::vsprntf): Modify to accomodate for lack of hExeced. + * thread.cc (MTinterface::Init): Merge Init1 and ClearReent into this method. + (MTinterface::Init1): Eliminate. + (MTinterface::ClearReent): Eliminate. + * thread.h: Reflect above changes. + * include/sys/strace.h (strace): Make microseconds() public. + +Sun Oct 15 21:54:52 2000 Christopher Faylor + + Make various functions 'regparm', throughout. + * pinfo.h (_pinfo): Inline simple signal manipulation functions. + Requires inclusion of thread.h which was removed from .cc files, where + appropriate. throughout. + * pinfo.cc: Eliminate signal manipulation functions. + (_pinfo::exit): Calculate total rusage for exiting process here. + * cygheap.cc (size2bucket): Eliminate. + (init_buckets): Ditto. + (_cmalloc): Calculate size and bits in a loop rather than going through + a function call. + (_crealloc): Use stored array index to calculate allocated size. + * spawn.cc (spawn_guts): Use _pinfo exit method to exit, calculating + cpu usage. + Sat Oct 14 21:24:16 2000 Christopher Faylor * exceptions.cc (set_console_handler): Don't allocate diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index a5a780e24..2d2f4083c 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -51,7 +51,7 @@ CC:=@CC@ # FIXME: Which is it, CC or CC_FOR_TARGET? CC_FOR_TARGET:=$(CC) CFLAGS:=@CFLAGS@ -CFLAGS+=-MD +CFLAGS+=-MD -fbuiltin CXXFLAGS:=@CXXFLAGS@ # For linking mount, etc. crt0.o isn't accessable in a fresh build. @@ -84,11 +84,6 @@ RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \ else echo runtest; fi` RUNTESTFLAGS = -ifdef MT_SAFE -MT_SAFE_HEADERS:=thread.h -MT_SAFE_OBJECTS:=pthread.o thread.o -endif - # Parameters used in building the cygwin.dll. # We build as new-cygwin.dll and rename at install time to overcome # native rebuilding issues (we don't want the build tools to see a partially @@ -123,11 +118,11 @@ DLL_OFILES:=assert.o cygheap.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o \ fhandler_random.o fhandler_raw.o fhandler_serial.o fhandler_tape.o \ fhandler_termios.o fhandler_tty.o fhandler_windows.o fhandler_zero.o \ fork.o glob.o grp.o heap.o init.o ioctl.o localtime.o malloc.o mmap.o \ - net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o regexp.o regerror.o \ - regsub.o registry.o resource.o scandir.o security.o select.o shared.o \ - signal.o sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o \ - syscalls.o sysconf.o syslog.o termios.o times.o tty.o uinfo.o uname.o \ - wait.o window.o \ + net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o pthread.o regexp.o \ + regerror.o regsub.o registry.o resource.o scandir.o security.o select.o \ + shared.o signal.o sigproc.o smallprint.o spawn.o strace.o strsep.o \ + sync.o syscalls.o sysconf.o syslog.o termios.o thread.o times.o tty.o \ + uinfo.o uname.o wait.o window.o \ $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MT_SAFE_OBJECTS) GMON_OFILES:= gmon.o mcount.o profil.o @@ -219,15 +214,6 @@ Makefile: cygwin.din $(DEF_FILE): cygwin.din config.status $(SHELL) config.status -# .h file dependencies -# This may be overkill, but it's better than the previous situation. -# As files/dependencies are added and removed from Cygwin, please keep -# this list up to date. - -WINSUP_H:=winsup.h fhandler.h path.h shared.h \ - sigproc.h include/cygwin/version.h \ - $(MT_SAFE_HEADERS) - winsup.h: config.h ifneq (,${wildcard *.d}) diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index b3018c67b..725833050 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -60,12 +60,14 @@ class fhandler_base; class cygheap_exec_info { public: + uid_t uid; char *old_title; fhandler_base **fds; size_t nfds; int argc; char **argv; - char **environ; + int envc; + char **envp; HANDLE myself_pinfo; char *cwd_posix; char *cwd_win32; @@ -76,6 +78,7 @@ class child_info_spawn: public child_info { public: cygheap_exec_info *moreinfo; + HANDLE hexec_proc; child_info_spawn (): moreinfo (NULL) {} ~child_info_spawn () @@ -90,11 +93,11 @@ public: cfree (moreinfo->cwd_posix); if (moreinfo->cwd_win32) cfree (moreinfo->cwd_win32); - if (moreinfo->environ) + if (moreinfo->envp) { - for (char **e = moreinfo->environ; *e; e++) + for (char **e = moreinfo->envp; *e; e++) cfree (*e); - cfree (moreinfo->environ); + cfree (moreinfo->envp); } CloseHandle (moreinfo->myself_pinfo); cfree (moreinfo); diff --git a/winsup/cygwin/cygerrno.h b/winsup/cygwin/cygerrno.h index c83120095..dd40819b9 100644 --- a/winsup/cygwin/cygerrno.h +++ b/winsup/cygwin/cygerrno.h @@ -8,9 +8,9 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -void __stdcall seterrno_from_win_error (const char *file, int line, DWORD code); -void __stdcall seterrno (const char *, int line); -int __stdcall geterrno_from_win_error (DWORD code, int deferrno); +void __stdcall seterrno_from_win_error (const char *file, int line, DWORD code) __attribute__ ((regparm(3))); +void __stdcall seterrno (const char *, int line) __attribute__ ((regparm(2))); +int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ((regparm(2))); #define __seterrno() seterrno (__FILE__, __LINE__) #define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val) diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 21bde12e1..e583c1efc 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -70,35 +70,6 @@ _csbrk (int sbs) #define NBUCKETS 32 char *buckets[NBUCKETS] = {0}; -int bucket2size[NBUCKETS] = {0}; - -static inline int -size2bucket (int size) -{ - int rv = 0x1f; - int bit = ~0x10; - int i; - - if (size < 4) - size = 4; - size = (size + 3) & ~3; - - for (i = 0; i < 5; i++) - { - if (bucket2size[rv & bit] >= size) - rv &= bit; - bit >>= 1; - } - return rv; -} - -static inline void -init_buckets () -{ - unsigned b; - for (b = 0; b < NBUCKETS; b++) - bucket2size[b] = (1 << b); -} struct _cmalloc_entry { @@ -116,16 +87,19 @@ struct _cmalloc_entry #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data))) #define cygheap_chain ((_cmalloc_entry **)cygheap) +static void *_cmalloc (int size) __attribute ((regparm(1))); +static void *__stdcall _crealloc (void *ptr, int size) __attribute ((regparm(2))); + static void *__stdcall _cmalloc (int size) { _cmalloc_entry *rvc; - int b; + int b, sz; - if (bucket2size[0] == 0) - init_buckets (); + /* Calculate "bit bucket" and size as a power of two. */ + for (b = 3, sz = 8; sz && sz < (size + 4); b++, sz <<= 1) + continue; - b = size2bucket (size); cygheap_protect->acquire (); if (buckets[b]) { @@ -135,7 +109,7 @@ _cmalloc (int size) } else { - size = bucket2size[b] + sizeof (_cmalloc_entry); + size = sz + sizeof (_cmalloc_entry); rvc = (_cmalloc_entry *) _csbrk (size); rvc->b = b; @@ -165,7 +139,7 @@ _crealloc (void *ptr, int size) newptr = _cmalloc (size); else { - int oldsize = bucket2size[to_cmalloc (ptr)->b]; + int oldsize = 1 << to_cmalloc (ptr)->b; if (size <= oldsize) return ptr; newptr = _cmalloc (size); @@ -228,7 +202,7 @@ cygheap_fixup_in_child (HANDLE parent, bool execed) } } -static void *__stdcall +inline static void * creturn (cygheap_types x, cygheap_entry * c, int len) { if (!c) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index fc335c231..425185c6a 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -32,12 +32,12 @@ extern HANDLE cygheap_max; #define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max))) extern "C" { -void __stdcall cfree (void *); +void __stdcall cfree (void *) __attribute__ ((regparm(1))); void __stdcall cygheap_fixup_in_child (HANDLE, bool); -void *__stdcall cmalloc (cygheap_types, DWORD); -void *__stdcall crealloc (void *, DWORD); -void *__stdcall ccalloc (cygheap_types, DWORD, DWORD); -char *__stdcall cstrdup (const char *); -char *__stdcall cstrdup1 (const char *); +void *__stdcall cmalloc (cygheap_types, DWORD) __attribute__ ((regparm(2))); +void *__stdcall crealloc (void *, DWORD) __attribute__ ((regparm(2))); +void *__stdcall ccalloc (cygheap_types, DWORD, DWORD) __attribute__ ((regparm(3))); +char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1))); +char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1))); void __stdcall cygheap_init (); } diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 5adf59478..117cb75c6 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -15,6 +15,7 @@ details. */ #include "exceptions.h" #include "autoload.h" #include +#include #include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -27,7 +28,6 @@ details. */ #include "perthread.h" #include "path.h" #include "dtable.h" -#include "thread.h" #include "shared_info.h" #include "cygwin_version.h" #include "perprocess.h" @@ -650,7 +650,7 @@ dll_crt0_1 () _impure_ptr = &reent_data; user_data->resourcelocks->Init (); - user_data->threadinterface->Init0 (); + user_data->threadinterface->Init (user_data->forkee); threadname_init (); debug_init (); @@ -658,6 +658,7 @@ dll_crt0_1 () regthread ("main", GetCurrentThreadId ()); + int envc = 0; char **envp = NULL; if (child_proc_info) @@ -671,14 +672,17 @@ dll_crt0_1 () cygheap_fixup_in_child (child_proc_info->parent, 0); alloc_stack (fork_info); set_myself (mypid); - user_data->forkee = child_proc_info->cygpid; user_data->heaptop = child_proc_info->heaptop; user_data->heapbase = child_proc_info->heapbase; user_data->heapptr = child_proc_info->heapptr; ProtectHandle (child_proc_info->forker_finished); break; - case PROC_EXEC: case PROC_SPAWN: + CloseHandle (spawn_info->hexec_proc); + goto around; + case PROC_EXEC: + hexec_proc = spawn_info->hexec_proc; + around: HANDLE h; cygheap_fixup_in_child (spawn_info->parent, 1); if (!spawn_info->moreinfo->myself_pinfo || @@ -689,12 +693,14 @@ dll_crt0_1 () set_myself (mypid, h); __argc = spawn_info->moreinfo->argc; __argv = spawn_info->moreinfo->argv; - envp = spawn_info->moreinfo->environ; + envp = spawn_info->moreinfo->envp; + envc = spawn_info->moreinfo->envc; cygcwd.fixup_after_exec (spawn_info->moreinfo->cwd_win32, spawn_info->moreinfo->cwd_posix, spawn_info->moreinfo->cwd_hash); fdtab.fixup_after_exec (spawn_info->parent, spawn_info->moreinfo->nfds, spawn_info->moreinfo->fds); + signal_fixup_after_exec (child_proc_info->type == PROC_SPAWN); CloseHandle (spawn_info->parent); if (spawn_info->moreinfo->old_title) { @@ -702,6 +708,9 @@ dll_crt0_1 () cfree (spawn_info->moreinfo->old_title); } ProtectHandle (child_proc_info->subproc_ready); + myself->uid = spawn_info->moreinfo->uid; + if (myself->uid == USHRT_MAX) + myself->use_psid = 0; break; } } @@ -730,6 +739,8 @@ dll_crt0_1 () instead of each time a file is opened. */ set_process_privileges (); + cygbench ("pre-forkee"); + if (user_data->forkee) { /* If we've played with the stack, stacksize != 0. That means that @@ -751,24 +762,11 @@ dll_crt0_1 () cygcwd.init (); /* Initialize our process table entry. */ - pinfo_init (envp); + pinfo_init (envp, envc); if (!old_title && GetConsoleTitle (title_buf, TITLESIZE)) old_title = title_buf; - /* Nasty static stuff needed by newlib - initialize it. - Note that impure_ptr has already been set up to point to this above - NB. This *MUST* be done here, just after the forkee code as some - of the calls below (eg. uinfo_init) do stdio calls - this area must - be set to zero before then. */ - - user_data->threadinterface->ClearReent(); - user_data->threadinterface->Init1(); - - char *line = GetCommandLineA (); - - line = strcpy ((char *) alloca (strlen (line) + 1), line); - /* Allocate fdtab */ dtable_init (); @@ -786,6 +784,9 @@ dll_crt0_1 () if (!__argc) { + char *line = GetCommandLineA (); + line = strcpy ((char *) alloca (strlen (line) + 1), line); + /* Scan the command line and build argv. Expand wildcards if not called from another cygwin process. */ build_argv (line, __argv, __argc, @@ -848,6 +849,7 @@ dll_crt0_1 () set_errno (0); MALLOC_CHECK; + cygbench (__progname); if (user_data->main) exit (user_data->main (__argc, __argv, *user_data->envptr)); } @@ -862,6 +864,9 @@ extern "C" void __stdcall _dll_crt0 () { char zeros[sizeof (fork_info->zero)] = {0}; +#ifdef DEBUGGING + strace.microseconds (); +#endif /* Set the os_being_run global. */ set_os_type (); @@ -893,10 +898,11 @@ _dll_crt0 () { switch (fork_info->type) { - case PROC_EXEC: - case PROC_SPAWN: case PROC_FORK: case PROC_FORK1: + user_data->forkee = fork_info->cygpid; + case PROC_EXEC: + case PROC_SPAWN: { child_proc_info = fork_info; mypid = child_proc_info->cygpid; @@ -997,9 +1003,7 @@ do_exit (int status) } } - if ((hExeced && hExeced != INVALID_HANDLE_VALUE) || (n & EXIT_NOCLOSEALL)) - n &= ~EXIT_NOCLOSEALL; - else if (exit_state < ES_CLOSEALL) + if (exit_state < ES_CLOSEALL) { exit_state = ES_CLOSEALL; close_all_files (); @@ -1024,6 +1028,8 @@ do_exit (int status) /* Kill orphaned children on group leader exit */ if (myself->pid == myself->pgid) { + system_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children", + myself->pid, myself->pgid); sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children", myself->pid, myself->pgid); kill_pgrp (myself->pgid, -SIGHUP); @@ -1044,17 +1050,7 @@ do_exit (int status) } window_terminate (); - fill_rusage (&myself->rusage_self, hMainProc); - events_terminate (); - - if (hExeced && hExeced != INVALID_HANDLE_VALUE) - { - debug_printf ("Killing(%d) non-cygwin process, handle %p", n, hExeced); - TerminateProcess (hExeced, n); - ForceCloseHandle1 (hExeced, childhProc); - } - shared_terminate (); minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n); @@ -1101,6 +1097,16 @@ __api_fatal (const char *fmt, ...) myself->exit (1); } +#ifdef DEBUGGING +void __stdcall +cygbench (const char *s) +{ + char buf[1024]; + if (GetEnvironmentVariable ("CYGWIN_BENCH", buf, sizeof (buf))) + small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ()); +} +#endif + extern "C" { /* This struct is unused, but it illustrates the layout of a DLL diff --git a/winsup/cygwin/debug.h b/winsup/cygwin/debug.h index 419cbab1b..ff4313f77 100644 --- a/winsup/cygwin/debug.h +++ b/winsup/cygwin/debug.h @@ -16,22 +16,12 @@ 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 +DWORD __stdcall WFSO (HANDLE, DWORD) __attribute__ ((regparm(2))); +DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD) __attribute__ ((regparm(3))); } -#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_ @@ -43,6 +33,7 @@ void __stdcall regthread (const char *, DWORD); int __stdcall iscygthread (); #ifndef DEBUGGING +# define cygbench(s) # define ForceCloseHandle CloseHandle # define ForceCloseHandle1(h, n) CloseHandle (h) # define ForceCloseHandle2(h, n) CloseHandle (h) @@ -75,6 +66,7 @@ void debug_init (); void __stdcall add_handle (const char *, int, HANDLE, const char *); BOOL __stdcall close_handle (const char *, int, HANDLE, const char *, BOOL); int __stdcall lpfu (const char *, int, DWORD timeout); +void __stdcall cygbench (const char *s); #endif /*DEBUGGING*/ #endif /*_DEBUG_H_*/ diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 7d520b6da..be92bfce4 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -29,7 +29,6 @@ details. */ #include "fhandler.h" #include "path.h" #include "dtable.h" -#include "thread.h" dtable fdtab; @@ -154,7 +153,7 @@ dtable::release (int fd) { if (!not_open (fd)) { - delete fds[fd]; /* CGF FIXME */ + delete fds[fd]; fds[fd] = NULL; } } diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index 85963fc2d..1952e944b 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -27,14 +27,14 @@ public: fhandler_base *build_fhandler (int fd, DWORD dev, const char *name, int unit = -1); fhandler_base *build_fhandler (int fd, const char *name, HANDLE h); - int not_open (int n); + int not_open (int n) __attribute__ ((regparm(1))); int find_unused_handle (int start); int find_unused_handle () { return find_unused_handle (first_fd_for_open);} void release (int fd); void init_std_file_from_handle (int fd, HANDLE handle, DWORD access, const char *name); int dup2 (int oldfd, int newfd); void fixup_after_exec (HANDLE, size_t, fhandler_base **); - fhandler_base *operator [](int fd) { return fds[fd]; } + inline fhandler_base *operator [](int fd) { return fds[fd]; } select_record *select_read (int fd, select_record *s); select_record *select_write (int fd, select_record *s); select_record *select_except (int fd, select_record *s); diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index f0a3fc7d7..612e7e13e 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -517,10 +517,10 @@ regopt (const char *name) * environment variable and set appropriate options from it. */ void -environ_init (char **envp) +environ_init (char **envp, int envc) { char *rawenv; - int sz, i; + int i; char *p; char *newp; int sawTERM = 0; @@ -541,9 +541,8 @@ environ_init (char **envp) envp_passed_in = 0; else { - sz = envsize (envp, 1); - char **newenv = (char **) malloc (sz); - memcpy (newenv, envp, sz); + char **newenv = (char **) malloc (envc); + memcpy (newenv, envp, envc); cfree (envp); envp = newenv; envp_passed_in = 1; @@ -551,7 +550,7 @@ environ_init (char **envp) } /* Allocate space for environment + trailing NULL + CYGWIN env. */ - lastenviron = envp = (char **) malloc ((4 + (sz = 100)) * sizeof (char *)); + lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *)); rawenv = GetEnvironmentStrings (); /* Current directory information is recorded as variables of the @@ -561,9 +560,8 @@ environ_init (char **envp) for (i = 0, p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1, i++) { newp = strdup (p); - if (i >= sz) - envp = (char **) realloc (envp, (4 + (sz += 100)) * - sizeof (char *)); + if (i >= envc) + envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *)); envp[i] = newp; if (*newp == '=') *newp = '!'; diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h index e5967eb20..888b473dd 100644 --- a/winsup/cygwin/environ.h +++ b/winsup/cygwin/environ.h @@ -9,7 +9,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ /* Initialize the environment */ -void environ_init (char **); +void environ_init (char **, int); /* The structure below is used to control conversion to/from posix-style * file specs. Currently, only PATH and HOME are converted, but PATH diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 8a65f355b..75ad01c67 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -18,7 +18,6 @@ details. */ #include "sigproc.h" #include "pinfo.h" #include "cygerrno.h" -#include "thread.h" #include "perthread.h" #include "shared_info.h" #include "perprocess.h" @@ -639,7 +638,7 @@ interrupt_now (CONTEXT *ctx, int sig, struct sigaction& siga, void *handler) SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread */ } -void __cdecl +void __stdcall signal_fixup_after_fork () { if (!sigsave.sig) @@ -653,6 +652,18 @@ signal_fixup_after_fork () } } +void __stdcall +signal_fixup_after_exec (bool isspawn) +{ + /* Set up child's signal handlers */ + for (int i = 0; i < NSIG; i++) + { + myself->getsig(i).sa_mask = 0; + if (myself->getsig(i).sa_handler != SIG_IGN || isspawn) + myself->getsig(i).sa_handler = SIG_DFL; + } +} + static int interrupt_on_return (DWORD ebp, int sig, struct sigaction& siga, void *handler) { @@ -775,7 +786,7 @@ call_handler (int sig, struct sigaction& siga, void *handler) } next: - if (hExeced != NULL || (!using_mainthread_frame && interruptible (cx.Eip))) + if (!using_mainthread_frame && interruptible (cx.Eip)) interrupt_now (&cx, sig, siga, handler); else if (!interrupt_on_return (ebp, sig, siga, handler)) { diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 7c1299bf8..f6ce3adf9 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -463,7 +463,7 @@ fhandler_base::read (void *in_ptr, size_t in_len) } /* Scan buffer and turn \r\n into \n */ - register char *src= (char *) ptr; + register char *src = (char *) ptr; register char *dst = (char *) ptr; register char *end = src + copied_chars - 1; @@ -772,7 +772,7 @@ rootdir(char *full_path) * \\server\share... -> \\server\share\ * else current drive. */ - char *root=full_path; + char *root = full_path; if (full_path[1] == ':') strcpy (full_path + 2, "\\"); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c51fe23a3..a883ed553 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -301,6 +301,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls) /* Initialize signal/process handling */ sigproc_init (); + cygbench ("fork-child"); return 0; } diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 9c4f3794a..0469c0217 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -16,7 +16,6 @@ details. */ #include #include #include -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/include/sys/strace.h b/winsup/cygwin/include/sys/strace.h index 82cc75d5c..d40e3ad7d 100644 --- a/winsup/cygwin/include/sys/strace.h +++ b/winsup/cygwin/include/sys/strace.h @@ -23,10 +23,10 @@ class strace { - int microseconds (); int vsprntf (char *buf, const char *func, const char *infmt, va_list ap); void write (unsigned category, const char *buf, int count); public: + int microseconds (); int version; int active; int lmicrosec; diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 6beb45a2e..6d00a53f1 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -16,7 +16,6 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygerrno.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index c6d88f613..bb33bca57 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -27,7 +27,6 @@ details. */ #include "fhandler.h" #include "path.h" #include "dtable.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index 29e912699..62b2955a0 100644 --- a/winsup/cygwin/passwd.cc +++ b/winsup/cygwin/passwd.cc @@ -16,7 +16,6 @@ details. */ #include "cygerrno.h" #include "fhandler.h" #include "dtable.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index cfc81263a..cbd6e5493 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -62,7 +62,6 @@ details. */ #include "cygerrno.h" #include "fhandler.h" #include "path.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -574,15 +573,13 @@ normalize_posix_path (const char *src, char *dst) } if (!isslash (src[0])) { - char cwd[MAX_PATH]; - if (!cygcwd.get (cwd)) + if (!cygcwd.get (dst)) return get_errno (); - if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH) + if (strlen (dst) + 1 + strlen (src) >= MAX_PATH) { debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src); return ENAMETOOLONG; } - strcpy (dst, cwd); dst = strchr (dst, '\0'); if (*src == '.') goto sawdot; @@ -681,17 +678,15 @@ normalize_win32_path (const char *src, char *dst) if (!SLASH_P (src[0]) && strchr (src, ':') == NULL) { - char cwd[MAX_PATH]; - if (!cygcwd.get (cwd, 0)) + if (!cygcwd.get (dst, 0)) return get_errno (); - if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH) + if (strlen (dst) + 1 + strlen (src) >= MAX_PATH) { debug_printf ("ENAMETOOLONG = normalize_win32_path (%s)", src); return ENAMETOOLONG; } - strcpy (dst, cwd); dst += strlen (dst); - if (!*cwd || !SLASH_P (dst[-1])) + if (!SLASH_P (dst[-1])) *dst++ = '\\'; } /* Two leading \'s? If so, preserve them. */ @@ -2775,7 +2770,7 @@ cygwin_split_path (const char *path, char *dir, char *file) }) /* Return TRUE if two strings match up to length n */ -int __stdcall +extern "C" int __stdcall strncasematch (const char *s1, const char *s2, size_t n) { if (s1 == s2) @@ -2792,7 +2787,7 @@ strncasematch (const char *s1, const char *s2, size_t n) } /* Return TRUE if two strings match */ -int __stdcall +extern "C" int __stdcall strcasematch (const char *s1, const char *s2) { if (s1 == s2) @@ -2807,7 +2802,7 @@ strcasematch (const char *s1, const char *s2) return *s2 == '\0'; } -char * __stdcall +extern "C" char * __stdcall strcasestr (const char *searchee, const char *lookfor) { if (*searchee == 0) @@ -2881,10 +2876,11 @@ cwdstuff::fixup_after_exec (char *win32_cwd, char *posix_cwd, DWORD hash_cwd) bool cwdstuff::get_initial () { + lock->acquire (); + if (win32) return 1; - lock->acquire (); int i; DWORD len, dlen; for (i = 0, dlen = MAX_PATH, len = 0; i < 3; dlen *= 2, i++) @@ -2899,6 +2895,7 @@ cwdstuff::get_initial () __seterrno (); lock->release (); debug_printf ("get_initial_cwd failed, %E"); + lock->release (); return 0; } set (NULL); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 8d037e3af..21aa0fb8d 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -16,7 +16,6 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygerrno.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -30,7 +29,7 @@ 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; +HANDLE hexec_proc = NULL; void __stdcall pinfo_fixup_after_fork () @@ -46,19 +45,6 @@ pinfo_fixup_after_fork () } } -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. */ @@ -102,11 +88,11 @@ set_myself (pid_t pid, HANDLE h) /* Initialize the process table entry for the current task. This is not called for fork'd tasks, only exec'd ones. */ void __stdcall -pinfo_init (char **envp) +pinfo_init (char **envp, int envc) { if (envp) { - environ_init (envp); + environ_init (envp, envc); /* spawn has already set up a pid structure for us so we'll use that */ myself->process_state |= PID_CYGPARENT; } @@ -120,98 +106,28 @@ pinfo_init (char **envp) myself->ctty = -1; myself->uid = USHRT_MAX; - environ_init (NULL); /* call after myself has been set up */ + environ_init (NULL, 0); /* call after myself has been set up */ } debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid); } void -_pinfo::exit (UINT n) +_pinfo::exit (UINT n, bool norecord) { - process_state = PID_EXITED; + if (!norecord) + process_state = PID_EXITED; + + /* FIXME: There is a potential race between an execed process and its + parent here. I hated to add a mutex just for this, though. */ + struct rusage r; + fill_rusage (&r, hMainProc); + add_rusage (&rusage_self, &r); + sigproc_printf ("Calling ExitProcess %d", n); ExitProcess (n); } -struct sigaction& -_pinfo::getsig(int sig) -{ -#ifdef _MT_SAFE - if (thread2signal) - return thread2signal->sigs[sig]; - return sigs[sig]; -#else - return sigs[sig]; -#endif -}; - -sigset_t& -_pinfo::getsigmask () -{ -#ifdef _MT_SAFE - if (thread2signal) - return *thread2signal->sigmask; - return sig_mask; -#else - return sig_mask; -#endif -}; - -void -_pinfo::setsigmask (sigset_t _mask) -{ -#ifdef _MT_SAFE - if (thread2signal) - *(thread2signal->sigmask) = _mask; - sig_mask=_mask; -#else - sig_mask=_mask; -#endif -} - -LONG * -_pinfo::getsigtodo(int sig) -{ -#ifdef _MT_SAFE - if (thread2signal) - return thread2signal->sigtodo + __SIGOFFSET + sig; - return _sigtodo + __SIGOFFSET + sig; -#else - return _sigtodo + __SIGOFFSET + sig; -#endif -} - -extern HANDLE hMainThread; - -HANDLE -_pinfo::getthread2signal() -{ -#ifdef _MT_SAFE - if (thread2signal) - return thread2signal->win32_obj_id; - return hMainThread; -#else - return hMainThread; -#endif -} - -void -_pinfo::setthread2signal(void *_thr) -{ -#ifdef _MT_SAFE - // assert has myself lock - thread2signal=(ThreadItem*)_thr; -#else -#endif -} - -void -_pinfo::copysigs(_pinfo *_other) -{ - sigs = _other->sigs; -} - void pinfo::init (pid_t n, DWORD create, HANDLE in_h) { diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 2c57d83c8..067ef6104 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -20,8 +20,8 @@ enum #define PSIZE 1024 -class ThreadItem; #include +#include "thread.h" class _pinfo { @@ -104,20 +104,41 @@ public: /* 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 *); - void exit (UINT n) __attribute__ ((noreturn)); + void exit (UINT n, bool norecord = 0) __attribute__ ((noreturn, regparm(2))); + + inline struct sigaction& getsig (int sig) + { + return thread2signal ? thread2signal->sigs[sig] : sigs[sig]; + } + + inline void copysigs (_pinfo *p) {sigs = p->sigs;} + + inline sigset_t& getsigmask () + { + return thread2signal ? *thread2signal->sigmask : sig_mask; + } + + inline void setsigmask (sigset_t mask) + { + if (thread2signal) + *(thread2signal->sigmask) = mask; + sig_mask = mask; + } + + inline LONG* getsigtodo (int sig) {return _sigtodo + __SIGOFFSET + sig;} + + inline HANDLE getthread2signal () + { + return thread2signal ? thread2signal->win32_obj_id : hMainThread; + } + + inline void setthread2signal (void *thr) {thread2signal = (ThreadItem *) thr;} 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 + ThreadItem *thread2signal; // NULL means means thread any other means a pthread }; class pinfo @@ -172,7 +193,7 @@ cygwin_pid (pid_t pid) return (pid_t) (os_being_run == winNT) ? pid : -(int) pid; } -void __stdcall pinfo_init (char **); +void __stdcall pinfo_init (char **, int); void __stdcall set_myself (pid_t pid, HANDLE h = NULL); extern pinfo myself; @@ -181,7 +202,7 @@ extern "C" int _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv, const char *const *envp); extern void __stdcall pinfo_fixup_after_fork (); -extern void __stdcall pinfo_fixup_in_spawned_child (HANDLE hchild); +extern HANDLE hexec_proc; /* For mmaps across fork(). */ int __stdcall recreate_mmaps_after_fork (void *); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 1253b23eb..1d381d8bb 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -456,22 +456,9 @@ proc_terminate (void) pchildren[i].release (); } nchildren = nzombies = 0; - /* Just zero sync_proc_subproc as the delete below seems to cause problems for older gccs. */ - #if 1 sync_proc_subproc = NULL; - #else - /* Attempt to close and release sync_proc_subproc in a - * non-raceable manner. - */ - muto *m = sync_proc_subproc; - if (m) - { - sync_proc_subproc = NULL; - // delete m; - } - #endif } sigproc_printf ("leaving"); } diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index ee2e6a6cd..1a79cffc5 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -101,11 +101,10 @@ BOOL __stdcall proc_exists (_pinfo *); BOOL __stdcall pid_exists (pid_t); int __stdcall sig_send (_pinfo *, int, DWORD ebp = (DWORD) __builtin_frame_address (0)); void __stdcall signal_fixup_after_fork (); +void __stdcall signal_fixup_after_exec (bool); extern char myself_nowait_dummy[]; extern char myself_nowait_nonmain_dummy[]; -extern HANDLE hExeced; // Process handle of new window - // process created by spawn_guts() #define WAIT_SIG_EXITING (WAIT_OBJECT_0 + 1) diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 6939ad578..74f01fcd4 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -158,8 +158,6 @@ handle (int n, int direction) return fh->get_output_handle (); } -HANDLE NO_COPY hExeced = NULL; - int iscmd (const char *argv0, const char *what) { @@ -289,12 +287,9 @@ static int __stdcall spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, const char *const envp[], int mode) { - int i; BOOL rc; pid_t cygpid; - hExeced = NULL; - MALLOC_CHECK; if (prog_arg == NULL) @@ -507,10 +502,12 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, cygcwd.copy (ciresrv.moreinfo->cwd_posix, ciresrv.moreinfo->cwd_win32, ciresrv.moreinfo->cwd_hash); - ciresrv.moreinfo->environ = (char **) cmalloc (HEAP_1_ARGV, envsize (envp, 1)); + ciresrv.moreinfo->envc = envsize (envp, 0); + ciresrv.moreinfo->envp = (char **) cmalloc (HEAP_1_ARGV, ciresrv.moreinfo->envc); + ciresrv.hexec_proc = hexec_proc; char **c; const char * const *e; - for (c = ciresrv.moreinfo->environ, e = envp; *e;) + for (c = ciresrv.moreinfo->envp, e = envp; *e;) *c++ = cstrdup1 (*e++); *c = NULL; if (mode != _P_OVERLAY || @@ -530,11 +527,12 @@ skip_arg_parsing: syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf); - int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED | - GetPriorityClass (hMainProc); + int flags = CREATE_DEFAULT_ERROR_MODE | GetPriorityClass (hMainProc); if (mode == _P_DETACH || !set_console_state_for_spawn ()) flags |= DETACHED_PROCESS; + if (mode != _P_OVERLAY) + flags |= CREATE_SUSPENDED; /* Build windows style environment list */ char *envblock; @@ -552,7 +550,24 @@ skip_arg_parsing: if (!hToken && myself->token != INVALID_HANDLE_VALUE) hToken = myself->token; - if (hToken) +cygbench ("spawn-guts"); + if (!hToken) + { + ciresrv.moreinfo->uid = getuid (); + 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, + /* 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); + } + else { /* allow the child to interact with our window station/desktop */ HANDLE hwst, hdsk; @@ -561,6 +576,7 @@ skip_arg_parsing: char wstname[1024]; char dskname[1024]; + ciresrv.moreinfo->uid = USHRT_MAX; hwst = GetProcessWindowStation(); SetUserObjectSecurity(hwst, &dsi, get_null_sd ()); GetUserObjectInformation(hwst, UOI_NAME, wstname, 1024, &n); @@ -612,19 +628,6 @@ skip_arg_parsing: && myself->impersonated && myself->token != INVALID_HANDLE_VALUE) seteuid (uid); } - else - 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, - /* 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); MALLOC_CHECK; if (envblock) @@ -654,26 +657,17 @@ skip_arg_parsing: /* Name the handle similarly to proc_subproc. */ ProtectHandle1 (pi.hProcess, childhProc); - ProtectHandle (pi.hThread); if (mode == _P_OVERLAY) { + /* These are both duplicated in the child code. We do this here, + primarily for strace. */ strcpy (myself->progname, real_path); - hExeced = pi.hProcess; myself->dwProcessId = pi.dwProcessId; - - /* 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_fixup_in_spawned_child (pi.hProcess); + ProtectHandle (pi.hThread); pinfo child (cygpid, 1); if (!child) { @@ -684,7 +678,6 @@ skip_arg_parsing: child->username[0] = '\0'; child->progname[0] = '\0'; child->ppid = myself->pid; - child->uid = myself->uid; child->gid = myself->gid; child->pgid = myself->pgid; child->sid = myself->sid; @@ -702,27 +695,15 @@ skip_arg_parsing: child->rootlen = myself->rootlen; child->dwProcessId = pi.dwProcessId; child->hProcess = pi.hProcess; - 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->use_psid = 0; - } child.remember (); + /* Start the child running */ + ResumeThread (pi.hThread); } - sigproc_printf ("spawned windows pid %d", pi.dwProcessId); - /* Start the child running */ - ResumeThread (pi.hThread); ForceCloseHandle (pi.hThread); + sigproc_printf ("spawned windows pid %d", pi.dwProcessId); + if (hToken && hToken != myself->token) CloseHandle (hToken); @@ -824,16 +805,6 @@ skip_arg_parsing: system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess); } } - if (hExeced) - { - ForceCloseHandle1 (hExeced, childhProc); - hExeced = INVALID_HANDLE_VALUE; - } - } - else if (exited) - { - ForceCloseHandle1 (hExeced, childhProc); - hExeced = INVALID_HANDLE_VALUE; // stop do_exit from attempting to terminate child } MALLOC_CHECK; @@ -841,11 +812,9 @@ skip_arg_parsing: switch (mode) { case _P_OVERLAY: + ForceCloseHandle1 (pi.hProcess, childhProc); proc_terminate (); - struct rusage r; - fill_rusage (&r, hMainProc); - add_rusage (&myself->rusage_self, &r); - ExitProcess (0); + myself->exit (0, 1); break; case _P_WAIT: waitpid (cygpid, (int *) &res, 0); diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index badf0001a..74f77e1ad 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -134,7 +134,9 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap) *p = '\000'; p = progname; count = __small_sprintf (buf, fmt, p && *p ? p : "?", - myself->pid, hExeced ? "!" : ""); + myself->pid, + myself->dwProcessId != GetCurrentProcessId () + ? "!" : ""); if (func) count += getfunc (buf + count, func); } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index f54cc1ccf..f4a13b0a7 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -29,7 +29,6 @@ details. */ #include "fhandler.h" #include "path.h" #include "dtable.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index fb1a3d67c..cb2a98efe 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -20,7 +20,6 @@ details. */ #include #include #include -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -81,7 +80,7 @@ _reent_clib () SetLastError (tmp); return _r->_clib; -}; +} struct _winsup_t * _reent_winsup () @@ -95,7 +94,7 @@ _reent_winsup () #endif SetLastError (tmp); return _r->_winsup; -}; +} inline LPCRITICAL_SECTION ResourceLocks::Lock (int _resid) @@ -108,7 +107,7 @@ ResourceLocks::Lock (int _resid) _resid, &lock, user_data, myself->pid, GetCurrentThreadId ()); #endif return &lock; -}; +} void SetResourceLock (int _res_id, int _mode, const char *_function) @@ -138,7 +137,7 @@ ReleaseResourceLock (int _res_id, int _mode, const char *_function) #endif LeaveCriticalSection (user_data->resourcelocks->Lock (_res_id)); -}; +} #ifdef _CYG_THREAD_FAILSAFE void @@ -157,8 +156,6 @@ AssertResourceOwner (int _res_id, int _mode) void ResourceLocks::Init () { - thread_printf ("Init resource lock %p -> %p", this, &lock); - InitializeCriticalSection (&lock); inited = true; @@ -167,8 +164,8 @@ ResourceLocks::Init () count = 0; #endif - thread_printf ("Resource lock %p inited by %p , %d", &lock, user_data, myself->pid); -}; + thread_printf ("lock %p inited by %p , %d", &lock, user_data, myself->pid); +} void ResourceLocks::Delete () @@ -179,7 +176,7 @@ ResourceLocks::Delete () DeleteCriticalSection (&lock); inited = false; } -}; +} // Thread interface @@ -188,7 +185,7 @@ void MTinterface::ReleaseItem (MTitem * _item) { _item->used = false; -}; +} MTitem * MTinterface::Find (void *_value, int (*comp) (void *, void *), register int &_index, MTList * _list) @@ -202,7 +199,7 @@ MTinterface::Find (void *_value, int (*comp) (void *, void *), register int &_in current = NULL; } return current; -}; +} int MTinterface::Find (MTitem & _item, MTList * _list) @@ -216,21 +213,22 @@ MTinterface::Find (MTitem & _item, MTList * _list) break; } return (_index == _list->index ? -1 : _index); -}; +} int MTinterface::FindNextUnused (MTList * _list) { register int i = 0; - for (; i < _list->index && _list->items[i] != NULL && _list->items[i]->used && _list->items[i]->joinable != 'Y'; i++); + for (; i < _list->index && _list->items[i] != NULL && _list->items[i]->used && _list->items[i]->joinable != 'Y'; i++) + continue; return i; -}; +} MTitem * MTinterface::GetItem (int _index, MTList * _list) { return (_index < _list->index ? _list->items[_index] : NULL); -}; +} MTitem * MTinterface::SetItem (int _index, MTitem * _item, MTList * _list) @@ -238,23 +236,24 @@ MTinterface::SetItem (int _index, MTitem * _item, MTList * _list) if (_index == _list->index && _list->index < MT_MAX_ITEMS) _list->index++; return (_index < _list->index ? _list->items[_index] = _item : NULL); -}; +} int CmpPthreadObj (void *_i, void *_value) { return ((MTitem *) _i)->Id () == *(int *) _value; -}; +} int CmpThreadId (void *_i, void *_id) { return ((ThreadItem *) _i)->thread_id == * (DWORD *) _id; -}; +} void -MTinterface::Init0 () +MTinterface::Init (int forked) { +#if 0 for (int i = 0; i < MT_MAX_ITEMS; i++) { threadlist.items[i] = NULL; @@ -265,6 +264,7 @@ MTinterface::Init0 () threadlist.index = 0; mutexlist.index = 0; semalist.index = 0; +#endif reent_index = TlsAlloc (); @@ -272,39 +272,35 @@ MTinterface::Init0 () reents._winsup = &winsup_reent; winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG); +#if 0 winsup_reent._grp_pos = 0; winsup_reent._process_ident = 0; winsup_reent._process_logopt = 0; winsup_reent._process_facility = 0; +#endif TlsSetValue (reent_index, &reents); // the static reent_data will be used in the main thread -}; + if (forked) + return; -void -MTinterface::Init1 () -{ // create entry for main thread - int i = FindNextUnused (&threadlist); - assert (i == 0); - ThreadItem *item = (ThreadItem *) GetItem (i, &threadlist); + ThreadItem *item = (ThreadItem *) GetItem (0, &threadlist); - item = (ThreadItem *) SetItem (i, &mainthread, &threadlist); + item = (ThreadItem *) SetItem (0, &mainthread, &threadlist); item->used = true; item->win32_obj_id = myself->hProcess; item->thread_id = GetCurrentThreadId (); +#if 0 item->function = NULL; item->sigs = NULL; item->sigmask = NULL; item->sigtodo = NULL; -}; +#endif -void -MTinterface::ClearReent () -{ struct _reent *r = _REENT; memset (r, 0, sizeof (struct _reent)); @@ -312,9 +308,7 @@ MTinterface::ClearReent () r->_stdin = &r->__sf[0]; r->_stdout = &r->__sf[1]; r->_stderr = &r->__sf[2]; - -}; - +} ThreadItem * MTinterface::CreateThread (pthread_t * t, TFD (func), void *arg, pthread_attr_t a) @@ -342,8 +336,7 @@ MTinterface::CreateThread (pthread_t * t, TFD (func), void *arg, pthread_attr_t *t = (pthread_t) item->win32_obj_id; return item; -}; - +} MutexItem * MTinterface::CreateMutex (pthread_mutex_t * mutex) @@ -375,7 +368,7 @@ MTinterface::GetCallingThread () DWORD id = GetCurrentThreadId (); int index = 0; return (ThreadItem *) Find (&id, &CmpThreadId, index, &threadlist); -}; +} ThreadItem * MTinterface::GetThread (pthread_t * _t) @@ -383,7 +376,7 @@ MTinterface::GetThread (pthread_t * _t) AssertResourceOwner (LOCK_THREAD_LIST, READ_LOCK); int index = 0; return (ThreadItem *) Find (_t, &CmpPthreadObj, index, &threadlist); -}; +} MutexItem * MTinterface::GetMutex (pthread_mutex_t * mp) @@ -406,19 +399,19 @@ void MTitem::Destroy () { CloseHandle (win32_obj_id); -}; +} int MutexItem::Lock () { return WaitForSingleObject (win32_obj_id, INFINITE); -}; +} int MutexItem::TryLock () { return WaitForSingleObject (win32_obj_id, 0); -}; +} int MutexItem::UnLock () @@ -448,26 +441,26 @@ MTinterface::CreateSemaphore (sem_t * _s, int pshared, int _v) *_s = (sem_t) item->win32_obj_id; return item; -}; +} int SemaphoreItem::Wait () { return WaitForSingleObject (win32_obj_id, INFINITE); -}; +} int SemaphoreItem::Post () { long pc; return ReleaseSemaphore (win32_obj_id, 1, &pc); -}; +} int SemaphoreItem::TryWait () { return WaitForSingleObject (win32_obj_id, 0); -}; +} ////////////////////////// Pthreads @@ -547,34 +540,34 @@ __pthread_create (pthread_t * thread, const pthread_attr_t * attr, TFD (start_ro ReleaseResourceLock (LOCK_THREAD_LIST, WRITE_LOCK | READ_LOCK, "__pthread_create"); return 0; -}; +} int __pthread_attr_init (pthread_attr_t * attr) { attr->stacksize = 0; return 0; -}; +} int __pthread_attr_setstacksize (pthread_attr_t * attr, size_t size) { attr->stacksize = size; return 0; -}; +} int __pthread_attr_getstacksize (pthread_attr_t * attr, size_t * size) { *size = attr->stacksize; return 0; -}; +} int __pthread_attr_destroy (pthread_attr_t * /*attr*/) { return 0; -}; +} int __pthread_exit (void *value_ptr) @@ -609,7 +602,7 @@ __pthread_join (pthread_t * thread, void **return_val) }/* End if*/ return 0; -}; +} int __pthread_detach (pthread_t * thread) @@ -667,30 +660,30 @@ __pthread_getsequence_np (pthread_t * thread) { GETTHREAD ("__pthread_getsequence_np"); return item->GetThreadId (); -}; +} /* Thread SpecificData */ int __pthread_key_create (pthread_key_t */*key*/) { NOT_IMP ("_p_key_create\n"); -}; +} int __pthread_key_delete (pthread_key_t */*key*/) { NOT_IMP ("_p_key_delete\n"); -}; +} int __pthread_setspecific (pthread_key_t */*key*/, const void */*value*/) { NOT_IMP ("_p_key_setsp\n"); -}; +} void * __pthread_getspecific (pthread_key_t */*key*/) { NOT_IMP ("_p_key_getsp\n"); -}; +} /* Thread signal */ int @@ -708,7 +701,7 @@ __pthread_kill (pthread_t * thread, int sig) // unlock myself return rval; -}; +} int __pthread_sigmask (int operation, const sigset_t * set, sigset_t * old_set) @@ -728,7 +721,7 @@ __pthread_sigmask (int operation, const sigset_t * set, sigset_t * old_set) // unlock this myself return rval; -}; +} /* ID */ pthread_t @@ -741,13 +734,13 @@ __pthread_self () ReleaseResourceLock (LOCK_THREAD_LIST, READ_LOCK, "__pthread_self"); return (pthread_t) item->Id (); -}; +} int __pthread_equal (pthread_t * t1, pthread_t * t2) { return (*t1 - *t2); -}; +} /* Mutexes */ @@ -762,7 +755,7 @@ __pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t */*_att ReleaseResourceLock (LOCK_MUTEX_LIST, WRITE_LOCK | READ_LOCK, "__pthread_mutex_init"); return 0; -}; +} int __pthread_mutex_lock (pthread_mutex_t * mutex) @@ -772,7 +765,7 @@ __pthread_mutex_lock (pthread_mutex_t * mutex) item->Lock (); return 0; -}; +} int __pthread_mutex_trylock (pthread_mutex_t * mutex) @@ -783,7 +776,7 @@ __pthread_mutex_trylock (pthread_mutex_t * mutex) return EBUSY; return 0; -}; +} int __pthread_mutex_unlock (pthread_mutex_t * mutex) @@ -793,7 +786,7 @@ __pthread_mutex_unlock (pthread_mutex_t * mutex) item->UnLock (); return 0; -}; +} int __pthread_mutex_destroy (pthread_mutex_t * mutex) @@ -810,7 +803,7 @@ __pthread_mutex_destroy (pthread_mutex_t * mutex) ReleaseResourceLock (LOCK_MUTEX_LIST, READ_LOCK | WRITE_LOCK, "__pthread_mutex_destroy"); return 0; -}; +} /* Semaphores */ int @@ -824,7 +817,7 @@ __sem_init (sem_t * sem, int pshared, unsigned int value) ReleaseResourceLock (LOCK_SEM_LIST, READ_LOCK | WRITE_LOCK, "__sem_init"); return 0; -}; +} int __sem_destroy (sem_t * sem) @@ -841,7 +834,7 @@ __sem_destroy (sem_t * sem) ReleaseResourceLock (LOCK_SEM_LIST, READ_LOCK | WRITE_LOCK, "__sem_destroy"); return 0; -}; +} int __sem_wait (sem_t * sem) @@ -851,7 +844,7 @@ __sem_wait (sem_t * sem) item->Wait (); return 0; -}; +} int __sem_trywait (sem_t * sem) @@ -862,7 +855,7 @@ __sem_trywait (sem_t * sem) return EAGAIN; return 0; -}; +} int __sem_post (sem_t * sem) @@ -872,7 +865,7 @@ __sem_post (sem_t * sem) item->Post (); return 0; -}; +} #else diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 0ef4725c5..999bd5ed8 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -110,8 +110,8 @@ struct __reent_t _reent *_reent_clib (); _winsup_t *_reent_winsup (); -void SetResourceLock (int, int, const char *); -void ReleaseResourceLock (int, int, const char *); +void SetResourceLock (int, int, const char *) __attribute__ ((regparm(3))); +void ReleaseResourceLock (int, int, const char *) __attribute__ ((regparm(3))); #ifdef _CYG_THREAD_FAILSAFE void AssertResourceOwner (int, int); @@ -209,9 +209,7 @@ public: struct _winsup_t winsup_reent; ThreadItem mainthread; - void Init0 (); - void Init1 (); - void ClearReent (); + void Init (int); void ReleaseItem (MTitem *); diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index b8e715deb..bff40b612 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -19,7 +19,6 @@ details. */ #include "cygerrno.h" #include "fhandler.h" #include "path.h" -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 7057fd11e..e0c5d0726 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -18,7 +18,6 @@ details. */ #include #include #include -#include "thread.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 2deee0e6a..bd1fd9b12 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -184,15 +184,15 @@ int __stdcall writable_directory (const char *file); int __stdcall stat_dev (DWORD, int, unsigned long, struct stat *); extern BOOL allow_ntsec; -unsigned long __stdcall hash_path_name (unsigned long hash, const char *name); -void __stdcall nofinalslash (const char *src, char *dst); -extern "C" char *__stdcall rootdir (char *full_path); +unsigned long __stdcall hash_path_name (unsigned long hash, const char *name) __attribute__ ((regparm(2))); +void __stdcall nofinalslash (const char *src, char *dst) __attribute__ ((regparm(2))); +extern "C" char *__stdcall rootdir (char *full_path) __attribute__ ((regparm(1))); /* String manipulation */ -char *__stdcall strccpy (char *s1, const char **s2, char c); -int __stdcall strcasematch (const char *s1, const char *s2); -int __stdcall strncasematch (const char *s1, const char *s2, size_t n); -char *__stdcall strcasestr (const char *searchee, const char *lookfor); +extern "C" char *__stdcall strccpy (char *s1, const char **s2, char c); +extern "C" int __stdcall strcasematch (const char *s1, const char *s2) __attribute__ ((regparm(2))); +extern "C" int __stdcall strncasematch (const char *s1, const char *s2, size_t n) __attribute__ ((regparm(3))); +extern "C" char *__stdcall strcasestr (const char *searchee, const char *lookfor) __attribute__ ((regparm(2))); /* Time related */ void __stdcall totimeval (struct timeval *dst, FILETIME * src, int sub, int flag);