1 /* $Id: Exit.c,v 1.3 2000/08/16 20:01:18 dwonnaco Exp $ */
3 /**********************************************************
5 * Error fighting and exit facilities *
7 **********************************************************/
17 #include <petit/Exit.h>
18 #include <petit/debug.h>
19 #include <petit/omega2flags.h>
20 #include <petit/motif.h>
21 #include <petit/petit_args.h>
27 static void RemoveIfEmpty(char *, FILE *);
29 static int mysignals
= 0;
32 * if something bad happens
34 void set_signals(void) {
36 /* Set signal reactions */
37 /* Note that under Solaris 2.4 and other SYSV unices, upon receiving a signal,
38 the handler is set back to SIG_DFL before the signal handler is run.
39 This shouldn't make any difference. */
41 if(signal(SIGQUIT
,&sigAbort
) == SIGNAL_ERROR
||
42 signal(SIGINT
, &sigAbort
) == SIGNAL_ERROR
||
43 signal(SIGILL
, &sigAbort
) == SIGNAL_ERROR
||
44 signal(SIGTRAP
,&sigAbort
) == SIGNAL_ERROR
||
45 signal(SIGFPE
, &sigAbort
) == SIGNAL_ERROR
||
46 signal(SIGBUS
, &sigAbort
) == SIGNAL_ERROR
||
47 signal(SIGSEGV
,&sigAbort
) == SIGNAL_ERROR
||
48 // signal(SIGSYS, &sigAbort) == SIGNAL_ERROR ||
49 false ) { // this just makes it possible to comment out the above
50 fprintf(stderr
, "\nset_signals: can not set reaction to signals\n");
61 void ErrAssert(char *t
) {
62 fprintf(stderr
,"\n%s: %s\n", &petit_args
.argv
[0][0], t
);
70 fprintf(stderr
,"\n%s: %s\n", &petit_args
.argv
[0][0], t
);
77 void Warning(char *t
) {
78 fprintf(stderr
, "\n%s: %s -- just warning\n", &petit_args
.argv
[0][0], t
);
87 /* Close and remove debug files (if they are empty) */
88 RemoveIfEmpty("trace.out", debug
);
89 RemoveIfEmpty("aux.out", debug2
);
92 fprintf(stderr
, "Empty or bad menu (xcode = %d)\n", x
);
100 return(0); /* eager to please compiler */
105 * Do closing procedures
111 if(mysignals
&& signal(SIGTRAP
, SIG_DFL
) == SIGNAL_ERROR
) {
113 fprintf(stderr
, "\nset_signals: can not set reaction to signals\n");
117 #if ! defined BATCH_ONLY_PETIT
126 fprintf(stderr
, "Exit apparently due to user error (exit code 1)\n");
130 fprintf(stderr
, "Exit apparently due to system limitation or error (exit code %d)\n", e
);
133 fprintf(stderr
, "Something really bad happened (exit code %d)\n", e
);
143 char *home
= getenv("PETITHOME");
144 if (home
) strcpy(crash
, home
);
145 if (crash
[0]) strcat(crash
, "/misc/crash");
146 if (crash
[0]) fp
= fopen(crash
, "r");
147 if(crash
[0] && fp
!= NULL
) {
151 char *env_var_for_core
= "PETIT_DUMP_CORE";
152 if (getenv(env_var_for_core
))
157 fprintf(stderr
, "Not dumping core - set %s to generate core dump\n", env_var_for_core
);
164 * Abort by bad signal
166 #if SIG_HANDLER_HAS_ONE_ARG == 1
169 void sigAbort(int c
, ...)
179 {SIGINT
, 0, "Interrupt"},
180 {SIGQUIT
, 1, "Quit"},
181 {SIGILL
, 1, "Illegal instruction"},
182 {SIGTRAP
, 1, "Trace trap"},
183 {SIGABRT
, 1, "Abort"},
184 {SIGFPE
, 1, "Floating arithmetic exception"},
185 {SIGBUS
, 1, "Bus error"},
186 {SIGSEGV
, 1, "Segmentation violation"},
187 // {SIGSYS, 1, "Bad argument to system call"},
191 sprintf(s
,"\n%s: signal %d: ", &petit_args
.argv
[0][0], c
);
193 for(i
=0; i
< (int)(sizeof(sigs
)/sizeof(struct sig1
)); i
++) {
195 sprintf(s
, "%s", sigs
[i
].text
);
201 if (i
>= (int)(sizeof(sigs
)/sizeof(struct sig1
)) || sigs
[i
].core
) {
212 * We don't want to print anything if we don't have memory,
213 * because buffer allocation problem may lead to cycling
216 void out_of_memory(void)
218 fprintf(debug
,"Memory Allocation failed\n");
219 Write("Memory allocation failed -- not enough memory\n");
225 #include <sys/file.h>
227 void Write(const char *s
) {
231 fd
= open("/dev/tty",O_WRONLY
,0);
235 if(write(fd
,s
,l
)!=l
) exit(188);
240 * Remove file with given name if it's empty
243 void RemoveIfEmpty(char *fname
, FILE *file
) {
245 file
= fopen(fname
, "r");
248 fprintf(stderr
, "\nWarning: debug file %s was lost\n", fname
);
252 if(fgetc(file
) == EOF
) {
254 if(unlink(fname
)!=0) {
256 fprintf(stderr
, "Warning: can not remove debug file %s\n", fname
);