procmgmt: Tidy header includes
[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 #include <roken.h>
14
15 #include <windows.h>
16
17 #include "pmgtprivate.h"
18
19 /* Implements native-signal redirection.  Basically, NT generated signals
20  * are caught and passed through to the signal functions implemented by
21  * this process management library.
22  *
23  * Note that signals are passed through by name, since procmgmt.h can't
24  * be included here (given that signal(), raise(), etc. are redefined).
25  */
26
27
28 /* Program must have FP code to trap SIGFPE; MS suggests the following def. */
29 static volatile double dummyDouble = 0.0f;
30
31
32 /*
33  * NativeSignalHandler() -- handles (redirects) NT-generated signals.
34  */
35 static void __cdecl
36 NativeSignalHandler(int signo)
37 {
38     const char *signame = NULL;
39     int libSigno;
40
41     /* Reinstall signal handler for signo; no reliable signals on NT */
42     (void)signal(signo, NativeSignalHandler);
43
44     /* NT defines few signals, and doesn't really generate all of these */
45     switch (signo) {
46     case SIGINT:
47         signame = "SIGINT";
48         break;
49     case SIGILL:
50         signame = "SIGILL";
51         break;
52     case SIGFPE:
53         signame = "SIGFPE";
54         break;
55     case SIGSEGV:
56         signame = "SIGSEGV";
57         break;
58     case SIGTERM:
59         signame = "SIGTERM";
60         break;
61     case SIGABRT:
62         signame = "SIGABRT";
63         break;
64     default:
65         /* unexpect signo value */
66         signame = NULL;
67         break;
68     }
69
70     if (signame != NULL) {
71         /* Redirect NT signal into process management library */
72         if (pmgt_SignalRaiseLocalByName(signame, &libSigno) == 0
73             && signo == SIGABRT) {
74             /* SIGABRT is a special case.  It is generated by NT when abort()
75              * is called.  Upon returning from the signal handler, abort()
76              * will terminate the process with an exit code of 3.  In order
77              * to make an understandable termination status available to the
78              * process management library's waitpid() function, we exit
79              * the process here with a more appropriate exit code.
80              */
81             ExitProcess(PMGT_SIGSTATUS_ENCODE(libSigno));
82         }
83     }
84 }
85
86
87 /*
88  * pmgt_RedirectNativeSignals() -- initialize native signal redirection.
89  */
90 int
91 pmgt_RedirectNativeSignals(void)
92 {
93     if (signal(SIGINT, NativeSignalHandler) == SIG_ERR
94         || signal(SIGILL, NativeSignalHandler) == SIG_ERR
95         || signal(SIGFPE, NativeSignalHandler) == SIG_ERR
96         || signal(SIGSEGV, NativeSignalHandler) == SIG_ERR
97         || signal(SIGTERM, NativeSignalHandler) == SIG_ERR
98         || signal(SIGABRT, NativeSignalHandler) == SIG_ERR) {
99         errno = EINVAL;
100         return -1;
101     } else {
102         return 0;
103     }
104 }
105
106 /*
107  * pmgt_RedirectNativeSignals() -- initialize native signal redirection.
108  */
109 int
110 pmgt_RestoreNativeSignals(void)
111 {
112     if (signal(SIGINT, SIG_DFL) == SIG_ERR
113         || signal(SIGILL, SIG_DFL) == SIG_ERR
114         || signal(SIGFPE, SIG_DFL) == SIG_ERR
115         || signal(SIGSEGV, SIG_DFL) == SIG_ERR
116         || signal(SIGTERM, SIG_DFL) == SIG_ERR
117         || signal(SIGABRT, SIG_DFL) == SIG_ERR) {
118         errno = EINVAL;
119         return -1;
120     } else {
121         return 0;
122     }
123 }
124