Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e1b0445

Browse files
author
Kristján Valur Jónsson
committed
get_file() no longer leaks a FILE structure. If given a file descriptor, it calls dup() to get a new handle. Then both the FILE object and the fd can be closed.
This is important, because otherwise, the leaked FILE object will be closed on process exit, causing assertions on Windows, e.g. in the test_multiprocessing.py regression test.
1 parent 47f27a3 commit e1b0445

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

Python/import.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,13 +3023,21 @@ get_file(char *pathname, PyObject *fob, char *mode)
30233023
int fd = PyObject_AsFileDescriptor(fob);
30243024
if (fd == -1)
30253025
return NULL;
3026-
/* XXX This will leak a FILE struct. Fix this!!!!
3027-
(But it doesn't leak a file descrioptor!) */
3026+
if (!_PyVerify_fd(fd))
3027+
goto error;
3028+
/* the FILE struct gets a new fd, so that it can be closed
3029+
* independently of the file descriptor given
3030+
*/
3031+
fd = dup(fd);
3032+
if (fd == -1)
3033+
goto error;
30283034
fp = fdopen(fd, mode);
30293035
}
3030-
if (fp == NULL)
3031-
PyErr_SetFromErrno(PyExc_IOError);
3032-
return fp;
3036+
if (fp)
3037+
return fp;
3038+
error:
3039+
PyErr_SetFromErrno(PyExc_IOError);
3040+
return NULL;
30333041
}
30343042

30353043
static PyObject *
@@ -3051,8 +3059,7 @@ imp_load_compiled(PyObject *self, PyObject *args)
30513059
return NULL;
30523060
}
30533061
m = load_compiled_module(name, pathname, fp);
3054-
if (fob == NULL)
3055-
fclose(fp);
3062+
fclose(fp);
30563063
PyMem_Free(pathname);
30573064
return m;
30583065
}
@@ -3081,6 +3088,8 @@ imp_load_dynamic(PyObject *self, PyObject *args)
30813088
}
30823089
m = _PyImport_LoadDynamicModule(name, pathname, fp);
30833090
PyMem_Free(pathname);
3091+
if (fp)
3092+
fclose(fp);
30843093
return m;
30853094
}
30863095

@@ -3105,8 +3114,7 @@ imp_load_source(PyObject *self, PyObject *args)
31053114
return NULL;
31063115
}
31073116
m = load_source_module(name, pathname, fp);
3108-
if (fob == NULL)
3109-
fclose(fp);
3117+
fclose(fp);
31103118
return m;
31113119
}
31123120

@@ -3150,6 +3158,8 @@ imp_load_module(PyObject *self, PyObject *args)
31503158
}
31513159
ret = load_module(name, fp, pathname, type, NULL);
31523160
PyMem_Free(pathname);
3161+
if (fp)
3162+
fclose(fp);
31533163
return ret;
31543164
}
31553165

0 commit comments

Comments
 (0)