From 04ac4c1cb8e7af5571adbe64cb82938a323e5850 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Tue, 11 Sep 2012 15:47:28 +0200 Subject: [PATCH] Issue #15895: my analysis was slightly off. The FILE pointer is only leaked when set_main_loader() fails for a pyc file with closeit=0. In the success case run_pyc_file() does its own cleanup of the fp. I've changed the code to use another FILE ptr for pyc files and moved the fclose() to PyRun_SimpleFileExFlags() to make it more obvious what's happening. --- Python/pythonrun.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 7e9f6545e26..b1ca125781c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1385,7 +1385,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, { PyObject *m, *d, *v; const char *ext; - int set_file_name = 0, close_own_fp = 0, ret; + int set_file_name = 0, ret; size_t len; m = PyImport_AddModule("__main__"); @@ -1411,15 +1411,15 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, len = strlen(filename); ext = filename + len - (len > 4 ? 4 : 0); if (maybe_pyc_file(fp, filename, ext, closeit)) { + FILE *pyc_fp; /* Try to run a pyc file. First, re-open in binary */ if (closeit) fclose(fp); - if ((fp = fopen(filename, "rb")) == NULL) { + if ((pyc_fp = fopen(filename, "rb")) == NULL) { fprintf(stderr, "python: Can't reopen .pyc file\n"); ret = -1; goto done; } - close_own_fp = 1; /* Turn on optimization if a .pyo file is given */ if (strcmp(ext, ".pyo") == 0) Py_OptimizeFlag = 1; @@ -1427,9 +1427,11 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { fprintf(stderr, "python: failed to set __main__.__loader__\n"); ret = -1; + fclose(pyc_fp); goto done; } - v = run_pyc_file(fp, filename, d, d, flags); + v = run_pyc_file(pyc_fp, filename, d, d, flags); + fclose(pyc_fp); } else { /* When running from stdin, leave __main__.__loader__ alone */ if (strcmp(filename, "") != 0 && @@ -1450,9 +1452,6 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, Py_DECREF(v); ret = 0; done: - if (close_own_fp) { - fclose(fp); - } if (set_file_name && PyDict_DelItemString(d, "__file__")) PyErr_Clear(); return ret; @@ -1999,7 +1998,6 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, (void) PyMarshal_ReadLongFromFile(fp); (void) PyMarshal_ReadLongFromFile(fp); v = PyMarshal_ReadLastObjectFromFile(fp); - fclose(fp); if (v == NULL || !PyCode_Check(v)) { Py_XDECREF(v); PyErr_SetString(PyExc_RuntimeError,