diff options
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 1573 | 
1 files changed, 17 insertions, 1556 deletions
| diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 9b2405f..ebedd12 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -15,6 +15,7 @@  #include "ast.h"  #include "marshal.h"  #include "osdefs.h" +#include <locale.h>  #ifdef HAVE_SIGNAL_H  #include <signal.h> @@ -25,18 +26,12 @@  #endif  #ifdef HAVE_LANGINFO_H -#include <locale.h>  #include <langinfo.h>  #endif  #ifdef MS_WINDOWS  #undef BYTE  #include "windows.h" -#define PATH_MAX MAXPATHLEN -#endif - -#ifdef __gnu_hurd__ -#define PATH_MAX MAXPATHLEN  #endif  _Py_IDENTIFIER(builtins); @@ -45,7 +40,6 @@ _Py_IDENTIFIER(flush);  _Py_IDENTIFIER(last_traceback);  _Py_IDENTIFIER(last_type);  _Py_IDENTIFIER(last_value); -_Py_IDENTIFIER(name);  _Py_IDENTIFIER(ps1);  _Py_IDENTIFIER(ps2);  _Py_IDENTIFIER(stdin); @@ -53,43 +47,13 @@ _Py_IDENTIFIER(stdout);  _Py_IDENTIFIER(stderr);  _Py_static_string(PyId_string, "<string>"); -#ifdef Py_REF_DEBUG -static -void _print_total_refs(void) { -    PyObject *xoptions, *value; -    _Py_IDENTIFIER(showrefcount); - -    xoptions = PySys_GetXOptions(); -    if (xoptions == NULL) -        return; -    value = _PyDict_GetItemId(xoptions, &PyId_showrefcount); -    if (value == Py_True) -        fprintf(stderr, -                "[%" PY_FORMAT_SIZE_T "d refs, " -                "%" PY_FORMAT_SIZE_T "d blocks]\n", -                _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); -} -#endif - -#ifndef Py_REF_DEBUG -#define PRINT_TOTAL_REFS() -#else /* Py_REF_DEBUG */ -#define PRINT_TOTAL_REFS() _print_total_refs() -#endif -  #ifdef __cplusplus  extern "C" {  #endif -extern wchar_t *Py_GetPath(void); -  extern grammar _PyParser_Grammar; /* From graminit.c */  /* Forward */ -static void initmain(PyInterpreterState *interp); -static int initfsencoding(PyInterpreterState *interp); -static void initsite(void); -static int initstdio(void);  static void flush_io(void);  static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *,                            PyCompilerFlags *, PyArena *); @@ -97,1182 +61,6 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,                                PyCompilerFlags *);  static void err_input(perrdetail *);  static void err_free(perrdetail *); -static void initsigs(void); -static void call_py_exitfuncs(void); -static void wait_for_thread_shutdown(void); -static void call_ll_exitfuncs(void); -extern int _PyUnicode_Init(void); -extern int _PyStructSequence_Init(void); -extern void _PyUnicode_Fini(void); -extern int _PyLong_Init(void); -extern void PyLong_Fini(void); -extern int _PyFaulthandler_Init(void); -extern void _PyFaulthandler_Fini(void); -extern void _PyHash_Fini(void); -extern int _PyTraceMalloc_Init(void); -extern int _PyTraceMalloc_Fini(void); - -#ifdef WITH_THREAD -extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); -extern void _PyGILState_Fini(void); -#endif /* WITH_THREAD */ - -int Py_DebugFlag; /* Needed by parser.c */ -int Py_VerboseFlag; /* Needed by import.c */ -int Py_QuietFlag; /* Needed by sysmodule.c */ -int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ -int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */ -int Py_NoSiteFlag; /* Suppress 'import site' */ -int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ -int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ -int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ -int Py_FrozenFlag; /* Needed by getpath.c */ -int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ -int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ -int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ -int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ -int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ - -PyThreadState *_Py_Finalizing = NULL; - -/* Hack to force loading of object files */ -int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ -    PyOS_mystrnicmp; /* Python/pystrcmp.o */ - -/* PyModule_GetWarningsModule is no longer necessary as of 2.6 -since _warnings is builtin.  This API should not be used. */ -PyObject * -PyModule_GetWarningsModule(void) -{ -    return PyImport_ImportModule("warnings"); -} - -static int initialized = 0; - -/* API to access the initialized flag -- useful for esoteric use */ - -int -Py_IsInitialized(void) -{ -    return initialized; -} - -/* Helper to allow an embedding application to override the normal - * mechanism that attempts to figure out an appropriate IO encoding - */ - -static char *_Py_StandardStreamEncoding = NULL; -static char *_Py_StandardStreamErrors = NULL; - -int -Py_SetStandardStreamEncoding(const char *encoding, const char *errors) -{ -    if (Py_IsInitialized()) { -        /* This is too late to have any effect */ -        return -1; -    } -    /* Can't call PyErr_NoMemory() on errors, as Python hasn't been -     * initialised yet. -     * -     * However, the raw memory allocators are initialised appropriately -     * as C static variables, so _PyMem_RawStrdup is OK even though -     * Py_Initialize hasn't been called yet. -     */ -    if (encoding) { -        _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); -        if (!_Py_StandardStreamEncoding) { -            return -2; -        } -    } -    if (errors) { -        _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); -        if (!_Py_StandardStreamErrors) { -            if (_Py_StandardStreamEncoding) { -                PyMem_RawFree(_Py_StandardStreamEncoding); -            } -            return -3; -        } -    } -    return 0; -} - -/* Global initializations.  Can be undone by Py_Finalize().  Don't -   call this twice without an intervening Py_Finalize() call.  When -   initializations fail, a fatal error is issued and the function does -   not return.  On return, the first thread and interpreter state have -   been created. - -   Locking: you must hold the interpreter lock while calling this. -   (If the lock has not yet been initialized, that's equivalent to -   having the lock, but you cannot use multiple threads.) - -*/ - -static int -add_flag(int flag, const char *envs) -{ -    int env = atoi(envs); -    if (flag < env) -        flag = env; -    if (flag < 1) -        flag = 1; -    return flag; -} - -static char* -get_codec_name(const char *encoding) -{ -    char *name_utf8, *name_str; -    PyObject *codec, *name = NULL; - -    codec = _PyCodec_Lookup(encoding); -    if (!codec) -        goto error; - -    name = _PyObject_GetAttrId(codec, &PyId_name); -    Py_CLEAR(codec); -    if (!name) -        goto error; - -    name_utf8 = _PyUnicode_AsString(name); -    if (name_utf8 == NULL) -        goto error; -    name_str = _PyMem_RawStrdup(name_utf8); -    Py_DECREF(name); -    if (name_str == NULL) { -        PyErr_NoMemory(); -        return NULL; -    } -    return name_str; - -error: -    Py_XDECREF(codec); -    Py_XDECREF(name); -    return NULL; -} - -static char* -get_locale_encoding(void) -{ -#ifdef MS_WINDOWS -    char codepage[100]; -    PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); -    return get_codec_name(codepage); -#elif defined(HAVE_LANGINFO_H) && defined(CODESET) -    char* codeset = nl_langinfo(CODESET); -    if (!codeset || codeset[0] == '\0') { -        PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); -        return NULL; -    } -    return get_codec_name(codeset); -#else -    PyErr_SetNone(PyExc_NotImplementedError); -    return NULL; -#endif -} - -static void -import_init(PyInterpreterState *interp, PyObject *sysmod) -{ -    PyObject *importlib; -    PyObject *impmod; -    PyObject *sys_modules; -    PyObject *value; - -    /* Import _importlib through its frozen version, _frozen_importlib. */ -    if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { -        Py_FatalError("Py_Initialize: can't import _frozen_importlib"); -    } -    else if (Py_VerboseFlag) { -        PySys_FormatStderr("import _frozen_importlib # frozen\n"); -    } -    importlib = PyImport_AddModule("_frozen_importlib"); -    if (importlib == NULL) { -        Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from " -                      "sys.modules"); -    } -    interp->importlib = importlib; -    Py_INCREF(interp->importlib); - -    /* Install _importlib as __import__ */ -    impmod = PyInit_imp(); -    if (impmod == NULL) { -        Py_FatalError("Py_Initialize: can't import imp"); -    } -    else if (Py_VerboseFlag) { -        PySys_FormatStderr("import imp # builtin\n"); -    } -    sys_modules = PyImport_GetModuleDict(); -    if (Py_VerboseFlag) { -        PySys_FormatStderr("import sys # builtin\n"); -    } -    if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) { -        Py_FatalError("Py_Initialize: can't save _imp to sys.modules"); -    } - -    value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); -    if (value == NULL) { -        PyErr_Print(); -        Py_FatalError("Py_Initialize: importlib install failed"); -    } -    Py_DECREF(value); -    Py_DECREF(impmod); - -    _PyImportZip_Init(); -} - - -void -_Py_InitializeEx_Private(int install_sigs, int install_importlib) -{ -    PyInterpreterState *interp; -    PyThreadState *tstate; -    PyObject *bimod, *sysmod, *pstderr; -    char *p; -    extern void _Py_ReadyTypes(void); - -    if (initialized) -        return; -    initialized = 1; -    _Py_Finalizing = NULL; - -#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) -    /* Set up the LC_CTYPE locale, so we can obtain -       the locale's charset without having to switch -       locales. */ -    setlocale(LC_CTYPE, ""); -#endif - -    if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') -        Py_DebugFlag = add_flag(Py_DebugFlag, p); -    if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') -        Py_VerboseFlag = add_flag(Py_VerboseFlag, p); -    if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') -        Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); -    if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') -        Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); -    /* The variable is only tested for existence here; _PyRandom_Init will -       check its value further. */ -    if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') -        Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); - -    _PyRandom_Init(); - -    interp = PyInterpreterState_New(); -    if (interp == NULL) -        Py_FatalError("Py_Initialize: can't make first interpreter"); - -    tstate = PyThreadState_New(interp); -    if (tstate == NULL) -        Py_FatalError("Py_Initialize: can't make first thread"); -    (void) PyThreadState_Swap(tstate); - -#ifdef WITH_THREAD -    /* We can't call _PyEval_FiniThreads() in Py_Finalize because -       destroying the GIL might fail when it is being referenced from -       another running thread (see issue #9901). -       Instead we destroy the previously created GIL here, which ensures -       that we can call Py_Initialize / Py_Finalize multiple times. */ -    _PyEval_FiniThreads(); - -    /* Auto-thread-state API */ -    _PyGILState_Init(interp, tstate); -#endif /* WITH_THREAD */ - -    _Py_ReadyTypes(); - -    if (!_PyFrame_Init()) -        Py_FatalError("Py_Initialize: can't init frames"); - -    if (!_PyLong_Init()) -        Py_FatalError("Py_Initialize: can't init longs"); - -    if (!PyByteArray_Init()) -        Py_FatalError("Py_Initialize: can't init bytearray"); - -    if (!_PyFloat_Init()) -        Py_FatalError("Py_Initialize: can't init float"); - -    interp->modules = PyDict_New(); -    if (interp->modules == NULL) -        Py_FatalError("Py_Initialize: can't make modules dictionary"); - -    /* Init Unicode implementation; relies on the codec registry */ -    if (_PyUnicode_Init() < 0) -        Py_FatalError("Py_Initialize: can't initialize unicode"); -    if (_PyStructSequence_Init() < 0) -        Py_FatalError("Py_Initialize: can't initialize structseq"); - -    bimod = _PyBuiltin_Init(); -    if (bimod == NULL) -        Py_FatalError("Py_Initialize: can't initialize builtins modules"); -    _PyImport_FixupBuiltin(bimod, "builtins"); -    interp->builtins = PyModule_GetDict(bimod); -    if (interp->builtins == NULL) -        Py_FatalError("Py_Initialize: can't initialize builtins dict"); -    Py_INCREF(interp->builtins); - -    /* initialize builtin exceptions */ -    _PyExc_Init(bimod); - -    sysmod = _PySys_Init(); -    if (sysmod == NULL) -        Py_FatalError("Py_Initialize: can't initialize sys"); -    interp->sysdict = PyModule_GetDict(sysmod); -    if (interp->sysdict == NULL) -        Py_FatalError("Py_Initialize: can't initialize sys dict"); -    Py_INCREF(interp->sysdict); -    _PyImport_FixupBuiltin(sysmod, "sys"); -    PySys_SetPath(Py_GetPath()); -    PyDict_SetItemString(interp->sysdict, "modules", -                         interp->modules); - -    /* Set up a preliminary stderr printer until we have enough -       infrastructure for the io module in place. */ -    pstderr = PyFile_NewStdPrinter(fileno(stderr)); -    if (pstderr == NULL) -        Py_FatalError("Py_Initialize: can't set preliminary stderr"); -    _PySys_SetObjectId(&PyId_stderr, pstderr); -    PySys_SetObject("__stderr__", pstderr); -    Py_DECREF(pstderr); - -    _PyImport_Init(); - -    _PyImportHooks_Init(); - -    /* Initialize _warnings. */ -    _PyWarnings_Init(); - -    if (!install_importlib) -        return; - -    import_init(interp, sysmod); - -    /* initialize the faulthandler module */ -    if (_PyFaulthandler_Init()) -        Py_FatalError("Py_Initialize: can't initialize faulthandler"); - -    _PyTime_Init(); - -    if (initfsencoding(interp) < 0) -        Py_FatalError("Py_Initialize: unable to load the file system codec"); - -    if (install_sigs) -        initsigs(); /* Signal handling stuff, including initintr() */ - -    if (_PyTraceMalloc_Init() < 0) -        Py_FatalError("Py_Initialize: can't initialize tracemalloc"); - -    initmain(interp); /* Module __main__ */ -    if (initstdio() < 0) -        Py_FatalError( -            "Py_Initialize: can't initialize sys standard streams"); - -    /* Initialize warnings. */ -    if (PySys_HasWarnOptions()) { -        PyObject *warnings_module = PyImport_ImportModule("warnings"); -        if (warnings_module == NULL) { -            fprintf(stderr, "'import warnings' failed; traceback:\n"); -            PyErr_Print(); -        } -        Py_XDECREF(warnings_module); -    } - -    if (!Py_NoSiteFlag) -        initsite(); /* Module site */ -} - -void -Py_InitializeEx(int install_sigs) -{ -    _Py_InitializeEx_Private(install_sigs, 1); -} - -void -Py_Initialize(void) -{ -    Py_InitializeEx(1); -} - - -#ifdef COUNT_ALLOCS -extern void dump_counts(FILE*); -#endif - -/* Flush stdout and stderr */ - -static int -file_is_closed(PyObject *fobj) -{ -    int r; -    PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); -    if (tmp == NULL) { -        PyErr_Clear(); -        return 0; -    } -    r = PyObject_IsTrue(tmp); -    Py_DECREF(tmp); -    if (r < 0) -        PyErr_Clear(); -    return r > 0; -} - -static void -flush_std_files(void) -{ -    PyObject *fout = _PySys_GetObjectId(&PyId_stdout); -    PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); -    PyObject *tmp; - -    if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { -        tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); -        if (tmp == NULL) -            PyErr_WriteUnraisable(fout); -        else -            Py_DECREF(tmp); -    } - -    if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { -        tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); -        if (tmp == NULL) -            PyErr_Clear(); -        else -            Py_DECREF(tmp); -    } -} - -/* Undo the effect of Py_Initialize(). - -   Beware: if multiple interpreter and/or thread states exist, these -   are not wiped out; only the current thread and interpreter state -   are deleted.  But since everything else is deleted, those other -   interpreter and thread states should no longer be used. - -   (XXX We should do better, e.g. wipe out all interpreters and -   threads.) - -   Locking: as above. - -*/ - -void -Py_Finalize(void) -{ -    PyInterpreterState *interp; -    PyThreadState *tstate; - -    if (!initialized) -        return; - -    wait_for_thread_shutdown(); - -    /* The interpreter is still entirely intact at this point, and the -     * exit funcs may be relying on that.  In particular, if some thread -     * or exit func is still waiting to do an import, the import machinery -     * expects Py_IsInitialized() to return true.  So don't say the -     * interpreter is uninitialized until after the exit funcs have run. -     * Note that Threading.py uses an exit func to do a join on all the -     * threads created thru it, so this also protects pending imports in -     * the threads created via Threading. -     */ -    call_py_exitfuncs(); - -    /* Get current thread state and interpreter pointer */ -    tstate = PyThreadState_GET(); -    interp = tstate->interp; - -    /* Remaining threads (e.g. daemon threads) will automatically exit -       after taking the GIL (in PyEval_RestoreThread()). */ -    _Py_Finalizing = tstate; -    initialized = 0; - -    /* Flush sys.stdout and sys.stderr */ -    flush_std_files(); - -    /* Disable signal handling */ -    PyOS_FiniInterrupts(); - -    /* Collect garbage.  This may call finalizers; it's nice to call these -     * before all modules are destroyed. -     * XXX If a __del__ or weakref callback is triggered here, and tries to -     * XXX import a module, bad things can happen, because Python no -     * XXX longer believes it's initialized. -     * XXX     Fatal Python error: Interpreter not initialized (version mismatch?) -     * XXX is easy to provoke that way.  I've also seen, e.g., -     * XXX     Exception exceptions.ImportError: 'No module named sha' -     * XXX         in <function callback at 0x008F5718> ignored -     * XXX but I'm unclear on exactly how that one happens.  In any case, -     * XXX I haven't seen a real-life report of either of these. -     */ -    PyGC_Collect(); -#ifdef COUNT_ALLOCS -    /* With COUNT_ALLOCS, it helps to run GC multiple times: -       each collection might release some types from the type -       list, so they become garbage. */ -    while (PyGC_Collect() > 0) -        /* nothing */; -#endif -    /* Destroy all modules */ -    PyImport_Cleanup(); - -    /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ -    flush_std_files(); - -    /* Collect final garbage.  This disposes of cycles created by -     * class definitions, for example. -     * XXX This is disabled because it caused too many problems.  If -     * XXX a __del__ or weakref callback triggers here, Python code has -     * XXX a hard time running, because even the sys module has been -     * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). -     * XXX One symptom is a sequence of information-free messages -     * XXX coming from threads (if a __del__ or callback is invoked, -     * XXX other threads can execute too, and any exception they encounter -     * XXX triggers a comedy of errors as subsystem after subsystem -     * XXX fails to find what it *expects* to find in sys to help report -     * XXX the exception and consequent unexpected failures).  I've also -     * XXX seen segfaults then, after adding print statements to the -     * XXX Python code getting called. -     */ -#if 0 -    PyGC_Collect(); -#endif - -    /* Disable tracemalloc after all Python objects have been destroyed, -       so it is possible to use tracemalloc in objects destructor. */ -    _PyTraceMalloc_Fini(); - -    /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ -    _PyImport_Fini(); - -    /* Cleanup typeobject.c's internal caches. */ -    _PyType_Fini(); - -    /* unload faulthandler module */ -    _PyFaulthandler_Fini(); - -    /* Debugging stuff */ -#ifdef COUNT_ALLOCS -    dump_counts(stdout); -#endif -    /* dump hash stats */ -    _PyHash_Fini(); - -    PRINT_TOTAL_REFS(); - -#ifdef Py_TRACE_REFS -    /* Display all objects still alive -- this can invoke arbitrary -     * __repr__ overrides, so requires a mostly-intact interpreter. -     * Alas, a lot of stuff may still be alive now that will be cleaned -     * up later. -     */ -    if (Py_GETENV("PYTHONDUMPREFS")) -        _Py_PrintReferences(stderr); -#endif /* Py_TRACE_REFS */ - -    /* Clear interpreter state and all thread states. */ -    PyInterpreterState_Clear(interp); - -    /* Now we decref the exception classes.  After this point nothing -       can raise an exception.  That's okay, because each Fini() method -       below has been checked to make sure no exceptions are ever -       raised. -    */ - -    _PyExc_Fini(); - -    /* Sundry finalizers */ -    PyMethod_Fini(); -    PyFrame_Fini(); -    PyCFunction_Fini(); -    PyTuple_Fini(); -    PyList_Fini(); -    PySet_Fini(); -    PyBytes_Fini(); -    PyByteArray_Fini(); -    PyLong_Fini(); -    PyFloat_Fini(); -    PyDict_Fini(); -    PySlice_Fini(); -    _PyGC_Fini(); -    _PyRandom_Fini(); - -    /* Cleanup Unicode implementation */ -    _PyUnicode_Fini(); - -    /* reset file system default encoding */ -    if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { -        PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); -        Py_FileSystemDefaultEncoding = NULL; -    } - -    /* XXX Still allocated: -       - various static ad-hoc pointers to interned strings -       - int and float free list blocks -       - whatever various modules and libraries allocate -    */ - -    PyGrammar_RemoveAccelerators(&_PyParser_Grammar); - -    /* Cleanup auto-thread-state */ -#ifdef WITH_THREAD -    _PyGILState_Fini(); -#endif /* WITH_THREAD */ - -    /* Delete current thread. After this, many C API calls become crashy. */ -    PyThreadState_Swap(NULL); -    PyInterpreterState_Delete(interp); - -#ifdef Py_TRACE_REFS -    /* Display addresses (& refcnts) of all objects still alive. -     * An address can be used to find the repr of the object, printed -     * above by _Py_PrintReferences. -     */ -    if (Py_GETENV("PYTHONDUMPREFS")) -        _Py_PrintReferenceAddresses(stderr); -#endif /* Py_TRACE_REFS */ -#ifdef PYMALLOC_DEBUG -    if (Py_GETENV("PYTHONMALLOCSTATS")) -        _PyObject_DebugMallocStats(stderr); -#endif - -    call_ll_exitfuncs(); -} - -/* Create and initialize a new interpreter and thread, and return the -   new thread.  This requires that Py_Initialize() has been called -   first. - -   Unsuccessful initialization yields a NULL pointer.  Note that *no* -   exception information is available even in this case -- the -   exception information is held in the thread, and there is no -   thread. - -   Locking: as above. - -*/ - -PyThreadState * -Py_NewInterpreter(void) -{ -    PyInterpreterState *interp; -    PyThreadState *tstate, *save_tstate; -    PyObject *bimod, *sysmod; - -    if (!initialized) -        Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); - -    interp = PyInterpreterState_New(); -    if (interp == NULL) -        return NULL; - -    tstate = PyThreadState_New(interp); -    if (tstate == NULL) { -        PyInterpreterState_Delete(interp); -        return NULL; -    } - -    save_tstate = PyThreadState_Swap(tstate); - -    /* XXX The following is lax in error checking */ - -    interp->modules = PyDict_New(); - -    bimod = _PyImport_FindBuiltin("builtins"); -    if (bimod != NULL) { -        interp->builtins = PyModule_GetDict(bimod); -        if (interp->builtins == NULL) -            goto handle_error; -        Py_INCREF(interp->builtins); -    } - -    /* initialize builtin exceptions */ -    _PyExc_Init(bimod); - -    sysmod = _PyImport_FindBuiltin("sys"); -    if (bimod != NULL && sysmod != NULL) { -        PyObject *pstderr; - -        interp->sysdict = PyModule_GetDict(sysmod); -        if (interp->sysdict == NULL) -            goto handle_error; -        Py_INCREF(interp->sysdict); -        PySys_SetPath(Py_GetPath()); -        PyDict_SetItemString(interp->sysdict, "modules", -                             interp->modules); -        /* Set up a preliminary stderr printer until we have enough -           infrastructure for the io module in place. */ -        pstderr = PyFile_NewStdPrinter(fileno(stderr)); -        if (pstderr == NULL) -            Py_FatalError("Py_Initialize: can't set preliminary stderr"); -        _PySys_SetObjectId(&PyId_stderr, pstderr); -        PySys_SetObject("__stderr__", pstderr); -        Py_DECREF(pstderr); - -        _PyImportHooks_Init(); - -        import_init(interp, sysmod); - -        if (initfsencoding(interp) < 0) -            goto handle_error; - -        if (initstdio() < 0) -            Py_FatalError( -            "Py_Initialize: can't initialize sys standard streams"); -        initmain(interp); -        if (!Py_NoSiteFlag) -            initsite(); -    } - -    if (!PyErr_Occurred()) -        return tstate; - -handle_error: -    /* Oops, it didn't work.  Undo it all. */ - -    PyErr_PrintEx(0); -    PyThreadState_Clear(tstate); -    PyThreadState_Swap(save_tstate); -    PyThreadState_Delete(tstate); -    PyInterpreterState_Delete(interp); - -    return NULL; -} - -/* Delete an interpreter and its last thread.  This requires that the -   given thread state is current, that the thread has no remaining -   frames, and that it is its interpreter's only remaining thread. -   It is a fatal error to violate these constraints. - -   (Py_Finalize() doesn't have these constraints -- it zaps -   everything, regardless.) - -   Locking: as above. - -*/ - -void -Py_EndInterpreter(PyThreadState *tstate) -{ -    PyInterpreterState *interp = tstate->interp; - -    if (tstate != PyThreadState_GET()) -        Py_FatalError("Py_EndInterpreter: thread is not current"); -    if (tstate->frame != NULL) -        Py_FatalError("Py_EndInterpreter: thread still has a frame"); - -    wait_for_thread_shutdown(); - -    if (tstate != interp->tstate_head || tstate->next != NULL) -        Py_FatalError("Py_EndInterpreter: not the last thread"); - -    PyImport_Cleanup(); -    PyInterpreterState_Clear(interp); -    PyThreadState_Swap(NULL); -    PyInterpreterState_Delete(interp); -} - -#ifdef MS_WINDOWS -static wchar_t *progname = L"python"; -#else -static wchar_t *progname = L"python3"; -#endif - -void -Py_SetProgramName(wchar_t *pn) -{ -    if (pn && *pn) -        progname = pn; -} - -wchar_t * -Py_GetProgramName(void) -{ -    return progname; -} - -static wchar_t *default_home = NULL; -static wchar_t env_home[MAXPATHLEN+1]; - -void -Py_SetPythonHome(wchar_t *home) -{ -    default_home = home; -} - -wchar_t * -Py_GetPythonHome(void) -{ -    wchar_t *home = default_home; -    if (home == NULL && !Py_IgnoreEnvironmentFlag) { -        char* chome = Py_GETENV("PYTHONHOME"); -        if (chome) { -            size_t size = Py_ARRAY_LENGTH(env_home); -            size_t r = mbstowcs(env_home, chome, size); -            if (r != (size_t)-1 && r < size) -                home = env_home; -        } - -    } -    return home; -} - -/* Create __main__ module */ - -static void -initmain(PyInterpreterState *interp) -{ -    PyObject *m, *d, *loader; -    m = PyImport_AddModule("__main__"); -    if (m == NULL) -        Py_FatalError("can't create __main__ module"); -    d = PyModule_GetDict(m); -    if (PyDict_GetItemString(d, "__builtins__") == NULL) { -        PyObject *bimod = PyImport_ImportModule("builtins"); -        if (bimod == NULL) { -            Py_FatalError("Failed to retrieve builtins module"); -        } -        if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { -            Py_FatalError("Failed to initialize __main__.__builtins__"); -        } -        Py_DECREF(bimod); -    } -    /* Main is a little special - imp.is_builtin("__main__") will return -     * False, but BuiltinImporter is still the most appropriate initial -     * setting for its __loader__ attribute. A more suitable value will -     * be set if __main__ gets further initialized later in the startup -     * process. -     */ -    loader = PyDict_GetItemString(d, "__loader__"); -    if (loader == NULL || loader == Py_None) { -        PyObject *loader = PyObject_GetAttrString(interp->importlib, -                                                  "BuiltinImporter"); -        if (loader == NULL) { -            Py_FatalError("Failed to retrieve BuiltinImporter"); -        } -        if (PyDict_SetItemString(d, "__loader__", loader) < 0) { -            Py_FatalError("Failed to initialize __main__.__loader__"); -        } -        Py_DECREF(loader); -    } -} - -static int -initfsencoding(PyInterpreterState *interp) -{ -    PyObject *codec; - -    if (Py_FileSystemDefaultEncoding == NULL) -    { -        Py_FileSystemDefaultEncoding = get_locale_encoding(); -        if (Py_FileSystemDefaultEncoding == NULL) -            Py_FatalError("Py_Initialize: Unable to get the locale encoding"); - -        Py_HasFileSystemDefaultEncoding = 0; -        interp->fscodec_initialized = 1; -        return 0; -    } - -    /* the encoding is mbcs, utf-8 or ascii */ -    codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); -    if (!codec) { -        /* Such error can only occurs in critical situations: no more -         * memory, import a module of the standard library failed, -         * etc. */ -        return -1; -    } -    Py_DECREF(codec); -    interp->fscodec_initialized = 1; -    return 0; -} - -/* Import the site module (not into __main__ though) */ - -static void -initsite(void) -{ -    PyObject *m; -    m = PyImport_ImportModule("site"); -    if (m == NULL) { -        fprintf(stderr, "Failed to import the site module\n"); -        PyErr_Print(); -        Py_Finalize(); -        exit(1); -    } -    else { -        Py_DECREF(m); -    } -} - -static PyObject* -create_stdio(PyObject* io, -    int fd, int write_mode, char* name, -    char* encoding, char* errors) -{ -    PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; -    const char* mode; -    const char* newline; -    PyObject *line_buffering; -    int buffering, isatty; -    _Py_IDENTIFIER(open); -    _Py_IDENTIFIER(isatty); -    _Py_IDENTIFIER(TextIOWrapper); -    _Py_IDENTIFIER(mode); - -    /* stdin is always opened in buffered mode, first because it shouldn't -       make a difference in common use cases, second because TextIOWrapper -       depends on the presence of a read1() method which only exists on -       buffered streams. -    */ -    if (Py_UnbufferedStdioFlag && write_mode) -        buffering = 0; -    else -        buffering = -1; -    if (write_mode) -        mode = "wb"; -    else -        mode = "rb"; -    buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", -                                 fd, mode, buffering, -                                 Py_None, Py_None, Py_None, 0); -    if (buf == NULL) -        goto error; - -    if (buffering) { -        _Py_IDENTIFIER(raw); -        raw = _PyObject_GetAttrId(buf, &PyId_raw); -        if (raw == NULL) -            goto error; -    } -    else { -        raw = buf; -        Py_INCREF(raw); -    } - -    text = PyUnicode_FromString(name); -    if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) -        goto error; -    res = _PyObject_CallMethodId(raw, &PyId_isatty, ""); -    if (res == NULL) -        goto error; -    isatty = PyObject_IsTrue(res); -    Py_DECREF(res); -    if (isatty == -1) -        goto error; -    if (isatty || Py_UnbufferedStdioFlag) -        line_buffering = Py_True; -    else -        line_buffering = Py_False; - -    Py_CLEAR(raw); -    Py_CLEAR(text); - -#ifdef MS_WINDOWS -    /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r" -       newlines to "\n". -       sys.stdout and sys.stderr: translate "\n" to "\r\n". */ -    newline = NULL; -#else -    /* sys.stdin: split lines at "\n". -       sys.stdout and sys.stderr: don't translate newlines (use "\n"). */ -    newline = "\n"; -#endif - -    stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", -                                    buf, encoding, errors, -                                    newline, line_buffering); -    Py_CLEAR(buf); -    if (stream == NULL) -        goto error; - -    if (write_mode) -        mode = "w"; -    else -        mode = "r"; -    text = PyUnicode_FromString(mode); -    if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0) -        goto error; -    Py_CLEAR(text); -    return stream; - -error: -    Py_XDECREF(buf); -    Py_XDECREF(stream); -    Py_XDECREF(text); -    Py_XDECREF(raw); -    return NULL; -} - -static int -is_valid_fd(int fd) -{ -    int dummy_fd; -    if (fd < 0 || !_PyVerify_fd(fd)) -        return 0; -    dummy_fd = dup(fd); -    if (dummy_fd < 0) -        return 0; -    close(dummy_fd); -    return 1; -} - -/* Initialize sys.stdin, stdout, stderr and builtins.open */ -static int -initstdio(void) -{ -    PyObject *iomod = NULL, *wrapper; -    PyObject *bimod = NULL; -    PyObject *m; -    PyObject *std = NULL; -    int status = 0, fd; -    PyObject * encoding_attr; -    char *pythonioencoding = NULL, *encoding, *errors; - -    /* Hack to avoid a nasty recursion issue when Python is invoked -       in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ -    if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { -        goto error; -    } -    Py_DECREF(m); - -    if (!(m = PyImport_ImportModule("encodings.latin_1"))) { -        goto error; -    } -    Py_DECREF(m); - -    if (!(bimod = PyImport_ImportModule("builtins"))) { -        goto error; -    } - -    if (!(iomod = PyImport_ImportModule("io"))) { -        goto error; -    } -    if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { -        goto error; -    } - -    /* Set builtins.open */ -    if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { -        Py_DECREF(wrapper); -        goto error; -    } -    Py_DECREF(wrapper); - -    encoding = _Py_StandardStreamEncoding; -    errors = _Py_StandardStreamErrors; -    if (!encoding || !errors) { -        pythonioencoding = Py_GETENV("PYTHONIOENCODING"); -        if (pythonioencoding) { -            char *err; -            pythonioencoding = _PyMem_Strdup(pythonioencoding); -            if (pythonioencoding == NULL) { -                PyErr_NoMemory(); -                goto error; -            } -            err = strchr(pythonioencoding, ':'); -            if (err) { -                *err = '\0'; -                err++; -                if (*err && !errors) { -                    errors = err; -                } -            } -            if (*pythonioencoding && !encoding) { -                encoding = pythonioencoding; -            } -        } -    } - -    /* Set sys.stdin */ -    fd = fileno(stdin); -    /* Under some conditions stdin, stdout and stderr may not be connected -     * and fileno() may point to an invalid file descriptor. For example -     * GUI apps don't have valid standard streams by default. -     */ -    if (!is_valid_fd(fd)) { -        std = Py_None; -        Py_INCREF(std); -    } -    else { -        std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors); -        if (std == NULL) -            goto error; -    } /* if (fd < 0) */ -    PySys_SetObject("__stdin__", std); -    _PySys_SetObjectId(&PyId_stdin, std); -    Py_DECREF(std); - -    /* Set sys.stdout */ -    fd = fileno(stdout); -    if (!is_valid_fd(fd)) { -        std = Py_None; -        Py_INCREF(std); -    } -    else { -        std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors); -        if (std == NULL) -            goto error; -    } /* if (fd < 0) */ -    PySys_SetObject("__stdout__", std); -    _PySys_SetObjectId(&PyId_stdout, std); -    Py_DECREF(std); - -#if 1 /* Disable this if you have trouble debugging bootstrap stuff */ -    /* Set sys.stderr, replaces the preliminary stderr */ -    fd = fileno(stderr); -    if (!is_valid_fd(fd)) { -        std = Py_None; -        Py_INCREF(std); -    } -    else { -        std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace"); -        if (std == NULL) -            goto error; -    } /* if (fd < 0) */ - -    /* Same as hack above, pre-import stderr's codec to avoid recursion -       when import.c tries to write to stderr in verbose mode. */ -    encoding_attr = PyObject_GetAttrString(std, "encoding"); -    if (encoding_attr != NULL) { -        const char * std_encoding; -        std_encoding = _PyUnicode_AsString(encoding_attr); -        if (std_encoding != NULL) { -            PyObject *codec_info = _PyCodec_Lookup(std_encoding); -            Py_XDECREF(codec_info); -        } -        Py_DECREF(encoding_attr); -    } -    PyErr_Clear();  /* Not a fatal error if codec isn't available */ - -    if (PySys_SetObject("__stderr__", std) < 0) { -        Py_DECREF(std); -        goto error; -    } -    if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { -        Py_DECREF(std); -        goto error; -    } -    Py_DECREF(std); -#endif - -    if (0) { -  error: -        status = -1; -    } - -    /* We won't need them anymore. */ -    if (_Py_StandardStreamEncoding) { -        PyMem_RawFree(_Py_StandardStreamEncoding); -        _Py_StandardStreamEncoding = NULL; -    } -    if (_Py_StandardStreamErrors) { -        PyMem_RawFree(_Py_StandardStreamErrors); -        _Py_StandardStreamErrors = NULL; -    } -    PyMem_Free(pythonioencoding); -    Py_XDECREF(bimod); -    Py_XDECREF(iomod); -    return status; -}  /* Parse input from a file and execute it */ @@ -1322,7 +110,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *      err = -1;      for (;;) {          ret = PyRun_InteractiveOneObject(fp, filename, flags); -        PRINT_TOTAL_REFS(); +        _PY_DEBUG_PRINT_TOTAL_REFS();          if (ret == E_EOF) {              err = 0;              break; @@ -1477,7 +265,7 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *f  static int  maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)  { -    if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0) +    if (strcmp(ext, ".pyc") == 0)          return 1;      /* Only look into the file if we are allowed to close it, since @@ -1516,7 +304,7 @@ set_main_loader(PyObject *d, const char *filename, const char *loader_name)  {      PyInterpreterState *interp;      PyThreadState *tstate; -    PyObject *filename_obj, *loader_type, *loader; +    PyObject *filename_obj, *bootstrap, *loader_type = NULL, *loader;      int result = 0;      filename_obj = PyUnicode_DecodeFSDefault(filename); @@ -1525,7 +313,12 @@ set_main_loader(PyObject *d, const char *filename, const char *loader_name)      /* Get current thread state and interpreter pointer */      tstate = PyThreadState_GET();      interp = tstate->interp; -    loader_type = PyObject_GetAttrString(interp->importlib, loader_name); +    bootstrap = PyObject_GetAttrString(interp->importlib, +                                       "_bootstrap_external"); +    if (bootstrap != NULL) { +        loader_type = PyObject_GetAttrString(bootstrap, loader_name); +        Py_DECREF(bootstrap); +    }      if (loader_type == NULL) {          Py_DECREF(filename_obj);          return -1; @@ -1583,9 +376,6 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,              fprintf(stderr, "python: Can't reopen .pyc file\n");              goto done;          } -        /* Turn on optimization if a .pyo file is given */ -        if (strcmp(ext, ".pyo") == 0) -            Py_OptimizeFlag = 1;          if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) {              fprintf(stderr, "python: failed to set __main__.__loader__\n"); @@ -1729,7 +519,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj)          return;      if (offset >= 0) { -        if (offset > 0 && offset == strlen(text) && text[offset - 1] == '\n') +        if (offset > 0 && (size_t)offset == strlen(text) && text[offset - 1] == '\n')              offset--;          for (;;) {              nl = strchr(text, '\n'); @@ -2193,13 +983,17 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,      magic = PyMarshal_ReadLongFromFile(fp);      if (magic != PyImport_GetMagicNumber()) { -        PyErr_SetString(PyExc_RuntimeError, -                   "Bad magic number in .pyc file"); +        if (!PyErr_Occurred()) +            PyErr_SetString(PyExc_RuntimeError, +                       "Bad magic number in .pyc file");          return NULL;      }      /* Skip mtime and size */      (void) PyMarshal_ReadLongFromFile(fp);      (void) PyMarshal_ReadLongFromFile(fp); +    if (PyErr_Occurred()) +        return NULL; +      v = PyMarshal_ReadLastObjectFromFile(fp);      if (v == NULL || !PyCode_Check(v)) {          Py_XDECREF(v); @@ -2587,272 +1381,6 @@ cleanup:      }  } -/* Print the current exception (if an exception is set) with its traceback, - * or display the current Python stack. - * - * Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is - * called on catastrophic cases. */ - -static void -_Py_PrintFatalError(int fd) -{ -    PyObject *ferr, *res; -    PyObject *exception, *v, *tb; -    int has_tb; -    PyThreadState *tstate; - -    PyErr_Fetch(&exception, &v, &tb); -    if (exception == NULL) { -        /* No current exception */ -        goto display_stack; -    } - -    ferr = _PySys_GetObjectId(&PyId_stderr); -    if (ferr == NULL || ferr == Py_None) { -        /* sys.stderr is not set yet or set to None, -           no need to try to display the exception */ -        goto display_stack; -    } - -    PyErr_NormalizeException(&exception, &v, &tb); -    if (tb == NULL) { -        tb = Py_None; -        Py_INCREF(tb); -    } -    PyException_SetTraceback(v, tb); -    if (exception == NULL) { -        /* PyErr_NormalizeException() failed */ -        goto display_stack; -    } - -    has_tb = (tb != NULL && tb != Py_None); -    PyErr_Display(exception, v, tb); -    Py_XDECREF(exception); -    Py_XDECREF(v); -    Py_XDECREF(tb); - -    /* sys.stderr may be buffered: call sys.stderr.flush() */ -    res = _PyObject_CallMethodId(ferr, &PyId_flush, ""); -    if (res == NULL) -        PyErr_Clear(); -    else -        Py_DECREF(res); - -    if (has_tb) -        return; - -display_stack: -    /* PyGILState_GetThisThreadState() works even if the GIL was released */ -    tstate = PyGILState_GetThisThreadState(); -    if (tstate == NULL) { -        /* _Py_DumpTracebackThreads() requires the thread state to display -         * frames */ -        return; -    } - -    fputc('\n', stderr); -    fflush(stderr); - -    /* display the current Python stack */ -    _Py_DumpTracebackThreads(fd, tstate->interp, tstate); -} - -/* Print fatal error message and abort */ - -void -Py_FatalError(const char *msg) -{ -    const int fd = fileno(stderr); -    static int reentrant = 0; -#ifdef MS_WINDOWS -    size_t len; -    WCHAR* buffer; -    size_t i; -#endif - -    if (reentrant) { -        /* Py_FatalError() caused a second fatal error. -           Example: flush_std_files() raises a recursion error. */ -        goto exit; -    } -    reentrant = 1; - -    fprintf(stderr, "Fatal Python error: %s\n", msg); -    fflush(stderr); /* it helps in Windows debug build */ - -    /* Print the exception (if an exception is set) with its traceback, -     * or display the current Python stack. */ -    _Py_PrintFatalError(fd); - -    /* Flush sys.stdout and sys.stderr */ -    flush_std_files(); - -    /* The main purpose of faulthandler is to display the traceback. We already -     * did our best to display it. So faulthandler can now be disabled. -     * (Don't trigger it on abort().) */ -    _PyFaulthandler_Fini(); - -#ifdef MS_WINDOWS -    len = strlen(msg); - -    /* Convert the message to wchar_t. This uses a simple one-to-one -    conversion, assuming that the this error message actually uses ASCII -    only. If this ceases to be true, we will have to convert. */ -    buffer = alloca( (len+1) * (sizeof *buffer)); -    for( i=0; i<=len; ++i) -        buffer[i] = msg[i]; -    OutputDebugStringW(L"Fatal Python error: "); -    OutputDebugStringW(buffer); -    OutputDebugStringW(L"\n"); -#endif /* MS_WINDOWS */ - -exit: -#if defined(MS_WINDOWS) && defined(_DEBUG) -    DebugBreak(); -#endif -    abort(); -} - -/* Clean up and exit */ - -#ifdef WITH_THREAD -#include "pythread.h" -#endif - -static void (*pyexitfunc)(void) = NULL; -/* For the atexit module. */ -void _Py_PyAtExit(void (*func)(void)) -{ -    pyexitfunc = func; -} - -static void -call_py_exitfuncs(void) -{ -    if (pyexitfunc == NULL) -        return; - -    (*pyexitfunc)(); -    PyErr_Clear(); -} - -/* Wait until threading._shutdown completes, provided -   the threading module was imported in the first place. -   The shutdown routine will wait until all non-daemon -   "threading" threads have completed. */ -static void -wait_for_thread_shutdown(void) -{ -#ifdef WITH_THREAD -    _Py_IDENTIFIER(_shutdown); -    PyObject *result; -    PyThreadState *tstate = PyThreadState_GET(); -    PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, -                                                  "threading"); -    if (threading == NULL) { -        /* threading not imported */ -        PyErr_Clear(); -        return; -    } -    result = _PyObject_CallMethodId(threading, &PyId__shutdown, ""); -    if (result == NULL) { -        PyErr_WriteUnraisable(threading); -    } -    else { -        Py_DECREF(result); -    } -    Py_DECREF(threading); -#endif -} - -#define NEXITFUNCS 32 -static void (*exitfuncs[NEXITFUNCS])(void); -static int nexitfuncs = 0; - -int Py_AtExit(void (*func)(void)) -{ -    if (nexitfuncs >= NEXITFUNCS) -        return -1; -    exitfuncs[nexitfuncs++] = func; -    return 0; -} - -static void -call_ll_exitfuncs(void) -{ -    while (nexitfuncs > 0) -        (*exitfuncs[--nexitfuncs])(); - -    fflush(stdout); -    fflush(stderr); -} - -void -Py_Exit(int sts) -{ -    Py_Finalize(); - -    exit(sts); -} - -static void -initsigs(void) -{ -#ifdef SIGPIPE -    PyOS_setsig(SIGPIPE, SIG_IGN); -#endif -#ifdef SIGXFZ -    PyOS_setsig(SIGXFZ, SIG_IGN); -#endif -#ifdef SIGXFSZ -    PyOS_setsig(SIGXFSZ, SIG_IGN); -#endif -    PyOS_InitInterrupts(); /* May imply initsignal() */ -    if (PyErr_Occurred()) { -        Py_FatalError("Py_Initialize: can't import signal"); -    } -} - - -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. - * - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ -void -_Py_RestoreSignals(void) -{ -#ifdef SIGPIPE -    PyOS_setsig(SIGPIPE, SIG_DFL); -#endif -#ifdef SIGXFZ -    PyOS_setsig(SIGXFZ, SIG_DFL); -#endif -#ifdef SIGXFSZ -    PyOS_setsig(SIGXFSZ, SIG_DFL); -#endif -} - - -/* - * The file descriptor fd is considered ``interactive'' if either - *   a) isatty(fd) is TRUE, or - *   b) the -i flag was given, and the filename associated with - *      the descriptor is NULL or "<stdin>" or "???". - */ -int -Py_FdIsInteractive(FILE *fp, const char *filename) -{ -    if (isatty((int)fileno(fp))) -        return 1; -    if (!Py_InteractiveFlag) -        return 0; -    return (filename == NULL) || -           (strcmp(filename, "<stdin>") == 0) || -           (strcmp(filename, "???") == 0); -} -  #if defined(USE_STACKCHECK)  #if defined(WIN32) && defined(_MSC_VER) @@ -2891,73 +1419,6 @@ PyOS_CheckStack(void)  #endif /* USE_STACKCHECK */ - -/* Wrappers around sigaction() or signal(). */ - -PyOS_sighandler_t -PyOS_getsig(int sig) -{ -#ifdef HAVE_SIGACTION -    struct sigaction context; -    if (sigaction(sig, NULL, &context) == -1) -        return SIG_ERR; -    return context.sa_handler; -#else -    PyOS_sighandler_t handler; -/* Special signal handling for the secure CRT in Visual Studio 2005 */ -#if defined(_MSC_VER) && _MSC_VER >= 1400 -    switch (sig) { -    /* Only these signals are valid */ -    case SIGINT: -    case SIGILL: -    case SIGFPE: -    case SIGSEGV: -    case SIGTERM: -    case SIGBREAK: -    case SIGABRT: -        break; -    /* Don't call signal() with other values or it will assert */ -    default: -        return SIG_ERR; -    } -#endif /* _MSC_VER && _MSC_VER >= 1400 */ -    handler = signal(sig, SIG_IGN); -    if (handler != SIG_ERR) -        signal(sig, handler); -    return handler; -#endif -} - -/* - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ -PyOS_sighandler_t -PyOS_setsig(int sig, PyOS_sighandler_t handler) -{ -#ifdef HAVE_SIGACTION -    /* Some code in Modules/signalmodule.c depends on sigaction() being -     * used here if HAVE_SIGACTION is defined.  Fix that if this code -     * changes to invalidate that assumption. -     */ -    struct sigaction context, ocontext; -    context.sa_handler = handler; -    sigemptyset(&context.sa_mask); -    context.sa_flags = 0; -    if (sigaction(sig, &context, &ocontext) == -1) -        return SIG_ERR; -    return ocontext.sa_handler; -#else -    PyOS_sighandler_t oldhandler; -    oldhandler = signal(sig, handler); -#ifdef HAVE_SIGINTERRUPT -    siginterrupt(sig, 1); -#endif -    return oldhandler; -#endif -} -  /* Deprecated C API functions still provided for binary compatiblity */  #undef PyParser_SimpleParseFile | 
