1 /*
2  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #include <sys/signal.h>
19 #include "stdioInterf.h"
20 #include "fioMacros.h"
21 
22 #if defined(WIN32) || defined(WIN64)
23 #define write _write
24 #endif
25 
26 extern char *__fort_getopt(char *);
27 
28 /* signals handled and message strings */
29 
30 struct sigs {
31   int sig;   /* signal value */
32   char *str; /* message string */
33 };
34 
35 static struct sigs sigs[] = {
36     {SIGHUP, "hangup"},
37     {SIGINT, "interrupt"},
38     {SIGQUIT, "quit"},
39     {SIGILL, "illegal instruction"},
40     {SIGTRAP, "trace trap"},
41     {SIGIOT, "IOT instruction"},
42     {SIGBUS, "bus error"},
43     {SIGFPE, "floating point exception"},
44     /*	{SIGKILL,"kill"}, */
45     {SIGBUS, "bus error"},
46     {SIGSEGV, "segmentation violation"},
47     {SIGPIPE, "write on a pipe with no one to read it"},
48     /*	{SIGALRM,"alarm clock"}, */
49     /*	{SIGTERM,"software termination"},*/
50     {SIGTERM, NULL},
51 /*	{SIGURG,"urgent condition on IO channel"}, */
52 /*	{SIGSTOP,"sendable stop signal not from tty"}, */
53 /*	{SIGTSTP,"stop signal from tty"}, */
54 /*	{SIGCONT,"continue a stopped process"}, */
55 /*	{SIGCHLD,"to parent on child stop or exit"}, */
56 /*	{SIGTTIN,"to readers pgrp upon background tty read"}, */
57 /*	{SIGTTOU,"like TTIN for output if (tp->t_local&LTOSTOP)"}, */
58 /*	{SIGIO,"input/output possible signal"}, */
59 /*	{SIGXCPU,"exceeded CPU time limit"}, */
60 /*	{SIGXFSZ,"exceeded file size limit"}, */
61 /*	{SIGVTALRM,"virtual time alarm"}, */
62 /*	{SIGPROF,"profiling time alarm"}, */
63 /*	{SIGWINCH,"window changed"}, */
64 /*	{SIGLOST,"resource lost (eg, record-lock lost)"}, */
65 /*	{SIGUSR1,"user defined signal 1"}, */
66 /*	{SIGUSR2,"user defined signal 2"}, */
67     {0, NULL} /* end of list */
68 };
69 
70 /* print signal message */
71 
__fort_psignal(lcpu,s)72 void __fort_psignal(lcpu, s) int lcpu;
73 int s;
74 {
75   char buf[256];
76   int n;
77 
78   n = 0;
79   while ((sigs[n].sig != 0) && (sigs[n].sig != s)) {
80     n++;
81   }
82   if (sigs[n].sig == 0) {
83     sprintf(buf, "%d: killed by unknown signal %d\n", lcpu, s);
84     write(2, buf, strlen(buf));
85   } else if (sigs[n].str != NULL) {
86     sprintf(buf, "%d: %s\n", lcpu, sigs[n].str);
87     write(2, buf, strlen(buf));
88   }
89 }
90 
91 /* handler for signals */
92 
sighand(s)93 static void sighand(s) int s;
94 {
95   int lcpu;
96 
97   lcpu = __fort_myprocnum();
98   __fort_psignal(lcpu, s); /* print message */
99 #if !defined(WIN64) && !defined(WIN32)
100   sleep(1); /* wait for message to clear */
101 #endif
102   __fort_abort(NULL); /* abort */
103 }
104 
105 /* set handlers for signals */
106 
107 void
__fort_sethand()108 __fort_sethand()
109 {
110   char *p;
111   int n;
112 
113   p = __fort_getopt("-sigmsg");
114   if (p == NULL) {
115     return;
116   }
117   if ((*p == 'y') || (*p == 'Y') || (*p == 'a') || (*p == 'A') ||
118       (*p == '\0')) {
119     n = 0;
120     while (sigs[n].sig != 0) {
121       signal(sigs[n].sig, sighand);
122       n++;
123     }
124   } else {
125     while (*p != '\0') {
126       n = __fort_strtol(p, &p, 0);
127       signal(n, sighand);
128       p = (*p == ',' ? p + 1 : p);
129     }
130   }
131 }
132