Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Wilson <cygwin@cwilson.fastmail.fm>2009-10-07 01:51:17 +0400
committerCharles Wilson <cygwin@cwilson.fastmail.fm>2009-10-07 01:51:17 +0400
commitc8ee587a8e8ebcc06ed49b771c759b57b19a1aec (patch)
tree735e3a5f5bb4895b3e9b57b7b283d559604a3160 /winsup/cygwin/external.cc
parent960bdc0e74168138b71b8b2e5e9659be64bce3f0 (diff)
Add cygwin wrapper for ExitProcess and TerminateProcess.
Diffstat (limited to 'winsup/cygwin/external.cc')
-rw-r--r--winsup/cygwin/external.cc38
1 files changed, 38 insertions, 0 deletions
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index e20bebf56..38b8c71e2 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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;