Add wrappers for ExitProcess, TerminateProcess

Charles Wilson
Mon Oct 5 19:04:00 GMT 2009

Normally, posix programs should call abort(), exit(), _exit(), kill() --
or various pthread functions -- to terminate operation (either their
own, or that of some other processes/thread).  However, there are two
cases where the win32 ExitProcess and TerminateProcess functions might
justifiably be called:
  1) inside cygwin's own process startup/shutdown implementation
  2) "Native" programs that use the w32api throughout, but are compiled
using the cygwin compiler (e.g. without -mno-cygwin). [*]

However, the ExitProcess and TerminateProcess functions, when called
directly, do not allow for the 'exit status' maintained by cygwin to be
set. This can be a problem when such cygwin applications are exec'ed by
other cygwin apps: cygwin's code for exec'ing children doesn't ever
check the value of GetExitCodeProcess as set by these win32 functions,
if the child application is also a cygwin app.

The attached patch address this problem, by providing two wrappers:
  cygwin_terminate_process <--> TerminateProcess
  cygwin_exit_process      <--> ExitProcess
which simply set the cygwin exit code using the specified status value,
and then delegate to the underlying win32 call. This way, the parent
process -- if it is a cygwin process -- can access the exit code as

Note that TerminateProcess/ExitProcess -- and the new wrappers -- bypass
most of the cygwin shutdown code, so it is not recommended that ANY of
these functions be used in normal cygwin applications; they should be
used only when necessary -- e.g. case #1 above.

[*] In case #2, even with this patch, the client code must be modified
to call the wrappers. We can, in a follow-up patch, add objects to
libcygwin.a that explicitly force using the wrappers when client code
calls ExitProcess/TerminateProcess, but I'm not sure that's a good idea,
so I deferred that decision. Furthermore, if you're going to modify the
source code of the client, you might as well modify it to use the
recommended posix functions, in actuality, it's just case
#1 that really needs this support.

So, how should cygwin's process startup/shutdown code use these new
functions? Well, this can serve as the beginnings of a generic mechanism
for deferring error messages on process startup, using custom NTSTATUS
values (which have bit 29 set: eg. 0x[ea62]0000000).  At present, cygwin
maps any NTSTATUS values greater than 0xc00000000 to a posix exit value
of 127, because when bits 30 and 31 are set, this means
"STATUS_SEVERITY_ERROR", and cygwin assumes that these NTSTATUS values
will only occur during process startup -- thus, a posix 127 is
appropriate for "errors that occur during process startup". We could
revisit this assumption later.

One example of intended use is the v2 runtime pseudo-reloc stuff, posted
simultaneously on the cygwin-devel list.

But, here's a short example:
#include <stdio.h>
#include <windows.h>
#include <ntdef.h>
#include <sys/cygwin.h>

#define STATUS_ILLEGAL_DLL_RELOCATION        ((NTSTATUS) 0xc0000269)
#define STATUS_DLL_NOT_FOUND                 ((NTSTATUS) 0xc0000135)

/* custom NTSTATUS value */

int main(int argc, char* argv[])
//cygwin_terminate_process (GetCurrentProcess(),
  exit (1);

$ gcc -o foo foo.c
$ ./foo
$ echo $?

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_exit_process): New function.
	(cygwin_terminate_process): New function.
	* include/cygwin/version.h: Bump version.
	* pinfo.h (pinfo::set_exit_code): New method.
	* (pinfo::set_exit_code): New, refactored from...
	(pinfo::maybe_set_exit_code_from_windows): here. Call it.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 01-cygwin-terminate-process.patch
Type: application/x-patch
Size: 7158 bytes
Desc: not available
URL: <>

More information about the Cygwin-patches mailing list