blob: 980f2edee4a9751a588f1bb789664428103ae700 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum1984f1e1992-08-04 12:41:02 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Python interpreter top-level routines, including init/exit */
26
27#include "allobjects.h"
28
29#include "grammar.h"
30#include "node.h"
31#include "parsetok.h"
32#include "graminit.h"
33#include "errcode.h"
34#include "sysmodule.h"
Guido van Rossum6135a871995-01-09 17:53:26 +000035#include "bltinmodule.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036#include "compile.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000037#include "eval.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000038#include "ceval.h"
39#include "pythonrun.h"
40#include "import.h"
Guido van Rossumfdef2711994-09-14 13:31:04 +000041#include "marshal.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000042
Guido van Rossuma110aa61994-08-29 12:50:44 +000043#ifdef HAVE_SIGNAL_H
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000044#include <signal.h>
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000045#endif
46
Guido van Rossum42a51241995-01-30 12:52:46 +000047#ifdef THINK_C
48#include <console.h>
49#endif
50
Guido van Rossum1984f1e1992-08-04 12:41:02 +000051extern char *getpythonpath();
52
53extern grammar gram; /* From graminit.c */
54
Guido van Rossumb73cc041993-11-01 16:28:59 +000055/* Forward */
Guido van Rossum6135a871995-01-09 17:53:26 +000056static void initmain PROTO((void));
Guido van Rossuma110aa61994-08-29 12:50:44 +000057static object *run_err_node PROTO((node *n, char *filename,
Guido van Rossumb73cc041993-11-01 16:28:59 +000058 object *globals, object *locals));
59static object *run_node PROTO((node *n, char *filename,
60 object *globals, object *locals));
Guido van Rossuma110aa61994-08-29 12:50:44 +000061static void err_input PROTO((perrdetail *));
Guido van Rossumb376a4a1993-11-23 17:53:17 +000062static void initsigs PROTO((void));
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000063
Guido van Rossum1984f1e1992-08-04 12:41:02 +000064int debugging; /* Needed by parser.c */
65int verbose; /* Needed by import.c */
Guido van Rossuma110aa61994-08-29 12:50:44 +000066int suppress_print; /* Needed by ceval.c */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000067
68/* Initialize all */
69
70void
71initall()
72{
73 static int inited;
74
75 if (inited)
76 return;
77 inited = 1;
78
79 initimport();
80
Guido van Rossuma110aa61994-08-29 12:50:44 +000081 /* Modules '__builtin__' and 'sys' are initialized here,
Guido van Rossum1984f1e1992-08-04 12:41:02 +000082 they are needed by random bits of the interpreter.
83 All other modules are optional and are initialized
84 when they are first imported. */
85
86 initbuiltin(); /* Also initializes builtin exceptions */
87 initsys();
Guido van Rossum1984f1e1992-08-04 12:41:02 +000088
89 setpythonpath(getpythonpath());
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000090
91 initsigs(); /* Signal handling stuff, including initintr() */
Guido van Rossum6135a871995-01-09 17:53:26 +000092
93 initmain();
94}
95
96/* Create __main__ module */
97
98static void
99initmain()
100{
101 object *m, *d;
102 m = add_module("__main__");
103 if (m == NULL)
104 fatal("can't create __main__ module");
105 d = getmoduledict(m);
106 if (dictlookup(d, "__builtins__") == NULL) {
Guido van Rossum94390ec1995-01-12 11:37:57 +0000107 if (dictinsert(d, "__builtins__", getbuiltins()))
Guido van Rossum6135a871995-01-09 17:53:26 +0000108 fatal("can't add __builtins__ to __main__");
109 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000110}
111
112/* Parse input from a file and execute it */
113
114int
115run(fp, filename)
116 FILE *fp;
117 char *filename;
118{
119 if (filename == NULL)
120 filename = "???";
121 if (isatty((int)fileno(fp)))
122 return run_tty_loop(fp, filename);
123 else
124 return run_script(fp, filename);
125}
126
127int
128run_tty_loop(fp, filename)
129 FILE *fp;
130 char *filename;
131{
132 object *v;
133 int ret;
134 v = sysget("ps1");
135 if (v == NULL) {
136 sysset("ps1", v = newstringobject(">>> "));
137 XDECREF(v);
138 }
139 v = sysget("ps2");
140 if (v == NULL) {
141 sysset("ps2", v = newstringobject("... "));
142 XDECREF(v);
143 }
144 for (;;) {
145 ret = run_tty_1(fp, filename);
146#ifdef REF_DEBUG
147 fprintf(stderr, "[%ld refs]\n", ref_total);
148#endif
149 if (ret == E_EOF)
150 return 0;
151 /*
152 if (ret == E_NOMEM)
153 return -1;
154 */
155 }
156}
157
158int
159run_tty_1(fp, filename)
160 FILE *fp;
161 char *filename;
162{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000163 object *m, *d, *v, *w;
164 node *n;
Guido van Rossuma110aa61994-08-29 12:50:44 +0000165 perrdetail err;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000166 char *ps1, *ps2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000167 v = sysget("ps1");
168 w = sysget("ps2");
169 if (v != NULL && is_stringobject(v)) {
170 INCREF(v);
171 ps1 = getstringvalue(v);
172 }
173 else {
174 v = NULL;
175 ps1 = "";
176 }
177 if (w != NULL && is_stringobject(w)) {
178 INCREF(w);
179 ps2 = getstringvalue(w);
180 }
181 else {
182 w = NULL;
183 ps2 = "";
184 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000185 BGN_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000186 n = parsefile(fp, filename, &gram, single_input, ps1, ps2, &err);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000187 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000188 XDECREF(v);
189 XDECREF(w);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000190 if (n == NULL) {
191 if (err.error == E_EOF) {
192 if (err.text)
193 free(err.text);
194 return E_EOF;
195 }
196 err_input(&err);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000197 print_error();
Guido van Rossuma110aa61994-08-29 12:50:44 +0000198 return err.error;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000199 }
200 m = add_module("__main__");
201 if (m == NULL)
202 return -1;
203 d = getmoduledict(m);
204 v = run_node(n, filename, d, d);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000205 if (v == NULL) {
206 print_error();
207 return -1;
208 }
209 DECREF(v);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000210 flushline();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000211 return 0;
212}
213
214int
215run_script(fp, filename)
216 FILE *fp;
217 char *filename;
218{
219 object *m, *d, *v;
Guido van Rossumfdef2711994-09-14 13:31:04 +0000220 char *ext;
221
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000222 m = add_module("__main__");
223 if (m == NULL)
224 return -1;
225 d = getmoduledict(m);
Guido van Rossumfdef2711994-09-14 13:31:04 +0000226 ext = filename + strlen(filename) - 4;
227 if ( strcmp(ext, ".pyc") == 0 ) {
228 /* Try to run a pyc file. First, re-open in binary */
Jack Jansene00637b1994-12-14 12:58:37 +0000229 /* Don't close, done in main: fclose(fp); */
Guido van Rossumfdef2711994-09-14 13:31:04 +0000230 if( (fp = fopen(filename, "rb")) == NULL ) {
231 fprintf(stderr, "python: Can't reopen .pyc file\n");
232 return -1;
233 }
234 v = run_pyc_file(fp, filename, d, d);
235 } else {
236 v = run_file(fp, filename, file_input, d, d);
237 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000238 if (v == NULL) {
239 print_error();
240 return -1;
241 }
242 DECREF(v);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000243 flushline();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000244 return 0;
245}
246
247int
248run_command(command)
249 char *command;
250{
251 object *m, *d, *v;
252 m = add_module("__main__");
253 if (m == NULL)
254 return -1;
255 d = getmoduledict(m);
256 v = run_string(command, file_input, d, d);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000257 if (v == NULL) {
258 print_error();
259 return -1;
260 }
261 DECREF(v);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000262 flushline();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000263 return 0;
264}
265
266void
267print_error()
268{
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000269 object *exception, *v, *tb, *f;
270 err_fetch(&exception, &v, &tb);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000271 flushline();
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000272 if (exception == NULL)
273 fatal("print_error called but no exception");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000274 if (exception == SystemExit) {
275 if (v == NULL || v == None)
276 goaway(0);
277 if (is_intobject(v))
278 goaway((int)getintvalue(v));
279 else {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000280 /* OK to use real stderr here */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000281 printobject(v, stderr, PRINT_RAW);
282 fprintf(stderr, "\n");
283 goaway(1);
284 }
285 }
286 sysset("last_type", exception);
287 sysset("last_value", v);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000288 sysset("last_traceback", tb);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000289 f = sysget("stderr");
290 if (f == NULL)
291 fprintf(stderr, "lost sys.stderr\n");
292 else {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000293 tb_print(tb, f);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000294 if (exception == SyntaxError) {
295 object *message;
296 char *filename, *text;
297 int lineno, offset;
298 if (!getargs(v, "(O(ziiz))", &message,
299 &filename, &lineno, &offset, &text))
300 err_clear();
301 else {
302 char buf[10];
303 writestring(" File \"", f);
304 if (filename == NULL)
305 writestring("<string>", f);
306 else
307 writestring(filename, f);
308 writestring("\", line ", f);
309 sprintf(buf, "%d", lineno);
310 writestring(buf, f);
311 writestring("\n", f);
312 if (text != NULL) {
Guido van Rossum798199d1994-09-19 08:08:50 +0000313 char *nl;
314 if (offset > 0 &&
315 offset == strlen(text))
316 offset--;
317 for (;;) {
318 nl = strchr(text, '\n');
319 if (nl == NULL ||
320 nl-text >= offset)
321 break;
322 offset -= (nl+1-text);
323 text = nl+1;
324 }
Guido van Rossuma110aa61994-08-29 12:50:44 +0000325 while (*text == ' ' || *text == '\t') {
326 text++;
327 offset--;
328 }
329 writestring(" ", f);
330 writestring(text, f);
331 if (*text == '\0' ||
332 text[strlen(text)-1] != '\n')
333 writestring("\n", f);
334 writestring(" ", f);
335 offset--;
336 while (offset > 0) {
337 writestring(" ", f);
338 offset--;
339 }
340 writestring("^\n", f);
341 }
342 INCREF(message);
343 DECREF(v);
344 v = message;
345 }
346 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000347 if (writeobject(exception, f, PRINT_RAW) != 0)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000348 err_clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000349 if (v != NULL && v != None) {
350 writestring(": ", f);
351 if (writeobject(v, f, PRINT_RAW) != 0)
352 err_clear();
353 }
354 writestring("\n", f);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000355 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000356 XDECREF(exception);
357 XDECREF(v);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000358 XDECREF(tb);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000359}
360
361object *
362run_string(str, start, globals, locals)
363 char *str;
364 int start;
Guido van Rossum5b722181993-03-30 17:46:03 +0000365 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000366{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000367 return run_err_node(parse_string(str, start),
368 "<string>", globals, locals);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000369}
370
371object *
372run_file(fp, filename, start, globals, locals)
373 FILE *fp;
374 char *filename;
375 int start;
Guido van Rossum5b722181993-03-30 17:46:03 +0000376 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000377{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000378 return run_err_node(parse_file(fp, filename, start),
379 filename, globals, locals);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000380}
381
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000382static object *
Guido van Rossuma110aa61994-08-29 12:50:44 +0000383run_err_node(n, filename, globals, locals)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000384 node *n;
385 char *filename;
Guido van Rossum5b722181993-03-30 17:46:03 +0000386 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000387{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000388 if (n == NULL)
389 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000390 return run_node(n, filename, globals, locals);
391}
392
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000393static object *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000394run_node(n, filename, globals, locals)
395 node *n;
396 char *filename;
Guido van Rossum5b722181993-03-30 17:46:03 +0000397 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000398{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000399 codeobject *co;
400 object *v;
401 co = compile(n, filename);
402 freetree(n);
403 if (co == NULL)
404 return NULL;
Guido van Rossum81daa321993-05-20 14:24:46 +0000405 v = eval_code(co, globals, locals, (object *)NULL, (object *)NULL);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000406 DECREF(co);
407 return v;
408}
409
Guido van Rossum8ae87c01995-01-26 00:40:38 +0000410static object *
Guido van Rossumfdef2711994-09-14 13:31:04 +0000411run_pyc_file(fp, filename, globals, locals)
412 FILE *fp;
413 char *filename;
414 object *globals, *locals;
415{
416 codeobject *co;
417 object *v;
418 long magic;
419 long get_pyc_magic();
420
421 magic = rd_long(fp);
422 if (magic != get_pyc_magic()) {
423 err_setstr(RuntimeError,
424 "Bad magic number in .pyc file");
425 return NULL;
426 }
427 (void) rd_long(fp);
428 v = rd_object(fp);
429 fclose(fp);
430 if (v == NULL || !is_codeobject(v)) {
431 XDECREF(v);
432 err_setstr(RuntimeError,
433 "Bad code object in .pyc file");
434 return NULL;
435 }
436 co = (codeobject *)v;
437 v = eval_code(co, globals, locals, (object *)NULL, (object *)NULL);
438 DECREF(co);
439 return v;
440}
441
442object *
Guido van Rossum5b722181993-03-30 17:46:03 +0000443compile_string(str, filename, start)
444 char *str;
445 char *filename;
446 int start;
447{
448 node *n;
Guido van Rossum5b722181993-03-30 17:46:03 +0000449 codeobject *co;
Guido van Rossuma110aa61994-08-29 12:50:44 +0000450 n = parse_string(str, start);
451 if (n == NULL)
Guido van Rossum5b722181993-03-30 17:46:03 +0000452 return NULL;
Guido van Rossum5b722181993-03-30 17:46:03 +0000453 co = compile(n, filename);
454 freetree(n);
455 return (object *)co;
456}
457
Guido van Rossuma110aa61994-08-29 12:50:44 +0000458/* Simplified interface to parsefile -- return node or set exception */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000459
Guido van Rossuma110aa61994-08-29 12:50:44 +0000460node *
461parse_file(fp, filename, start)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000462 FILE *fp;
463 char *filename;
464 int start;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000465{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000466 node *n;
467 perrdetail err;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 BGN_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000469 n = parsefile(fp, filename, &gram, start,
470 (char *)0, (char *)0, &err);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000471 END_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000472 if (n == NULL)
473 err_input(&err);
474 return n;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000475}
476
Guido van Rossuma110aa61994-08-29 12:50:44 +0000477/* Simplified interface to parsestring -- return node or set exception */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000478
Guido van Rossuma110aa61994-08-29 12:50:44 +0000479node *
480parse_string(str, start)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000481 char *str;
482 int start;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000483{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000484 node *n;
485 perrdetail err;
486 n = parsestring(str, &gram, start, &err);
487 if (n == NULL)
488 err_input(&err);
489 return n;
490}
491
492/* Set the error appropriate to the given input error code (see errcode.h) */
493
494static void
495err_input(err)
496 perrdetail *err;
497{
498 object *v, *w;
499 char *msg = NULL;
500 v = mkvalue("(ziiz)", err->filename,
501 err->lineno, err->offset, err->text);
502 if (err->text != NULL) {
503 free(err->text);
504 err->text = NULL;
505 }
506 switch (err->error) {
507 case E_SYNTAX:
508 msg = "invalid syntax";
509 break;
510 case E_TOKEN:
511 msg = "invalid token";
512
513 break;
514 case E_INTR:
515 err_set(KeyboardInterrupt);
516 return;
517 case E_NOMEM:
518 err_nomem();
519 return;
520 case E_EOF:
521 msg = "unexpected EOF while parsing";
522 break;
523 default:
524 fprintf(stderr, "error=%d\n", err->error);
525 msg = "unknown parsing error";
526 break;
527 }
528 w = mkvalue("(sO)", msg, v);
529 XDECREF(v);
530 err_setval(SyntaxError, w);
531 XDECREF(w);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000532}
533
534/* Print fatal error message and abort */
535
536void
537fatal(msg)
538 char *msg;
539{
Guido van Rossum83dd6c31994-09-29 09:38:33 +0000540 fprintf(stderr, "Fatal Python error: %s\n", msg);
Guido van Rossum8ae87c01995-01-26 00:40:38 +0000541#ifdef macintosh
542 for (;;);
543#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000544 abort();
545}
546
547/* Clean up and exit */
548
Guido van Rossuma110aa61994-08-29 12:50:44 +0000549#ifdef WITH_THREAD
550#include "thread.h"
551int threads_started = 0; /* Set by threadmodule.c and maybe others */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000552#endif
553
Guido van Rossum1662dd51994-09-07 14:38:28 +0000554#define NEXITFUNCS 32
555static void (*exitfuncs[NEXITFUNCS])();
556static int nexitfuncs = 0;
557
558int Py_AtExit(func)
559 void (*func) PROTO((void));
560{
561 if (nexitfuncs >= NEXITFUNCS)
562 return -1;
563 exitfuncs[nexitfuncs++] = func;
564 return 0;
565}
566
Guido van Rossuma110aa61994-08-29 12:50:44 +0000567void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000568cleanup()
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000569{
Guido van Rossum59bff391992-09-03 20:28:00 +0000570 object *exitfunc = sysget("exitfunc");
571
572 if (exitfunc) {
573 object *arg;
574 object *res;
575 sysset("exitfunc", (object *)NULL);
576 arg = newtupleobject(0);
577 if (arg == NULL)
578 res = NULL;
579 else {
580 res = call_object(exitfunc, arg);
581 DECREF(arg);
582 }
583 if (res == NULL) {
584 fprintf(stderr, "Error in sys.exitfunc:\n");
585 print_error();
586 }
587 }
588
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000589 flushline();
Guido van Rossum1662dd51994-09-07 14:38:28 +0000590
591 while (nexitfuncs > 0)
592 (*exitfuncs[--nexitfuncs])();
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000593}
594
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000595#ifdef COUNT_ALLOCS
596extern void dump_counts PROTO((void));
597#endif
598
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000599void
600goaway(sts)
601 int sts;
602{
603 cleanup();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000605#ifdef COUNT_ALLOCS
606 dump_counts();
607#endif
608
Guido van Rossuma110aa61994-08-29 12:50:44 +0000609#ifdef WITH_THREAD
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610
611 /* Other threads may still be active, so skip most of the
612 cleanup actions usually done (these are mostly for
613 debugging anyway). */
614
Guido van Rossumdf72a651992-08-12 15:27:32 +0000615 (void) save_thread();
Guido van Rossuma110aa61994-08-29 12:50:44 +0000616#ifndef NO_EXIT_PROG
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000617 if (threads_started)
618 _exit_prog(sts);
619 else
620 exit_prog(sts);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000621#else /* !NO_EXIT_PROG */
622 if (threads_started)
623 _exit(sts);
624 else
625 exit(sts);
626#endif /* !NO_EXIT_PROG */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000627
Guido van Rossuma110aa61994-08-29 12:50:44 +0000628#else /* WITH_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000629
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000630 doneimport();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000631
632 err_clear();
633
634#ifdef REF_DEBUG
635 fprintf(stderr, "[%ld refs]\n", ref_total);
636#endif
637
638#ifdef TRACE_REFS
639 if (askyesno("Print left references?")) {
640 printrefs(stderr);
641 }
642#endif /* TRACE_REFS */
643
Guido van Rossum42a51241995-01-30 12:52:46 +0000644#ifdef THINK_C
645 if (sts == 0)
646 console_options.pause_atexit = 0;
647#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000648 exit(sts);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000649#endif /* WITH_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000650 /*NOTREACHED*/
651}
652
Guido van Rossuma110aa61994-08-29 12:50:44 +0000653#ifdef HAVE_SIGNAL_H
654static RETSIGTYPE
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000655sighandler(sig)
656 int sig;
657{
658 signal(sig, SIG_DFL); /* Don't catch recursive signals */
659 cleanup(); /* Do essential clean-up */
Guido van Rossuma110aa61994-08-29 12:50:44 +0000660#ifdef HAVE_GETPID
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000661 kill(getpid(), sig); /* Pretend the signal killed us */
Guido van Rossuma110aa61994-08-29 12:50:44 +0000662#else
663 exit(1);
664#endif
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000665 /*NOTREACHED*/
666}
667#endif
668
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000669static void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000670initsigs()
671{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000672 RETSIGTYPE (*t)();
673#ifdef HAVE_SIGNAL_H
674#ifdef SIGPIPE
675 signal(SIGPIPE, SIG_IGN);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000676#endif
Guido van Rossuma110aa61994-08-29 12:50:44 +0000677#ifdef SIGHUP
678 t = signal(SIGHUP, SIG_IGN);
679 if (t == SIG_DFL)
680 signal(SIGHUP, sighandler);
681 else
682 signal(SIGHUP, t);
683#endif
684#ifdef SIGTERM
685 t = signal(SIGTERM, SIG_IGN);
686 if (t == SIG_DFL)
687 signal(SIGTERM, sighandler);
688 else
689 signal(SIGTERM, t);
690#endif
691#endif /* HAVE_SIGNAL_H */
692 initintr(); /* May imply initsignal() */
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000693}
694
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000695#ifdef TRACE_REFS
696/* Ask a yes/no question */
697
Guido van Rossum59bff391992-09-03 20:28:00 +0000698int
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000699askyesno(prompt)
700 char *prompt;
701{
702 char buf[256];
703
704 printf("%s [ny] ", prompt);
705 if (fgets(buf, sizeof buf, stdin) == NULL)
706 return 0;
707 return buf[0] == 'y' || buf[0] == 'Y';
708}
709#endif
710
Guido van Rossuma110aa61994-08-29 12:50:44 +0000711#ifdef MPW
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000712
713/* Check for file descriptor connected to interactive device.
714 Pretend that stdin is always interactive, other files never. */
715
716int
717isatty(fd)
718 int fd;
719{
720 return fd == fileno(stdin);
721}
722
723#endif