summaryrefslogtreecommitdiff
path: root/Python/import.c
diff options
context:
space:
mode:
authorKristján Valur Jónsson <kristjan@ccpgames.com>2009-03-31 17:43:39 +0000
committerKristján Valur Jónsson <kristjan@ccpgames.com>2009-03-31 17:43:39 +0000
commite1b0445ff97ef58d9888091df6c9bc2d3917ad0f (patch)
treeba29ec09b0fff42a988df8e41564940d782f27d4 /Python/import.c
parent47f27a346f0eb2bf067e8df2cedf7398985fd1a2 (diff)
downloadcpython-git-e1b0445ff97ef58d9888091df6c9bc2d3917ad0f.tar.gz
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.
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/Python/import.c b/Python/import.c
index 2be33085ca..529c3c2044 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -3023,13 +3023,21 @@ get_file(char *pathname, PyObject *fob, char *mode)
int fd = PyObject_AsFileDescriptor(fob);
if (fd == -1)
return NULL;
- /* XXX This will leak a FILE struct. Fix this!!!!
- (But it doesn't leak a file descrioptor!) */
+ if (!_PyVerify_fd(fd))
+ goto error;
+ /* the FILE struct gets a new fd, so that it can be closed
+ * independently of the file descriptor given
+ */
+ fd = dup(fd);
+ if (fd == -1)
+ goto error;
fp = fdopen(fd, mode);
}
- if (fp == NULL)
- PyErr_SetFromErrno(PyExc_IOError);
- return fp;
+ if (fp)
+ return fp;
+error:
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
}
static PyObject *
@@ -3051,8 +3059,7 @@ imp_load_compiled(PyObject *self, PyObject *args)
return NULL;
}
m = load_compiled_module(name, pathname, fp);
- if (fob == NULL)
- fclose(fp);
+ fclose(fp);
PyMem_Free(pathname);
return m;
}
@@ -3081,6 +3088,8 @@ imp_load_dynamic(PyObject *self, PyObject *args)
}
m = _PyImport_LoadDynamicModule(name, pathname, fp);
PyMem_Free(pathname);
+ if (fp)
+ fclose(fp);
return m;
}
@@ -3105,8 +3114,7 @@ imp_load_source(PyObject *self, PyObject *args)
return NULL;
}
m = load_source_module(name, pathname, fp);
- if (fob == NULL)
- fclose(fp);
+ fclose(fp);
return m;
}
@@ -3150,6 +3158,8 @@ imp_load_module(PyObject *self, PyObject *args)
}
ret = load_module(name, fp, pathname, type, NULL);
PyMem_Free(pathname);
+ if (fp)
+ fclose(fp);
return ret;
}