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