OSDN Git Service

Add cygwin wrapper for ExitProcess and TerminateProcess.
authorcwilson <cwilson>
Tue, 6 Oct 2009 21:51:14 +0000 (21:51 +0000)
committercwilson <cwilson>
Tue, 6 Oct 2009 21:51:14 +0000 (21:51 +0000)
winsup/cygwin/ChangeLog
winsup/cygwin/external.cc
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h

index 2bbff36..ffa5471 100644 (file)
@@ -1,5 +1,18 @@
 2009-10-05  Charles Wilson  <cygwin@cwilson.fastmail.fm>
 
+       Add cygwin wrapper for ExitProcess and TerminateProcess.
+       * include/sys/cygwin.h: Declare new cygwin_getinfo_type
+       CW_EXIT_PROCESS.
+       * external.cc (exit_process): New function.
+       (cygwin_internal): Handle CW_EXIT_PROCESS.
+       * 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.
+       * include/cygwin/version.h: Bump CYGWIN_VERSION_API_MINOR
+       to 215 to reflect the above change. 
+
+2009-10-05  Charles Wilson  <cygwin@cwilson.fastmail.fm>
+
        * exceptions.cc: Move global variable sigExeced...
        * globals.cc: here.
        * pinfo.cc (pinfo::maybe_set_exit_code_from_windows): Remove now
index e20bebf..38b8c71 100644 (file)
@@ -32,6 +32,7 @@ details. */
 #include <iptypes.h>
 
 child_info *get_cygwin_startup_info ();
+static void exit_process (UINT, bool) __attribute__((noreturn));
 
 static winpids pids;
 
@@ -161,6 +162,37 @@ sync_winenv ()
   free (envblock);
 }
 
+/*
+ * Cygwin-specific wrapper for win32 ExitProcess and TerminateProcess.
+ * It ensures that the correct exit code, derived from the specified
+ * status value, will be made available to this process's parent (if
+ * that parent is also a cygwin process). If useTerminateProcess is
+ * true, then TerminateProcess(GetCurrentProcess(),...) will be used;
+ * otherwise, ExitProcess(...) is called.
+ *
+ * Used by startup code for cygwin processes which is linked statically
+ * into applications, and is not part of the cygwin DLL -- which is why
+ * this interface is exposed. "Normal" programs should use ANSI exit(),
+ * ANSI abort(), or POSIX _exit(), rather than this function -- because
+ * calling ExitProcess or TerminateProcess, even through this wrapper,
+ * skips much of the cygwin process cleanup code.
+ */
+static void
+exit_process (UINT status, bool useTerminateProcess)
+{
+  pid_t pid = getpid ();
+  external_pinfo * ep = fillout_pinfo (pid, 1);
+  DWORD dwpid = ep ? ep->dwProcessId : pid;
+  pinfo p (pid, PID_MAP_RW);
+  if ((dwpid == GetCurrentProcessId()) && (p->pid == ep->pid))
+    p.set_exit_code ((DWORD)status);
+  if (useTerminateProcess)
+    TerminateProcess (GetCurrentProcess(), status);
+  /* avoid 'else' clause to silence warning */
+  ExitProcess (status);
+}
+
+
 extern "C" unsigned long
 cygwin_internal (cygwin_getinfo_types t, ...)
 {
@@ -375,6 +407,12 @@ cygwin_internal (cygwin_getinfo_types t, ...)
          seterrno(file, line);
        }
        break;
+      case CW_EXIT_PROCESS:
+       {
+         UINT status = va_arg (arg, UINT);
+         int useTerminateProcess = va_arg (arg, int);
+         exit_process (status, !!useTerminateProcess); /* no return */
+       }
 
       default:
        break;
index a396b1f..4cd7479 100644 (file)
@@ -368,12 +368,13 @@ details. */
       212: Add and export libstdc++ malloc wrappers.
       213: Export canonicalize_file_name, eaccess, euidaccess.
       214: Export execvpe, fexecve.
+      215: CW_EXIT_PROCESS added.
      */
 
      /* 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 3cd3a1c..5f38278 100644 (file)
@@ -142,7 +142,8 @@ typedef enum
     CW_CYGTLS_PADSIZE,
     CW_SET_DOS_FILE_WARNING,
     CW_SET_PRIV_KEY,
-    CW_SETERRNO
+    CW_SETERRNO,
+    CW_EXIT_PROCESS
   } cygwin_getinfo_types;
 
 #define CW_NEXTPID     0x80000000      /* or with pid to get next one */
index ee11d20..ba17f23 100644 (file)
@@ -136,6 +136,14 @@ 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;
@@ -147,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 5351595..8a30b8d 100644 (file)
@@ -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;}