include-afsconfig-before-param-h-20010712
[openafs.git] / src / procmgmt / redirect_nt.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID("$Header$");
14
15
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <signal.h>
22 #include <windows.h>
23
24 #include "pmgtprivate.h"
25
26 /* Implements native-signal redirection.  Basically, NT generated signals
27  * are caught and passed through to the signal functions implemented by
28  * this process management library.
29  *
30  * Note that signals are passed through by name, since procmgmt.h can't
31  * be included here (given that signal(), raise(), etc. are redefined).
32  */
33
34
35 /* Program must have FP code to trap SIGFPE; MS suggests the following def. */
36 static volatile double dummyDouble = 0.0f;
37
38
39 /*
40  * NativeSignalHandler() -- handles (redirects) NT-generated signals.
41  */
42 static void __cdecl
43 NativeSignalHandler(int signo)
44 {
45     const char *signame = NULL;
46     int libSigno;
47
48     /* Reinstall signal handler for signo; no reliable signals on NT */
49     (void) signal(signo, NativeSignalHandler);
50
51     /* NT defines few signals, and doesn't really generate all of these */
52     switch (signo) {
53       case SIGINT:
54         signame = "SIGINT";
55         break;
56       case SIGILL:
57         signame = "SIGILL";
58         break;
59       case SIGFPE:
60         signame = "SIGFPE";
61         break;
62       case SIGSEGV:
63         signame = "SIGSEGV";
64         break;
65       case SIGTERM:
66         signame = "SIGTERM";
67         break;
68       case SIGABRT:
69         signame = "SIGABRT";
70         break;
71       default:
72         /* unexpect signo value */
73         signame = NULL;
74         break;
75     }
76
77     if (signame != NULL) {
78         /* Redirect NT signal into process management library */
79         if (pmgt_SignalRaiseLocalByName(signame, &libSigno) == 0 &&
80             signo == SIGABRT) {
81             /* SIGABRT is a special case.  It is generated by NT when abort()
82              * is called.  Upon returning from the signal handler, abort()
83              * will terminate the process with an exit code of 3.  In order
84              * to make an understandable termination status available to the
85              * process management library's waitpid() function, we exit
86              * the process here with a more appropriate exit code.
87              */
88             ExitProcess(PMGT_SIGSTATUS_ENCODE(libSigno));
89         }
90     }
91 }
92
93
94 /*
95  * pmgt_RedirectNativeSignals() -- initialize native signal redirection.
96  */
97 int
98 pmgt_RedirectNativeSignals(void)
99 {
100     if (signal(SIGINT, NativeSignalHandler) == SIG_ERR ||
101         signal(SIGILL, NativeSignalHandler) == SIG_ERR ||
102         signal(SIGFPE, NativeSignalHandler) == SIG_ERR ||
103         signal(SIGSEGV, NativeSignalHandler) == SIG_ERR ||
104         signal(SIGTERM, NativeSignalHandler) == SIG_ERR ||
105         signal(SIGABRT, NativeSignalHandler) == SIG_ERR) {
106         errno = EINVAL;
107         return -1;
108     } else {
109         return 0;
110     }
111 }