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;