petit: make argument of Write const
[omega.git] / petit / src / Exit.c
blobb17df013cf5c4c1a6b8820c338b9674730d09daf
1 /* $Id: Exit.c,v 1.3 2000/08/16 20:01:18 dwonnaco Exp $ */
3 /**********************************************************
4 * *
5 * Error fighting and exit facilities *
6 * *
7 **********************************************************/
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <signal.h>
14 #include <unistd.h>
15 #include <fcntl.h>
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>
23 #ifdef WIN32
24 #define Write(x) ;
25 #endif
27 static void RemoveIfEmpty(char *, FILE *);
29 static int mysignals = 0;
32 * if something bad happens
34 void set_signals(void) {
35 #ifndef WIN32
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. */
40 if(!mysignals) {
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");
51 Exit(-1);
53 mysignals = 1;
55 #endif
59 * Assertion failed
61 void ErrAssert(char *t) {
62 fprintf(stderr,"\n%s: %s\n", &petit_args.argv[0][0], t);
63 Exit(-2);
67 * User error
69 void Error(char *t) {
70 fprintf(stderr,"\n%s: %s\n", &petit_args.argv[0][0], t);
71 Exit(1);
75 * Warning
77 void Warning(char *t) {
78 fprintf(stderr, "\n%s: %s -- just warning\n", &petit_args.argv[0][0], t);
83 * Quit menu command
85 int Quit(int x) {
87 /* Close and remove debug files (if they are empty) */
88 RemoveIfEmpty("trace.out", debug);
89 RemoveIfEmpty("aux.out", debug2);
91 if(x<0) {
92 fprintf(stderr, "Empty or bad menu (xcode = %d)\n", x);
93 x=2;
94 } else {
95 x=0;
98 Exit(x);
100 return(0); /* eager to please compiler */
105 * Do closing procedures
108 void Exit(int e)
110 #ifndef WIN32
111 if(mysignals && signal(SIGTRAP, SIG_DFL) == SIGNAL_ERROR) {
113 fprintf(stderr, "\nset_signals: can not set reaction to signals\n");
114 exit(-4);
117 #if ! defined BATCH_ONLY_PETIT
118 motif_fini();
119 #endif
121 switch(e) {
122 case 0:
123 case -1000:
124 break;
125 case 1:
126 fprintf(stderr, "Exit apparently due to user error (exit code 1)\n");
127 break;
128 case 2:
129 case -2:
130 fprintf(stderr, "Exit apparently due to system limitation or error (exit code %d)\n", e);
131 break;
132 default:
133 fprintf(stderr, "Something really bad happened (exit code %d)\n", e);
134 break;
137 if(e<0)
139 char crash[1024];
140 FILE *fp;
142 crash[0]=0;
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) {
148 fclose(fp);
149 system(crash);
151 char *env_var_for_core = "PETIT_DUMP_CORE";
152 if (getenv(env_var_for_core))
154 abort();
156 else
157 fprintf(stderr, "Not dumping core - set %s to generate core dump\n", env_var_for_core);
159 #endif
160 exit(e);
164 * Abort by bad signal
166 #if SIG_HANDLER_HAS_ONE_ARG == 1
167 void sigAbort(int c)
168 #else
169 void sigAbort(int c, ...)
170 #endif
173 #ifndef WIN32
174 static struct sig1 {
175 int sig;
176 int core;
177 char *text;
178 } sigs[] = {
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"},
189 static char s[80];
190 int i;
191 sprintf(s,"\n%s: signal %d: ", &petit_args.argv[0][0], c);
192 Write(s);
193 for(i=0; i< (int)(sizeof(sigs)/sizeof(struct sig1)); i++) {
194 if(sigs[i].sig==c) {
195 sprintf(s, "%s", sigs[i].text);
196 Write(s);
197 break;
200 Write("\n");
201 if (i >= (int)(sizeof(sigs)/sizeof(struct sig1)) || sigs[i].core) {
202 Exit(-2);
203 } else {
204 Exit(0);
206 #else
207 Exit(c);
208 #endif
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");
220 Exit(-1000);
224 #ifndef WIN32
225 #include <sys/file.h>
227 void Write(const char *s) {
228 static int fd = -1;
229 int l;
230 if(fd<0) {
231 fd = open("/dev/tty",O_WRONLY,0);
232 if(fd<0) exit(187);
234 l=strlen(s);
235 if(write(fd,s,l)!=l) exit(188);
237 #endif
240 * Remove file with given name if it's empty
242 static
243 void RemoveIfEmpty(char *fname, FILE *file) {
244 fclose(file);
245 file = fopen(fname, "r");
246 if(file==NULL) {
247 #if 0
248 fprintf(stderr, "\nWarning: debug file %s was lost\n", fname);
249 #endif
250 return;
252 if(fgetc(file) == EOF) {
253 fclose(file);
254 if(unlink(fname)!=0) {
255 #if 0
256 fprintf(stderr, "Warning: can not remove debug file %s\n", fname);
257 #endif
259 } else {
260 fclose(file);