Dave Korn wrote: > Charles Wilson wrote: > >> By moving the definition to globals.cc, we get its extern declaration in >> the autogenerated globals.h -- which everybody includes via winsup.h. > > Ooh, I forgot we had that. Makes sense then.
As revised: 2009-10-04 Charles Wilson <...> Add cygwin wrappers for ExitProcess and TerminateProcess. * include/sys/cygwin.h: Declare new functions cygwin_exit_process and cygwin_terminate_process. * cygwin.din: Add new functions cygwin_exit_process and cygwin_terminate_process. * dcrt0.cc (cygwin_exit_process): New function. (cygwin_terminate_process): New function. * include/cygwin/version.h: Bump version. * pinfo.h (pinfo::set_exit_code): New method. * pinfo.cc (pinfo::set_exit_code): New, refactored from... (pinfo::maybe_set_exit_code_from_windows): here. Call it. * exceptions.cc: Move global variable sigExeced... * globals.cc: here. -- Chuck
? .globals.cc.swp ? lib/cygwin1.def ? lib/pseudo-reloc.c.save Index: cygwin.din =================================================================== RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v retrieving revision 1.216 diff -u -p -r1.216 cygwin.din --- cygwin.din 26 Sep 2009 21:01:10 -0000 1.216 +++ cygwin.din 5 Oct 2009 19:52:51 -0000 @@ -250,6 +250,7 @@ cygwin_conv_to_win32_path SIGFE cygwin_create_path SIGFE cygwin_detach_dll SIGFE_MAYBE cygwin_dll_init NOSIGFE +cygwin_exit_process NOSIGFE cygwin_internal NOSIGFE cygwin_logon_user SIGFE cygwin_posix_path_list_p NOSIGFE @@ -258,6 +259,7 @@ cygwin_posix_to_win32_path_list_buf_size cygwin_set_impersonation_token SIGFE cygwin_split_path NOSIGFE cygwin_stackdump SIGFE +cygwin_terminate_process NOSIGFE cygwin_umount SIGFE cygwin_win32_to_posix_path_list SIGFE cygwin_win32_to_posix_path_list_buf_size SIGFE Index: dcrt0.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dcrt0.cc,v retrieving revision 1.365 diff -u -p -r1.365 dcrt0.cc --- dcrt0.cc 2 Oct 2009 14:58:10 -0000 1.365 +++ dcrt0.cc 5 Oct 2009 19:52:52 -0000 @@ -41,6 +41,8 @@ details. */ extern "C" void cygwin_exit (int) __attribute__ ((noreturn)); +extern "C" BOOL cygwin_terminate_process (HANDLE, UINT); +extern "C" void cygwin_exit_process (UINT) __attribute__ ((noreturn)); extern "C" void __sinit (_reent *); static int NO_COPY envc; @@ -1136,6 +1138,67 @@ _exit (int n) do_exit (((DWORD) n & 0xff) << 8); } +/* DOCTOOL-START + <title>cygwin_terminate_process</title> + + <funcsynopsis><funcprototype> + <funcdef>extern "C" BOOL + <function>cygwin_terminate_process</function> + </funcdef> + <paramdef>HANDLE <parameter>process</parameter></paramdef> + <paramdef>UINT <parameter>status</parameter></paramdef> + </funcprototype></funcsynopsis> + + <para>Cygwin-specific wrapper for win32 TerminateProcess. It +ensures that if used to terminate the current process, then the +correct exit code will be made available to this process's parent +(if that parent is also a cygwin process). Otherwise, it simply +delegates to the win32 TerminateProcess.</para> + + <para>This function should be used in cygwin programs instead +of TerminateProcess. Ordinarily, however, the ANSI abort() or the +POSIX _exit() function should be preferred over either +TerminateProcess or cygwin_terminate_process when used to terminate +the current process. Similarly, the POSIX kill() function should +be used to terminate cygwin processes other than the current one. +</sect1> + + DOCTOOL-END */ +extern "C" BOOL +cygwin_terminate_process (HANDLE process, UINT status) +{ + if (process == GetCurrentProcess()) + myself.set_exit_code ((DWORD)status); + + return TerminateProcess (process, status); +} + +/* DOCTOOL-START + <title>cygwin_exit_process</title> + + <funcsynopsis><funcprototype> + <funcdef>extern "C" void + <function>cygwin_exit_process</function> + </funcdef> + <paramdef>UINT <parameter>status</parameter></paramdef> + </funcprototype></funcsynopsis> + + <para>Cygwin-specific wrapper for win32 ExitProcess, which +ensures that parent cygwin process receives the specified status +as an exit code, before calling ExitProcess. This function should +be used in cygwin programs instead of ExitProcess. Ordinarily, +however, the ANSI exit() function should be preferred over either +ExitProcess or cygwin_exit_process.</para> +</sect1> + + DOCTOOL-END */ +extern "C" void +cygwin_exit_process (UINT status) +{ + myself.set_exit_code ((DWORD)status); + ExitProcess (status); +} + extern "C" void __api_fatal (const char *fmt, ...) { Index: exceptions.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/exceptions.cc,v retrieving revision 1.335 diff -u -p -r1.335 exceptions.cc --- exceptions.cc 19 Sep 2009 15:34:19 -0000 1.335 +++ exceptions.cc 5 Oct 2009 19:52:52 -0000 @@ -40,7 +40,6 @@ extern void sigdelayed (); }; extern child_info_spawn *chExeced; -int NO_COPY sigExeced; static BOOL WINAPI ctrl_c_handler (DWORD); static WCHAR windows_system_directory[1024]; Index: globals.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/globals.cc,v retrieving revision 1.9 diff -u -p -r1.9 globals.cc --- globals.cc 24 Aug 2009 11:14:30 -0000 1.9 +++ globals.cc 5 Oct 2009 19:52:52 -0000 @@ -49,6 +49,10 @@ SYSTEM_INFO system_info; /* Set in init.cc. Used to check if Cygwin DLL is dynamically loaded. */ int NO_COPY dynamically_loaded; +/* set in exceptions.cc. Used to store the desired exit value when + a process is killed by a signal */ +int NO_COPY sigExeced; + bool display_title; bool strip_title_path; bool allow_glob = true; Index: pinfo.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/pinfo.cc,v retrieving revision 1.253 diff -u -p -r1.253 pinfo.cc --- pinfo.cc 12 Jul 2009 21:15:47 -0000 1.253 +++ pinfo.cc 5 Oct 2009 19:52:52 -0000 @@ -136,11 +136,18 @@ status_exit (DWORD x) # define self (*this) void +pinfo::set_exit_code (DWORD x) +{ + if (x >= 0xc0000000UL) + x = status_exit (x); + self->exitcode = EXITCODE_SET | (sigExeced ?: (x & 0xff) << 8); +} + +void pinfo::maybe_set_exit_code_from_windows () { DWORD x = 0xdeadbeef; DWORD oexitcode = self->exitcode; - extern int sigExeced; if (hProcess && !(self->exitcode & EXITCODE_SET)) { @@ -148,9 +155,7 @@ pinfo::maybe_set_exit_code_from_windows process hasn't quite exited after closing pipe */ GetExitCodeProcess (hProcess, &x); - if (x >= 0xc0000000UL) - x = status_exit (x); - self->exitcode = EXITCODE_SET | (sigExeced ?: (x & 0xff) << 8); + set_exit_code (x); } sigproc_printf ("pid %d, exit value - old %p, windows %p, cygwin %p", self->pid, oexitcode, x, self->exitcode); Index: pinfo.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/pinfo.h,v retrieving revision 1.108 diff -u -p -r1.108 pinfo.h --- pinfo.h 20 Dec 2008 17:32:31 -0000 1.108 +++ pinfo.h 5 Oct 2009 19:52:52 -0000 @@ -155,6 +155,7 @@ public: } void exit (DWORD n) __attribute__ ((noreturn, regparm(2))); void maybe_set_exit_code_from_windows () __attribute__ ((regparm(1))); + void set_exit_code (DWORD n) __attribute__ ((regparm(2))); _pinfo *operator -> () const {return procinfo;} int operator == (pinfo *x) const {return x->procinfo == procinfo;} int operator == (pinfo &x) const {return x.procinfo == procinfo;} Index: include/cygwin/version.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v retrieving revision 1.299 diff -u -p -r1.299 version.h --- include/cygwin/version.h 26 Sep 2009 21:01:10 -0000 1.299 +++ include/cygwin/version.h 5 Oct 2009 19:52:53 -0000 @@ -368,12 +368,13 @@ details. */ 212: Add and export libstdc++ malloc wrappers. 213: Export canonicalize_file_name, eaccess, euidaccess. 214: Export execvpe, fexecve. + 215: Export cygwin_terminate_process, cygwin_exit_process. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 214 +#define CYGWIN_VERSION_API_MINOR 215 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible Index: include/sys/cygwin.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/include/sys/cygwin.h,v retrieving revision 1.80 diff -u -p -r1.80 cygwin.h --- include/sys/cygwin.h 7 Jul 2009 20:12:44 -0000 1.80 +++ include/sys/cygwin.h 5 Oct 2009 19:52:53 -0000 @@ -94,6 +94,8 @@ extern void *cygwin_create_path (cygwin_ extern pid_t cygwin_winpid_to_pid (int); extern int cygwin_posix_path_list_p (const char *); extern void cygwin_split_path (const char *, char *, char *); +extern void cygwin_exit_process (unsigned int status) __attribute__((noreturn)); +extern BOOL cygwin_terminate_process (HANDLE process, unsigned int status); struct __cygwin_perfile {