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