Import Upstream version 1.8.5
[hcoop/debian/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