Mercurial > cpython-lru_cache-weakref
comparison Python/pythonrun.c @ 78991:c3539eb02470
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.
| author | Christian Heimes <christian@cheimes.de> |
|---|---|
| date | Tue, 11 Sep 2012 15:47:28 +0200 |
| parents | 4754c4a710e6 |
| children | 02d25098ad57 |
comparison
equal
deleted
inserted
replaced
| 78990:4754c4a710e6 | 78991:c3539eb02470 |
|---|---|
| 1383 PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, | 1383 PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, |
| 1384 PyCompilerFlags *flags) | 1384 PyCompilerFlags *flags) |
| 1385 { | 1385 { |
| 1386 PyObject *m, *d, *v; | 1386 PyObject *m, *d, *v; |
| 1387 const char *ext; | 1387 const char *ext; |
| 1388 int set_file_name = 0, close_own_fp = 0, ret; | 1388 int set_file_name = 0, ret; |
| 1389 size_t len; | 1389 size_t len; |
| 1390 | 1390 |
| 1391 m = PyImport_AddModule("__main__"); | 1391 m = PyImport_AddModule("__main__"); |
| 1392 if (m == NULL) | 1392 if (m == NULL) |
| 1393 return -1; | 1393 return -1; |
| 1409 Py_DECREF(f); | 1409 Py_DECREF(f); |
| 1410 } | 1410 } |
| 1411 len = strlen(filename); | 1411 len = strlen(filename); |
| 1412 ext = filename + len - (len > 4 ? 4 : 0); | 1412 ext = filename + len - (len > 4 ? 4 : 0); |
| 1413 if (maybe_pyc_file(fp, filename, ext, closeit)) { | 1413 if (maybe_pyc_file(fp, filename, ext, closeit)) { |
| 1414 FILE *pyc_fp; | |
| 1414 /* Try to run a pyc file. First, re-open in binary */ | 1415 /* Try to run a pyc file. First, re-open in binary */ |
| 1415 if (closeit) | 1416 if (closeit) |
| 1416 fclose(fp); | 1417 fclose(fp); |
| 1417 if ((fp = fopen(filename, "rb")) == NULL) { | 1418 if ((pyc_fp = fopen(filename, "rb")) == NULL) { |
| 1418 fprintf(stderr, "python: Can't reopen .pyc file\n"); | 1419 fprintf(stderr, "python: Can't reopen .pyc file\n"); |
| 1419 ret = -1; | 1420 ret = -1; |
| 1420 goto done; | 1421 goto done; |
| 1421 } | 1422 } |
| 1422 close_own_fp = 1; | |
| 1423 /* Turn on optimization if a .pyo file is given */ | 1423 /* Turn on optimization if a .pyo file is given */ |
| 1424 if (strcmp(ext, ".pyo") == 0) | 1424 if (strcmp(ext, ".pyo") == 0) |
| 1425 Py_OptimizeFlag = 1; | 1425 Py_OptimizeFlag = 1; |
| 1426 | 1426 |
| 1427 if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { | 1427 if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { |
| 1428 fprintf(stderr, "python: failed to set __main__.__loader__\n"); | 1428 fprintf(stderr, "python: failed to set __main__.__loader__\n"); |
| 1429 ret = -1; | 1429 ret = -1; |
| 1430 fclose(pyc_fp); | |
| 1430 goto done; | 1431 goto done; |
| 1431 } | 1432 } |
| 1432 v = run_pyc_file(fp, filename, d, d, flags); | 1433 v = run_pyc_file(pyc_fp, filename, d, d, flags); |
| 1434 fclose(pyc_fp); | |
| 1433 } else { | 1435 } else { |
| 1434 /* When running from stdin, leave __main__.__loader__ alone */ | 1436 /* When running from stdin, leave __main__.__loader__ alone */ |
| 1435 if (strcmp(filename, "<stdin>") != 0 && | 1437 if (strcmp(filename, "<stdin>") != 0 && |
| 1436 set_main_loader(d, filename, "SourceFileLoader") < 0) { | 1438 set_main_loader(d, filename, "SourceFileLoader") < 0) { |
| 1437 fprintf(stderr, "python: failed to set __main__.__loader__\n"); | 1439 fprintf(stderr, "python: failed to set __main__.__loader__\n"); |
| 1448 goto done; | 1450 goto done; |
| 1449 } | 1451 } |
| 1450 Py_DECREF(v); | 1452 Py_DECREF(v); |
| 1451 ret = 0; | 1453 ret = 0; |
| 1452 done: | 1454 done: |
| 1453 if (close_own_fp) { | |
| 1454 fclose(fp); | |
| 1455 } | |
| 1456 if (set_file_name && PyDict_DelItemString(d, "__file__")) | 1455 if (set_file_name && PyDict_DelItemString(d, "__file__")) |
| 1457 PyErr_Clear(); | 1456 PyErr_Clear(); |
| 1458 return ret; | 1457 return ret; |
| 1459 } | 1458 } |
| 1460 | 1459 |
| 1997 } | 1996 } |
| 1998 /* Skip mtime and size */ | 1997 /* Skip mtime and size */ |
| 1999 (void) PyMarshal_ReadLongFromFile(fp); | 1998 (void) PyMarshal_ReadLongFromFile(fp); |
| 2000 (void) PyMarshal_ReadLongFromFile(fp); | 1999 (void) PyMarshal_ReadLongFromFile(fp); |
| 2001 v = PyMarshal_ReadLastObjectFromFile(fp); | 2000 v = PyMarshal_ReadLastObjectFromFile(fp); |
| 2002 fclose(fp); | |
| 2003 if (v == NULL || !PyCode_Check(v)) { | 2001 if (v == NULL || !PyCode_Check(v)) { |
| 2004 Py_XDECREF(v); | 2002 Py_XDECREF(v); |
| 2005 PyErr_SetString(PyExc_RuntimeError, | 2003 PyErr_SetString(PyExc_RuntimeError, |
| 2006 "Bad code object in .pyc file"); | 2004 "Bad code object in .pyc file"); |
| 2007 return NULL; | 2005 return NULL; |
