1/* Python interpreter main program */
2
3#include "Python.h"
4#include "osdefs.h"
5
6#include <locale.h>
7
8#if defined(MS_WINDOWS) || defined(__CYGWIN__)
9#include <windows.h>
10#ifdef HAVE_IO_H
11#include <io.h>
12#endif
13#ifdef HAVE_FCNTL_H
14#include <fcntl.h>
15#endif
16#endif
17
18#ifdef _MSC_VER
19#include <crtdbg.h>
20#endif
21
22#if defined(MS_WINDOWS)
23#define PYTHONHOMEHELP "<prefix>\\lib"
24#else
25#define PYTHONHOMEHELP "<prefix>/pythonX.X"
26#endif
27
28#include "pygetopt.h"
29
30#define COPYRIGHT \
31    "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
32    "for more information."
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38/* For Py_GetArgcArgv(); set by main() */
39static wchar_t **orig_argv;
40static int  orig_argc;
41
42/* command line options */
43#define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
44
45#define PROGRAM_OPTS BASE_OPTS
46
47/* Short usage message (with %s for argv0) */
48static const char usage_line[] =
49"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
50
51/* Long usage message, split into parts < 512 bytes */
52static const char usage_1[] = "\
53Options and arguments (and corresponding environment variables):\n\
54-b     : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
55         and comparing bytes/bytearray with str. (-bb: issue errors)\n\
56-B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\
57-c cmd : program passed in as string (terminates option list)\n\
58-d     : debug output from parser; also PYTHONDEBUG=x\n\
59-E     : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
60-h     : print this help message and exit (also --help)\n\
61";
62static const char usage_2[] = "\
63-i     : inspect interactively after running script; forces a prompt even\n\
64         if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
65-I     : isolate Python from the user's environment (implies -E and -s)\n\
66-m mod : run library module as a script (terminates option list)\n\
67-O     : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
68-OO    : remove doc-strings in addition to the -O optimizations\n\
69-q     : don't print version and copyright messages on interactive startup\n\
70-s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
71-S     : don't imply 'import site' on initialization\n\
72";
73static const char usage_3[] = "\
74-u     : unbuffered binary stdout and stderr, stdin always buffered;\n\
75         also PYTHONUNBUFFERED=x\n\
76         see man page for details on internal buffering relating to '-u'\n\
77-v     : verbose (trace import statements); also PYTHONVERBOSE=x\n\
78         can be supplied multiple times to increase verbosity\n\
79-V     : print the Python version number and exit (also --version)\n\
80         when given twice, print more information about the build\n\
81-W arg : warning control; arg is action:message:category:module:lineno\n\
82         also PYTHONWARNINGS=arg\n\
83-x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
84-X opt : set implementation-specific option\n\
85";
86static const char usage_4[] = "\
87file   : program read from script file\n\
88-      : program read from stdin (default; interactive mode if a tty)\n\
89arg ...: arguments passed to program in sys.argv[1:]\n\n\
90Other environment variables:\n\
91PYTHONSTARTUP: file executed on interactive startup (no default)\n\
92PYTHONPATH   : '%lc'-separated list of directories prefixed to the\n\
93               default module search path.  The result is sys.path.\n\
94";
95static const char usage_5[] =
96"PYTHONHOME   : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
97"               The default module search path uses %s.\n"
98"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
99"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
100"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
101static const char usage_6[] =
102"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
103"   to seed the hashes of str, bytes and datetime objects.  It can also be\n"
104"   set to an integer in the range [0,4294967295] to get hash values with a\n"
105"   predictable seed.\n"
106"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
107"   on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
108"   hooks.\n";
109
110static int
111usage(int exitcode, const wchar_t* program)
112{
113    FILE *f = exitcode ? stderr : stdout;
114
115    fprintf(f, usage_line, program);
116    if (exitcode)
117        fprintf(f, "Try `python -h' for more information.\n");
118    else {
119        fputs(usage_1, f);
120        fputs(usage_2, f);
121        fputs(usage_3, f);
122        fprintf(f, usage_4, (wint_t)DELIM);
123        fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
124        fputs(usage_6, f);
125    }
126    return exitcode;
127}
128
129static void RunStartupFile(PyCompilerFlags *cf)
130{
131    char *startup = Py_GETENV("PYTHONSTARTUP");
132    if (startup != NULL && startup[0] != '\0') {
133        FILE *fp = _Py_fopen(startup, "r");
134        if (fp != NULL) {
135            (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
136            PyErr_Clear();
137            fclose(fp);
138        } else {
139            int save_errno;
140
141            save_errno = errno;
142            PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
143            errno = save_errno;
144            PyErr_SetFromErrnoWithFilename(PyExc_IOError,
145                            startup);
146            PyErr_Print();
147            PyErr_Clear();
148        }
149    }
150}
151
152static void RunInteractiveHook(void)
153{
154    PyObject *sys, *hook, *result;
155    sys = PyImport_ImportModule("sys");
156    if (sys == NULL)
157        goto error;
158    hook = PyObject_GetAttrString(sys, "__interactivehook__");
159    Py_DECREF(sys);
160    if (hook == NULL)
161        PyErr_Clear();
162    else {
163        result = PyObject_CallObject(hook, NULL);
164        Py_DECREF(hook);
165        if (result == NULL)
166            goto error;
167        else
168            Py_DECREF(result);
169    }
170    return;
171
172error:
173    PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
174    PyErr_Print();
175    PyErr_Clear();
176}
177
178
179static int RunModule(wchar_t *modname, int set_argv0)
180{
181    PyObject *module, *runpy, *runmodule, *runargs, *result;
182    runpy = PyImport_ImportModule("runpy");
183    if (runpy == NULL) {
184        fprintf(stderr, "Could not import runpy module\n");
185        PyErr_Print();
186        return -1;
187    }
188    runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
189    if (runmodule == NULL) {
190        fprintf(stderr, "Could not access runpy._run_module_as_main\n");
191        PyErr_Print();
192        Py_DECREF(runpy);
193        return -1;
194    }
195    module = PyUnicode_FromWideChar(modname, wcslen(modname));
196    if (module == NULL) {
197        fprintf(stderr, "Could not convert module name to unicode\n");
198        PyErr_Print();
199        Py_DECREF(runpy);
200        Py_DECREF(runmodule);
201        return -1;
202    }
203    runargs = Py_BuildValue("(Oi)", module, set_argv0);
204    if (runargs == NULL) {
205        fprintf(stderr,
206            "Could not create arguments for runpy._run_module_as_main\n");
207        PyErr_Print();
208        Py_DECREF(runpy);
209        Py_DECREF(runmodule);
210        Py_DECREF(module);
211        return -1;
212    }
213    result = PyObject_Call(runmodule, runargs, NULL);
214    if (result == NULL) {
215        PyErr_Print();
216    }
217    Py_DECREF(runpy);
218    Py_DECREF(runmodule);
219    Py_DECREF(module);
220    Py_DECREF(runargs);
221    if (result == NULL) {
222        return -1;
223    }
224    Py_DECREF(result);
225    return 0;
226}
227
228static PyObject *
229AsImportPathEntry(wchar_t *filename)
230{
231    PyObject *sys_path0 = NULL, *importer;
232
233    sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename));
234    if (sys_path0 == NULL)
235        goto error;
236
237    importer = PyImport_GetImporter(sys_path0);
238    if (importer == NULL)
239        goto error;
240
241    if (importer == Py_None) {
242        Py_DECREF(sys_path0);
243        Py_DECREF(importer);
244        return NULL;
245    }
246    Py_DECREF(importer);
247    return sys_path0;
248
249error:
250    Py_XDECREF(sys_path0);
251    PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n");
252    PyErr_Print();
253    PyErr_Clear();
254    return NULL;
255}
256
257
258static int
259RunMainFromImporter(PyObject *sys_path0)
260{
261    PyObject *sys_path;
262    int sts;
263
264    /* Assume sys_path0 has already been checked by AsImportPathEntry,
265     * so put it in sys.path[0] and import __main__ */
266    sys_path = PySys_GetObject("path");
267    if (sys_path == NULL) {
268        PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
269        goto error;
270    }
271    sts = PyList_Insert(sys_path, 0, sys_path0);
272    if (sts) {
273        sys_path0 = NULL;
274        goto error;
275    }
276
277    sts = RunModule(L"__main__", 0);
278    return sts != 0;
279
280error:
281    Py_XDECREF(sys_path0);
282    PyErr_Print();
283    return 1;
284}
285
286static int
287run_command(wchar_t *command, PyCompilerFlags *cf)
288{
289    PyObject *unicode, *bytes;
290    int ret;
291
292    unicode = PyUnicode_FromWideChar(command, -1);
293    if (unicode == NULL)
294        goto error;
295    bytes = PyUnicode_AsUTF8String(unicode);
296    Py_DECREF(unicode);
297    if (bytes == NULL)
298        goto error;
299    ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf);
300    Py_DECREF(bytes);
301    return ret != 0;
302
303error:
304    PySys_WriteStderr("Unable to decode the command from the command line:\n");
305    PyErr_Print();
306    return 1;
307}
308
309static int
310run_file(FILE *fp, const wchar_t *filename, PyCompilerFlags *p_cf)
311{
312    PyObject *unicode, *bytes = NULL;
313    char *filename_str;
314    int run;
315
316    /* call pending calls like signal handlers (SIGINT) */
317    if (Py_MakePendingCalls() == -1) {
318        PyErr_Print();
319        return 1;
320    }
321
322    if (filename) {
323        unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
324        if (unicode != NULL) {
325            bytes = PyUnicode_EncodeFSDefault(unicode);
326            Py_DECREF(unicode);
327        }
328        if (bytes != NULL)
329            filename_str = PyBytes_AsString(bytes);
330        else {
331            PyErr_Clear();
332            filename_str = "<encoding error>";
333        }
334    }
335    else
336        filename_str = "<stdin>";
337
338    run = PyRun_AnyFileExFlags(fp, filename_str, filename != NULL, p_cf);
339    Py_XDECREF(bytes);
340    return run != 0;
341}
342
343
344/* Main program */
345
346int
347Py_Main(int argc, wchar_t **argv)
348{
349    int c;
350    int sts;
351    wchar_t *command = NULL;
352    wchar_t *filename = NULL;
353    wchar_t *module = NULL;
354    FILE *fp = stdin;
355    char *p;
356#ifdef MS_WINDOWS
357    wchar_t *wp;
358#endif
359    int skipfirstline = 0;
360    int stdin_is_interactive = 0;
361    int help = 0;
362    int version = 0;
363    int saw_unbuffered_flag = 0;
364    char *opt;
365    PyCompilerFlags cf;
366    PyObject *main_importer_path = NULL;
367    PyObject *warning_option = NULL;
368    PyObject *warning_options = NULL;
369
370    cf.cf_flags = 0;
371
372    orig_argc = argc;           /* For Py_GetArgcArgv() */
373    orig_argv = argv;
374
375    /* Hash randomization needed early for all string operations
376       (including -W and -X options). */
377    _PyOS_opterr = 0;  /* prevent printing the error in 1st pass */
378    while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
379        if (c == 'm' || c == 'c') {
380            /* -c / -m is the last option: following arguments are
381               not interpreter options. */
382            break;
383        }
384        if (c == 'E') {
385            Py_IgnoreEnvironmentFlag++;
386            break;
387        }
388    }
389
390    opt = Py_GETENV("PYTHONMALLOC");
391    if (_PyMem_SetupAllocators(opt) < 0) {
392        fprintf(stderr,
393                "Error in PYTHONMALLOC: unknown allocator \"%s\"!\n", opt);
394        exit(1);
395    }
396
397    Py_HashRandomizationFlag = 1;
398    _PyRandom_Init();
399
400    PySys_ResetWarnOptions();
401    _PyOS_ResetGetOpt();
402
403    while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
404        if (c == 'c') {
405            size_t len;
406            /* -c is the last option; following arguments
407               that look like options are left for the
408               command to interpret. */
409
410            len = wcslen(_PyOS_optarg) + 1 + 1;
411            command = (wchar_t *)PyMem_RawMalloc(sizeof(wchar_t) * len);
412            if (command == NULL)
413                Py_FatalError(
414                   "not enough memory to copy -c argument");
415            wcscpy(command, _PyOS_optarg);
416            command[len - 2] = '\n';
417            command[len - 1] = 0;
418            break;
419        }
420
421        if (c == 'm') {
422            /* -m is the last option; following arguments
423               that look like options are left for the
424               module to interpret. */
425            module = _PyOS_optarg;
426            break;
427        }
428
429        switch (c) {
430        case 'b':
431            Py_BytesWarningFlag++;
432            break;
433
434        case 'd':
435            Py_DebugFlag++;
436            break;
437
438        case 'i':
439            Py_InspectFlag++;
440            Py_InteractiveFlag++;
441            break;
442
443        case 'I':
444            Py_IsolatedFlag++;
445            Py_NoUserSiteDirectory++;
446            Py_IgnoreEnvironmentFlag++;
447            break;
448
449        /* case 'J': reserved for Jython */
450
451        case 'O':
452            Py_OptimizeFlag++;
453            break;
454
455        case 'B':
456            Py_DontWriteBytecodeFlag++;
457            break;
458
459        case 's':
460            Py_NoUserSiteDirectory++;
461            break;
462
463        case 'S':
464            Py_NoSiteFlag++;
465            break;
466
467        case 'E':
468            /* Already handled above */
469            break;
470
471        case 't':
472            /* ignored for backwards compatibility */
473            break;
474
475        case 'u':
476            Py_UnbufferedStdioFlag = 1;
477            saw_unbuffered_flag = 1;
478            break;
479
480        case 'v':
481            Py_VerboseFlag++;
482            break;
483
484        case 'x':
485            skipfirstline = 1;
486            break;
487
488        case 'h':
489        case '?':
490            help++;
491            break;
492
493        case 'V':
494            version++;
495            break;
496
497        case 'W':
498            if (warning_options == NULL)
499                warning_options = PyList_New(0);
500            if (warning_options == NULL)
501                Py_FatalError("failure in handling of -W argument");
502            warning_option = PyUnicode_FromWideChar(_PyOS_optarg, -1);
503            if (warning_option == NULL)
504                Py_FatalError("failure in handling of -W argument");
505            if (PyList_Append(warning_options, warning_option) == -1)
506                Py_FatalError("failure in handling of -W argument");
507            Py_DECREF(warning_option);
508            break;
509
510        case 'X':
511            PySys_AddXOption(_PyOS_optarg);
512            break;
513
514        case 'q':
515            Py_QuietFlag++;
516            break;
517
518        case 'R':
519            /* Ignored */
520            break;
521
522        /* This space reserved for other options */
523
524        default:
525            return usage(2, argv[0]);
526            /*NOTREACHED*/
527
528        }
529    }
530
531    if (help)
532        return usage(0, argv[0]);
533
534    if (version) {
535        printf("Python %s\n", version >= 2 ? Py_GetVersion() : PY_VERSION);
536        return 0;
537    }
538
539    if (!Py_InspectFlag &&
540        (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
541        Py_InspectFlag = 1;
542    if (!saw_unbuffered_flag &&
543        (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
544        Py_UnbufferedStdioFlag = 1;
545
546    if (!Py_NoUserSiteDirectory &&
547        (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
548        Py_NoUserSiteDirectory = 1;
549
550#ifdef MS_WINDOWS
551    if (!Py_IgnoreEnvironmentFlag && (wp = _wgetenv(L"PYTHONWARNINGS")) &&
552        *wp != L'\0') {
553        wchar_t *buf, *warning, *context = NULL;
554
555        buf = (wchar_t *)PyMem_RawMalloc((wcslen(wp) + 1) * sizeof(wchar_t));
556        if (buf == NULL)
557            Py_FatalError(
558               "not enough memory to copy PYTHONWARNINGS");
559        wcscpy(buf, wp);
560        for (warning = wcstok_s(buf, L",", &context);
561             warning != NULL;
562             warning = wcstok_s(NULL, L",", &context)) {
563            PySys_AddWarnOption(warning);
564        }
565        PyMem_RawFree(buf);
566    }
567#else
568    if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
569        char *buf, *oldloc;
570        PyObject *unicode;
571
572        /* settle for strtok here as there's no one standard
573           C89 wcstok */
574        buf = (char *)PyMem_RawMalloc(strlen(p) + 1);
575        if (buf == NULL)
576            Py_FatalError(
577               "not enough memory to copy PYTHONWARNINGS");
578        strcpy(buf, p);
579        oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
580        setlocale(LC_ALL, "");
581        for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
582#ifdef __APPLE__
583            /* Use utf-8 on Mac OS X */
584            unicode = PyUnicode_FromString(p);
585#else
586            unicode = PyUnicode_DecodeLocale(p, "surrogateescape");
587#endif
588            if (unicode == NULL) {
589                /* ignore errors */
590                PyErr_Clear();
591                continue;
592            }
593            PySys_AddWarnOptionUnicode(unicode);
594            Py_DECREF(unicode);
595        }
596        setlocale(LC_ALL, oldloc);
597        PyMem_RawFree(oldloc);
598        PyMem_RawFree(buf);
599    }
600#endif
601    if (warning_options != NULL) {
602        Py_ssize_t i;
603        for (i = 0; i < PyList_GET_SIZE(warning_options); i++) {
604            PySys_AddWarnOptionUnicode(PyList_GET_ITEM(warning_options, i));
605        }
606    }
607
608    if (command == NULL && module == NULL && _PyOS_optind < argc &&
609        wcscmp(argv[_PyOS_optind], L"-") != 0)
610    {
611        filename = argv[_PyOS_optind];
612    }
613
614    stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
615
616#if defined(MS_WINDOWS) || defined(__CYGWIN__)
617    /* don't translate newlines (\r\n <=> \n) */
618    _setmode(fileno(stdin), O_BINARY);
619    _setmode(fileno(stdout), O_BINARY);
620    _setmode(fileno(stderr), O_BINARY);
621#endif
622
623    if (Py_UnbufferedStdioFlag) {
624#ifdef HAVE_SETVBUF
625        setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
626        setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
627        setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
628#else /* !HAVE_SETVBUF */
629        setbuf(stdin,  (char *)NULL);
630        setbuf(stdout, (char *)NULL);
631        setbuf(stderr, (char *)NULL);
632#endif /* !HAVE_SETVBUF */
633    }
634    else if (Py_InteractiveFlag) {
635#ifdef MS_WINDOWS
636        /* Doesn't have to have line-buffered -- use unbuffered */
637        /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
638        setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
639#else /* !MS_WINDOWS */
640#ifdef HAVE_SETVBUF
641        setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
642        setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
643#endif /* HAVE_SETVBUF */
644#endif /* !MS_WINDOWS */
645        /* Leave stderr alone - it should be unbuffered anyway. */
646    }
647
648#ifdef __APPLE__
649    /* On MacOS X, when the Python interpreter is embedded in an
650       application bundle, it gets executed by a bootstrapping script
651       that does os.execve() with an argv[0] that's different from the
652       actual Python executable. This is needed to keep the Finder happy,
653       or rather, to work around Apple's overly strict requirements of
654       the process name. However, we still need a usable sys.executable,
655       so the actual executable path is passed in an environment variable.
656       See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
657       script. */
658    if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
659        wchar_t* buffer;
660        size_t len = strlen(p) + 1;
661
662        buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
663        if (buffer == NULL) {
664            Py_FatalError(
665               "not enough memory to copy PYTHONEXECUTABLE");
666        }
667
668        mbstowcs(buffer, p, len);
669        Py_SetProgramName(buffer);
670        /* buffer is now handed off - do not free */
671    } else {
672#ifdef WITH_NEXT_FRAMEWORK
673        char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
674
675        if (pyvenv_launcher && *pyvenv_launcher) {
676            /* Used by Mac/Tools/pythonw.c to forward
677             * the argv0 of the stub executable
678             */
679            wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, NULL);
680
681            if (wbuf == NULL) {
682                Py_FatalError("Cannot decode __PYVENV_LAUNCHER__");
683            }
684            Py_SetProgramName(wbuf);
685
686            /* Don't free wbuf, the argument to Py_SetProgramName
687             * must remain valid until Py_FinalizeEx is called.
688             */
689        } else {
690            Py_SetProgramName(argv[0]);
691        }
692#else
693        Py_SetProgramName(argv[0]);
694#endif
695    }
696#else
697    Py_SetProgramName(argv[0]);
698#endif
699    Py_Initialize();
700    Py_XDECREF(warning_options);
701
702    if (!Py_QuietFlag && (Py_VerboseFlag ||
703                        (command == NULL && filename == NULL &&
704                         module == NULL && stdin_is_interactive))) {
705        fprintf(stderr, "Python %s on %s\n",
706            Py_GetVersion(), Py_GetPlatform());
707        if (!Py_NoSiteFlag)
708            fprintf(stderr, "%s\n", COPYRIGHT);
709    }
710
711    if (command != NULL) {
712        /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
713        _PyOS_optind--;
714        argv[_PyOS_optind] = L"-c";
715    }
716
717    if (module != NULL) {
718        /* Backup _PyOS_optind and force sys.argv[0] = '-m'*/
719        _PyOS_optind--;
720        argv[_PyOS_optind] = L"-m";
721    }
722
723    if (filename != NULL) {
724        main_importer_path = AsImportPathEntry(filename);
725    }
726
727    if (main_importer_path != NULL) {
728        /* Let RunMainFromImporter adjust sys.path[0] later */
729        PySys_SetArgvEx(argc-_PyOS_optind, argv+_PyOS_optind, 0);
730    } else {
731        /* Use config settings to decide whether or not to update sys.path[0] */
732        PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
733    }
734
735    if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) &&
736        isatty(fileno(stdin)) &&
737        !Py_IsolatedFlag) {
738        PyObject *v;
739        v = PyImport_ImportModule("readline");
740        if (v == NULL)
741            PyErr_Clear();
742        else
743            Py_DECREF(v);
744    }
745
746    if (command) {
747        sts = run_command(command, &cf);
748        PyMem_RawFree(command);
749    } else if (module) {
750        sts = (RunModule(module, 1) != 0);
751    }
752    else {
753
754        if (filename == NULL && stdin_is_interactive) {
755            Py_InspectFlag = 0; /* do exit on SystemExit */
756            RunStartupFile(&cf);
757            RunInteractiveHook();
758        }
759        /* XXX */
760
761        sts = -1;               /* keep track of whether we've already run __main__ */
762
763        if (main_importer_path != NULL) {
764            sts = RunMainFromImporter(main_importer_path);
765        }
766
767        if (sts==-1 && filename != NULL) {
768            fp = _Py_wfopen(filename, L"r");
769            if (fp == NULL) {
770                char *cfilename_buffer;
771                const char *cfilename;
772                int err = errno;
773                cfilename_buffer = Py_EncodeLocale(filename, NULL);
774                if (cfilename_buffer != NULL)
775                    cfilename = cfilename_buffer;
776                else
777                    cfilename = "<unprintable file name>";
778                fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
779                    argv[0], cfilename, err, strerror(err));
780                if (cfilename_buffer)
781                    PyMem_Free(cfilename_buffer);
782                return 2;
783            }
784            else if (skipfirstline) {
785                int ch;
786                /* Push back first newline so line numbers
787                   remain the same */
788                while ((ch = getc(fp)) != EOF) {
789                    if (ch == '\n') {
790                        (void)ungetc(ch, fp);
791                        break;
792                    }
793                }
794            }
795            {
796                struct _Py_stat_struct sb;
797                if (_Py_fstat_noraise(fileno(fp), &sb) == 0 &&
798                    S_ISDIR(sb.st_mode)) {
799                    fprintf(stderr,
800                            "%ls: '%ls' is a directory, cannot continue\n",
801                            argv[0], filename);
802                    fclose(fp);
803                    return 1;
804                }
805            }
806        }
807
808        if (sts == -1)
809            sts = run_file(fp, filename, &cf);
810    }
811
812    /* Check this environment variable at the end, to give programs the
813     * opportunity to set it from Python.
814     */
815    if (!Py_InspectFlag &&
816        (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
817    {
818        Py_InspectFlag = 1;
819    }
820
821    if (Py_InspectFlag && stdin_is_interactive &&
822        (filename != NULL || command != NULL || module != NULL)) {
823        Py_InspectFlag = 0;
824        RunInteractiveHook();
825        /* XXX */
826        sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
827    }
828
829    if (Py_FinalizeEx() < 0) {
830        /* Value unlikely to be confused with a non-error exit status or
831        other special meaning */
832        sts = 120;
833    }
834
835#ifdef __INSURE__
836    /* Insure++ is a memory analysis tool that aids in discovering
837     * memory leaks and other memory problems.  On Python exit, the
838     * interned string dictionaries are flagged as being in use at exit
839     * (which it is).  Under normal circumstances, this is fine because
840     * the memory will be automatically reclaimed by the system.  Under
841     * memory debugging, it's a huge source of useless noise, so we
842     * trade off slower shutdown for less distraction in the memory
843     * reports.  -baw
844     */
845    _Py_ReleaseInternedUnicodeStrings();
846#endif /* __INSURE__ */
847
848    return sts;
849}
850
851/* this is gonna seem *real weird*, but if you put some other code between
852   Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
853   while statement in Misc/gdbinit:ppystack */
854
855/* Make the *original* argc/argv available to other modules.
856   This is rare, but it is needed by the secureware extension. */
857
858void
859Py_GetArgcArgv(int *argc, wchar_t ***argv)
860{
861    *argc = orig_argc;
862    *argv = orig_argv;
863}
864
865#ifdef __cplusplus
866}
867#endif
868