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