blob: 734b72b0c4480782dc3c9db41ef10ce932fac86f [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
Jack Jansen08e767b1995-02-02 14:30:20 +000051#ifdef __MWERKS__
52#include <SIOUX.h>
53#endif
54
Guido van Rossuma44823b1995-03-14 15:01:17 +000055#ifdef NT
56#undef BYTE
57#include "windows.h"
58#endif
59
Guido van Rossum1984f1e1992-08-04 12:41:02 +000060extern char *getpythonpath();
61
62extern grammar gram; /* From graminit.c */
63
Guido van Rossumb73cc041993-11-01 16:28:59 +000064/* Forward */
Guido van Rossum6135a871995-01-09 17:53:26 +000065static void initmain PROTO((void));
Guido van Rossuma110aa61994-08-29 12:50:44 +000066static object *run_err_node PROTO((node *n, char *filename,
Guido van Rossumb73cc041993-11-01 16:28:59 +000067 object *globals, object *locals));
68static object *run_node PROTO((node *n, char *filename,
69 object *globals, object *locals));
Guido van Rossum262e1241995-02-07 15:30:45 +000070static object *run_pyc_file PROTO((FILE *fp, char *filename,
71 object *globals, object *locals));
Guido van Rossuma110aa61994-08-29 12:50:44 +000072static void err_input PROTO((perrdetail *));
Guido van Rossumb376a4a1993-11-23 17:53:17 +000073static void initsigs PROTO((void));
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000074
Guido van Rossum1984f1e1992-08-04 12:41:02 +000075int debugging; /* Needed by parser.c */
76int verbose; /* Needed by import.c */
Guido van Rossuma110aa61994-08-29 12:50:44 +000077int suppress_print; /* Needed by ceval.c */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000078
79/* Initialize all */
80
81void
82initall()
83{
84 static int inited;
85
86 if (inited)
87 return;
88 inited = 1;
89
90 initimport();
91
Guido van Rossuma110aa61994-08-29 12:50:44 +000092 /* Modules '__builtin__' and 'sys' are initialized here,
Guido van Rossum1984f1e1992-08-04 12:41:02 +000093 they are needed by random bits of the interpreter.
94 All other modules are optional and are initialized
95 when they are first imported. */
96
97 initbuiltin(); /* Also initializes builtin exceptions */
98 initsys();
Guido van Rossum1984f1e1992-08-04 12:41:02 +000099
100 setpythonpath(getpythonpath());
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000101
102 initsigs(); /* Signal handling stuff, including initintr() */
Guido van Rossum6135a871995-01-09 17:53:26 +0000103
104 initmain();
105}
106
107/* Create __main__ module */
108
109static void
110initmain()
111{
112 object *m, *d;
113 m = add_module("__main__");
114 if (m == NULL)
115 fatal("can't create __main__ module");
116 d = getmoduledict(m);
117 if (dictlookup(d, "__builtins__") == NULL) {
Guido van Rossum94390ec1995-01-12 11:37:57 +0000118 if (dictinsert(d, "__builtins__", getbuiltins()))
Guido van Rossum6135a871995-01-09 17:53:26 +0000119 fatal("can't add __builtins__ to __main__");
120 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000121}
122
123/* Parse input from a file and execute it */
124
125int
126run(fp, filename)
127 FILE *fp;
128 char *filename;
129{
130 if (filename == NULL)
131 filename = "???";
132 if (isatty((int)fileno(fp)))
133 return run_tty_loop(fp, filename);
134 else
135 return run_script(fp, filename);
136}
137
138int
139run_tty_loop(fp, filename)
140 FILE *fp;
141 char *filename;
142{
143 object *v;
144 int ret;
145 v = sysget("ps1");
146 if (v == NULL) {
147 sysset("ps1", v = newstringobject(">>> "));
148 XDECREF(v);
149 }
150 v = sysget("ps2");
151 if (v == NULL) {
152 sysset("ps2", v = newstringobject("... "));
153 XDECREF(v);
154 }
155 for (;;) {
156 ret = run_tty_1(fp, filename);
157#ifdef REF_DEBUG
Guido van Rossum6f9e4331995-03-29 16:57:48 +0000158 fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000159#endif
160 if (ret == E_EOF)
161 return 0;
162 /*
163 if (ret == E_NOMEM)
164 return -1;
165 */
166 }
167}
168
169int
170run_tty_1(fp, filename)
171 FILE *fp;
172 char *filename;
173{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000174 object *m, *d, *v, *w;
175 node *n;
Guido van Rossuma110aa61994-08-29 12:50:44 +0000176 perrdetail err;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000177 char *ps1, *ps2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000178 v = sysget("ps1");
179 w = sysget("ps2");
180 if (v != NULL && is_stringobject(v)) {
181 INCREF(v);
182 ps1 = getstringvalue(v);
183 }
184 else {
185 v = NULL;
186 ps1 = "";
187 }
188 if (w != NULL && is_stringobject(w)) {
189 INCREF(w);
190 ps2 = getstringvalue(w);
191 }
192 else {
193 w = NULL;
194 ps2 = "";
195 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 BGN_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000197 n = parsefile(fp, filename, &gram, single_input, ps1, ps2, &err);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000199 XDECREF(v);
200 XDECREF(w);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000201 if (n == NULL) {
202 if (err.error == E_EOF) {
203 if (err.text)
204 free(err.text);
205 return E_EOF;
206 }
207 err_input(&err);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000208 print_error();
Guido van Rossuma110aa61994-08-29 12:50:44 +0000209 return err.error;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000210 }
211 m = add_module("__main__");
212 if (m == NULL)
213 return -1;
214 d = getmoduledict(m);
215 v = run_node(n, filename, d, d);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000216 if (v == NULL) {
217 print_error();
218 return -1;
219 }
220 DECREF(v);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000221 flushline();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000222 return 0;
223}
224
225int
226run_script(fp, filename)
227 FILE *fp;
228 char *filename;
229{
230 object *m, *d, *v;
Guido van Rossumfdef2711994-09-14 13:31:04 +0000231 char *ext;
232
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000233 m = add_module("__main__");
234 if (m == NULL)
235 return -1;
236 d = getmoduledict(m);
Guido van Rossumfdef2711994-09-14 13:31:04 +0000237 ext = filename + strlen(filename) - 4;
Jack Jansenbd06e961995-02-13 11:44:56 +0000238#ifdef macintosh
239 /* On a mac, we also assume a pyc file for types 'PYC ' and 'APPL' */
240 if ( strcmp(ext, ".pyc") == 0 || getfiletype(filename) == 'PYC ' ||
241 getfiletype(filename) == 'APPL' ) {
242#else
Guido van Rossumfdef2711994-09-14 13:31:04 +0000243 if ( strcmp(ext, ".pyc") == 0 ) {
Jack Jansenbd06e961995-02-13 11:44:56 +0000244#endif /* macintosh */
Guido van Rossumfdef2711994-09-14 13:31:04 +0000245 /* Try to run a pyc file. First, re-open in binary */
Jack Jansene00637b1994-12-14 12:58:37 +0000246 /* Don't close, done in main: fclose(fp); */
Guido van Rossumfdef2711994-09-14 13:31:04 +0000247 if( (fp = fopen(filename, "rb")) == NULL ) {
248 fprintf(stderr, "python: Can't reopen .pyc file\n");
249 return -1;
250 }
251 v = run_pyc_file(fp, filename, d, d);
252 } else {
253 v = run_file(fp, filename, file_input, d, d);
254 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000255 if (v == NULL) {
256 print_error();
257 return -1;
258 }
259 DECREF(v);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000260 flushline();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000261 return 0;
262}
263
264int
265run_command(command)
266 char *command;
267{
268 object *m, *d, *v;
269 m = add_module("__main__");
270 if (m == NULL)
271 return -1;
272 d = getmoduledict(m);
273 v = run_string(command, file_input, d, d);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000274 if (v == NULL) {
275 print_error();
276 return -1;
277 }
278 DECREF(v);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000279 flushline();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000280 return 0;
281}
282
283void
284print_error()
285{
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000286 object *exception, *v, *tb, *f;
287 err_fetch(&exception, &v, &tb);
Guido van Rossum6d023c91995-01-04 19:12:13 +0000288 flushline();
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000289 if (exception == NULL)
290 fatal("print_error called but no exception");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000291 if (exception == SystemExit) {
292 if (v == NULL || v == None)
293 goaway(0);
294 if (is_intobject(v))
295 goaway((int)getintvalue(v));
296 else {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000297 /* OK to use real stderr here */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000298 printobject(v, stderr, PRINT_RAW);
299 fprintf(stderr, "\n");
300 goaway(1);
301 }
302 }
303 sysset("last_type", exception);
304 sysset("last_value", v);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000305 sysset("last_traceback", tb);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000306 f = sysget("stderr");
307 if (f == NULL)
308 fprintf(stderr, "lost sys.stderr\n");
309 else {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000310 tb_print(tb, f);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000311 if (exception == SyntaxError) {
312 object *message;
313 char *filename, *text;
314 int lineno, offset;
315 if (!getargs(v, "(O(ziiz))", &message,
316 &filename, &lineno, &offset, &text))
317 err_clear();
318 else {
319 char buf[10];
320 writestring(" File \"", f);
321 if (filename == NULL)
322 writestring("<string>", f);
323 else
324 writestring(filename, f);
325 writestring("\", line ", f);
326 sprintf(buf, "%d", lineno);
327 writestring(buf, f);
328 writestring("\n", f);
329 if (text != NULL) {
Guido van Rossum798199d1994-09-19 08:08:50 +0000330 char *nl;
331 if (offset > 0 &&
332 offset == strlen(text))
333 offset--;
334 for (;;) {
335 nl = strchr(text, '\n');
336 if (nl == NULL ||
337 nl-text >= offset)
338 break;
339 offset -= (nl+1-text);
340 text = nl+1;
341 }
Guido van Rossuma110aa61994-08-29 12:50:44 +0000342 while (*text == ' ' || *text == '\t') {
343 text++;
344 offset--;
345 }
346 writestring(" ", f);
347 writestring(text, f);
348 if (*text == '\0' ||
349 text[strlen(text)-1] != '\n')
350 writestring("\n", f);
351 writestring(" ", f);
352 offset--;
353 while (offset > 0) {
354 writestring(" ", f);
355 offset--;
356 }
357 writestring("^\n", f);
358 }
359 INCREF(message);
360 DECREF(v);
361 v = message;
362 }
363 }
Guido van Rossum262e1241995-02-07 15:30:45 +0000364 if (is_classobject(exception)) {
365 object* className = ((classobject*)exception)->cl_name;
366 if (className == NULL)
367 writestring("<unknown>", f);
368 else {
369 if (writeobject(className, f, PRINT_RAW) != 0)
370 err_clear();
371 }
372 } else {
373 if (writeobject(exception, f, PRINT_RAW) != 0)
374 err_clear();
375 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000376 if (v != NULL && v != None) {
377 writestring(": ", f);
378 if (writeobject(v, f, PRINT_RAW) != 0)
379 err_clear();
380 }
381 writestring("\n", f);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000382 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000383 XDECREF(exception);
384 XDECREF(v);
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000385 XDECREF(tb);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000386}
387
388object *
389run_string(str, start, globals, locals)
390 char *str;
391 int start;
Guido van Rossum5b722181993-03-30 17:46:03 +0000392 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000393{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000394 return run_err_node(parse_string(str, start),
395 "<string>", globals, locals);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000396}
397
398object *
399run_file(fp, filename, start, globals, locals)
400 FILE *fp;
401 char *filename;
402 int start;
Guido van Rossum5b722181993-03-30 17:46:03 +0000403 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000404{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000405 return run_err_node(parse_file(fp, filename, start),
406 filename, globals, locals);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000407}
408
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000409static object *
Guido van Rossuma110aa61994-08-29 12:50:44 +0000410run_err_node(n, filename, globals, locals)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000411 node *n;
412 char *filename;
Guido van Rossum5b722181993-03-30 17:46:03 +0000413 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000414{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000415 if (n == NULL)
416 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000417 return run_node(n, filename, globals, locals);
418}
419
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000420static object *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000421run_node(n, filename, globals, locals)
422 node *n;
423 char *filename;
Guido van Rossum5b722181993-03-30 17:46:03 +0000424 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000425{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000426 codeobject *co;
427 object *v;
428 co = compile(n, filename);
429 freetree(n);
430 if (co == NULL)
431 return NULL;
Guido van Rossum81daa321993-05-20 14:24:46 +0000432 v = eval_code(co, globals, locals, (object *)NULL, (object *)NULL);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000433 DECREF(co);
434 return v;
435}
436
Guido van Rossum8ae87c01995-01-26 00:40:38 +0000437static object *
Guido van Rossumfdef2711994-09-14 13:31:04 +0000438run_pyc_file(fp, filename, globals, locals)
439 FILE *fp;
440 char *filename;
441 object *globals, *locals;
442{
443 codeobject *co;
444 object *v;
445 long magic;
446 long get_pyc_magic();
447
448 magic = rd_long(fp);
449 if (magic != get_pyc_magic()) {
450 err_setstr(RuntimeError,
451 "Bad magic number in .pyc file");
452 return NULL;
453 }
454 (void) rd_long(fp);
455 v = rd_object(fp);
456 fclose(fp);
457 if (v == NULL || !is_codeobject(v)) {
458 XDECREF(v);
459 err_setstr(RuntimeError,
460 "Bad code object in .pyc file");
461 return NULL;
462 }
463 co = (codeobject *)v;
464 v = eval_code(co, globals, locals, (object *)NULL, (object *)NULL);
465 DECREF(co);
466 return v;
467}
468
469object *
Guido van Rossum5b722181993-03-30 17:46:03 +0000470compile_string(str, filename, start)
471 char *str;
472 char *filename;
473 int start;
474{
475 node *n;
Guido van Rossum5b722181993-03-30 17:46:03 +0000476 codeobject *co;
Guido van Rossuma110aa61994-08-29 12:50:44 +0000477 n = parse_string(str, start);
478 if (n == NULL)
Guido van Rossum5b722181993-03-30 17:46:03 +0000479 return NULL;
Guido van Rossum5b722181993-03-30 17:46:03 +0000480 co = compile(n, filename);
481 freetree(n);
482 return (object *)co;
483}
484
Guido van Rossuma110aa61994-08-29 12:50:44 +0000485/* Simplified interface to parsefile -- return node or set exception */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000486
Guido van Rossuma110aa61994-08-29 12:50:44 +0000487node *
488parse_file(fp, filename, start)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000489 FILE *fp;
490 char *filename;
491 int start;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000492{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000493 node *n;
494 perrdetail err;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 BGN_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000496 n = parsefile(fp, filename, &gram, start,
497 (char *)0, (char *)0, &err);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000498 END_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000499 if (n == NULL)
500 err_input(&err);
501 return n;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000502}
503
Guido van Rossuma110aa61994-08-29 12:50:44 +0000504/* Simplified interface to parsestring -- return node or set exception */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000505
Guido van Rossuma110aa61994-08-29 12:50:44 +0000506node *
507parse_string(str, start)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000508 char *str;
509 int start;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000510{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000511 node *n;
512 perrdetail err;
513 n = parsestring(str, &gram, start, &err);
514 if (n == NULL)
515 err_input(&err);
516 return n;
517}
518
519/* Set the error appropriate to the given input error code (see errcode.h) */
520
521static void
522err_input(err)
523 perrdetail *err;
524{
525 object *v, *w;
526 char *msg = NULL;
527 v = mkvalue("(ziiz)", err->filename,
528 err->lineno, err->offset, err->text);
529 if (err->text != NULL) {
530 free(err->text);
531 err->text = NULL;
532 }
533 switch (err->error) {
534 case E_SYNTAX:
535 msg = "invalid syntax";
536 break;
537 case E_TOKEN:
538 msg = "invalid token";
539
540 break;
541 case E_INTR:
542 err_set(KeyboardInterrupt);
543 return;
544 case E_NOMEM:
545 err_nomem();
546 return;
547 case E_EOF:
548 msg = "unexpected EOF while parsing";
549 break;
550 default:
551 fprintf(stderr, "error=%d\n", err->error);
552 msg = "unknown parsing error";
553 break;
554 }
555 w = mkvalue("(sO)", msg, v);
556 XDECREF(v);
557 err_setval(SyntaxError, w);
558 XDECREF(w);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559}
560
561/* Print fatal error message and abort */
562
563void
564fatal(msg)
565 char *msg;
566{
Guido van Rossum83dd6c31994-09-29 09:38:33 +0000567 fprintf(stderr, "Fatal Python error: %s\n", msg);
Guido van Rossum8ae87c01995-01-26 00:40:38 +0000568#ifdef macintosh
569 for (;;);
570#endif
Guido van Rossuma44823b1995-03-14 15:01:17 +0000571#ifdef NT
572 OutputDebugString("Fatal Python error:");
573 OutputDebugString(msg);
574 OutputDebugString("\n");
575#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000576 abort();
577}
578
579/* Clean up and exit */
580
Guido van Rossuma110aa61994-08-29 12:50:44 +0000581#ifdef WITH_THREAD
582#include "thread.h"
583int threads_started = 0; /* Set by threadmodule.c and maybe others */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000584#endif
585
Guido van Rossum1662dd51994-09-07 14:38:28 +0000586#define NEXITFUNCS 32
587static void (*exitfuncs[NEXITFUNCS])();
588static int nexitfuncs = 0;
589
590int Py_AtExit(func)
591 void (*func) PROTO((void));
592{
593 if (nexitfuncs >= NEXITFUNCS)
594 return -1;
595 exitfuncs[nexitfuncs++] = func;
596 return 0;
597}
598
Guido van Rossuma110aa61994-08-29 12:50:44 +0000599void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000600cleanup()
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000601{
Guido van Rossum59bff391992-09-03 20:28:00 +0000602 object *exitfunc = sysget("exitfunc");
603
604 if (exitfunc) {
605 object *arg;
606 object *res;
607 sysset("exitfunc", (object *)NULL);
608 arg = newtupleobject(0);
609 if (arg == NULL)
610 res = NULL;
611 else {
612 res = call_object(exitfunc, arg);
613 DECREF(arg);
614 }
615 if (res == NULL) {
616 fprintf(stderr, "Error in sys.exitfunc:\n");
617 print_error();
618 }
619 }
620
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000621 flushline();
Guido van Rossum1662dd51994-09-07 14:38:28 +0000622
623 while (nexitfuncs > 0)
624 (*exitfuncs[--nexitfuncs])();
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000625}
626
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000627#ifdef COUNT_ALLOCS
628extern void dump_counts PROTO((void));
629#endif
630
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000631void
632goaway(sts)
633 int sts;
634{
635 cleanup();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000636
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000637#ifdef COUNT_ALLOCS
638 dump_counts();
639#endif
640
Guido van Rossuma110aa61994-08-29 12:50:44 +0000641#ifdef WITH_THREAD
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642
643 /* Other threads may still be active, so skip most of the
644 cleanup actions usually done (these are mostly for
645 debugging anyway). */
646
Guido van Rossumdf72a651992-08-12 15:27:32 +0000647 (void) save_thread();
Guido van Rossuma110aa61994-08-29 12:50:44 +0000648#ifndef NO_EXIT_PROG
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000649 if (threads_started)
650 _exit_prog(sts);
651 else
652 exit_prog(sts);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000653#else /* !NO_EXIT_PROG */
654 if (threads_started)
655 _exit(sts);
656 else
657 exit(sts);
658#endif /* !NO_EXIT_PROG */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000659
Guido van Rossuma110aa61994-08-29 12:50:44 +0000660#else /* WITH_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000661
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000662 doneimport();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000663
664 err_clear();
665
666#ifdef REF_DEBUG
Guido van Rossum6f9e4331995-03-29 16:57:48 +0000667 fprintf(stderr, "[%ld refs]\n", _Py_RefTotal);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000668#endif
669
670#ifdef TRACE_REFS
671 if (askyesno("Print left references?")) {
672 printrefs(stderr);
673 }
674#endif /* TRACE_REFS */
675
Jack Jansen08e767b1995-02-02 14:30:20 +0000676 /* XXXX Jack thinks it would be nicer to pause if any output has
677 ** been generated since the last interaction with the user...
678 */
Guido van Rossum42a51241995-01-30 12:52:46 +0000679#ifdef THINK_C
680 if (sts == 0)
681 console_options.pause_atexit = 0;
682#endif
Jack Jansen08e767b1995-02-02 14:30:20 +0000683#ifdef __MWERKS__
684 if (sts == 0)
685 SIOUXSettings.autocloseonquit = 1;
Jack Jansenbd06e961995-02-13 11:44:56 +0000686 else
687 SIOUXSettings.showstatusline = 1;
Jack Jansen08e767b1995-02-02 14:30:20 +0000688#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000689 exit(sts);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000690#endif /* WITH_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000691 /*NOTREACHED*/
692}
693
Guido van Rossuma110aa61994-08-29 12:50:44 +0000694#ifdef HAVE_SIGNAL_H
695static RETSIGTYPE
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000696sighandler(sig)
697 int sig;
698{
699 signal(sig, SIG_DFL); /* Don't catch recursive signals */
700 cleanup(); /* Do essential clean-up */
Guido van Rossuma110aa61994-08-29 12:50:44 +0000701#ifdef HAVE_GETPID
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000702 kill(getpid(), sig); /* Pretend the signal killed us */
Guido van Rossuma110aa61994-08-29 12:50:44 +0000703#else
704 exit(1);
705#endif
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000706 /*NOTREACHED*/
707}
708#endif
709
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000710static void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000711initsigs()
712{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000713 RETSIGTYPE (*t)();
714#ifdef HAVE_SIGNAL_H
715#ifdef SIGPIPE
716 signal(SIGPIPE, SIG_IGN);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000717#endif
Guido van Rossuma110aa61994-08-29 12:50:44 +0000718#ifdef SIGHUP
719 t = signal(SIGHUP, SIG_IGN);
720 if (t == SIG_DFL)
721 signal(SIGHUP, sighandler);
722 else
723 signal(SIGHUP, t);
724#endif
725#ifdef SIGTERM
726 t = signal(SIGTERM, SIG_IGN);
727 if (t == SIG_DFL)
728 signal(SIGTERM, sighandler);
729 else
730 signal(SIGTERM, t);
731#endif
732#endif /* HAVE_SIGNAL_H */
733 initintr(); /* May imply initsignal() */
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000734}
735
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000736#ifdef TRACE_REFS
737/* Ask a yes/no question */
738
Guido van Rossum59bff391992-09-03 20:28:00 +0000739int
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000740askyesno(prompt)
741 char *prompt;
742{
743 char buf[256];
744
745 printf("%s [ny] ", prompt);
746 if (fgets(buf, sizeof buf, stdin) == NULL)
747 return 0;
748 return buf[0] == 'y' || buf[0] == 'Y';
749}
750#endif
751
Guido van Rossuma110aa61994-08-29 12:50:44 +0000752#ifdef MPW
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000753
754/* Check for file descriptor connected to interactive device.
755 Pretend that stdin is always interactive, other files never. */
756
757int
758isatty(fd)
759 int fd;
760{
761 return fd == fileno(stdin);
762}
763
764#endif