diff -r 8aa032b26552 Include/Python.h
--- a/Include/Python.h Mon Apr 18 03:45:18 2016 +0000
+++ b/Include/Python.h Tue Apr 19 14:28:02 2016 +0200
@@ -139,6 +139,7 @@
#include "pystrtod.h"
#include "pystrcmp.h"
#include "dtoa.h"
+#include "fileutils.h"
/* _Py_Mangle is defined in compile.c */
PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
diff -r 8aa032b26552 Include/fileutils.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/fileutils.h Tue Apr 19 14:28:02 2016 +0200
@@ -0,0 +1,19 @@
+#ifndef Py_FILEUTILS_H
+#define Py_FILEUTILS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Try to make the file descriptor non-inheritable. Ignore errors. */
+PyAPI_FUNC(void) _Py_try_set_non_inheritable(int fd);
+
+/* Wrapper to fopen() which tries to make the file non-inheritable on success.
+ Ignore errors on trying to set the file descriptor non-inheritable. */
+PyAPI_FUNC(FILE*) _Py_fopen(const char *path, const char *mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_FILEUTILS_H */
diff -r 8aa032b26552 Makefile.pre.in
--- a/Makefile.pre.in Mon Apr 18 03:45:18 2016 +0000
+++ b/Makefile.pre.in Tue Apr 19 14:28:02 2016 +0200
@@ -312,7 +312,7 @@ ASDLGEN= $(srcdir)/Parser/asdl_c.py
OPCODETARGETS_H= \
$(srcdir)/Python/opcode_targets.h
-
+
OPCODETARGETGEN= \
$(srcdir)/Python/makeopcodetargets.py
@@ -351,7 +351,7 @@ PYTHON_OBJS= \
Python/pymath.o \
Python/pystate.o \
Python/pythonrun.o \
- Python/random.o \
+ Python/random.o \
Python/structmember.o \
Python/symtable.o \
Python/sysmodule.o \
@@ -362,6 +362,7 @@ PYTHON_OBJS= \
Python/dtoa.o \
Python/formatter_unicode.o \
Python/formatter_string.o \
+ Python/fileutils.o \
Python/$(DYNLOADFILE) \
$(LIBOBJS) \
$(MACHDEP_OBJS) \
@@ -781,6 +782,7 @@ PYTHON_HEADERS= \
Include/errcode.h \
Include/eval.h \
Include/fileobject.h \
+ Include/fileutils.h \
Include/floatobject.h \
Include/frameobject.h \
Include/funcobject.h \
diff -r 8aa032b26552 Modules/_bsddb.c
--- a/Modules/_bsddb.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/_bsddb.c Tue Apr 19 14:28:02 2016 +0200
@@ -3436,26 +3436,25 @@ DB_verify(DBObject* self, PyObject* args
FILE* outFile=NULL;
static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
NULL };
+ PyObject *error;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
&fileName, &dbName, &outFileName, &flags))
return NULL;
CHECK_DB_NOT_CLOSED(self);
- if (outFileName)
- outFile = fopen(outFileName, "w");
+ if (outFileName) {
+ outFile = _Py_fopen(outFileName, "w");
/* XXX(nnorwitz): it should probably be an exception if outFile
can't be opened. */
-
- { /* DB.verify acts as a DB handle destructor (like close) */
- PyObject *error;
-
- error=DB_close_internal(self, 0, 1);
- if (error) {
- if (outFile)
- fclose(outFile);
- return error;
- }
+ }
+
+ /* DB.verify acts as a DB handle destructor (like close) */
+ error = DB_close_internal(self, 0, 1);
+ if (error) {
+ if (outFile)
+ fclose(outFile);
+ return error;
}
MYDB_BEGIN_ALLOW_THREADS;
diff -r 8aa032b26552 Modules/_testcapimodule.c
--- a/Modules/_testcapimodule.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/_testcapimodule.c Tue Apr 19 14:28:02 2016 +0200
@@ -2169,7 +2169,7 @@ pymarshal_write_long_to_file(PyObject* s
&value, &filename, &version))
return NULL;
- fp = fopen(filename, "wb");
+ fp = _Py_fopen(filename, "wb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -2195,7 +2195,7 @@ pymarshal_write_object_to_file(PyObject*
&obj, &filename, &version))
return NULL;
- fp = fopen(filename, "wb");
+ fp = _Py_fopen(filename, "wb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -2220,7 +2220,7 @@ pymarshal_read_short_from_file(PyObject*
if (!PyArg_ParseTuple(args, "s:pymarshal_read_short_from_file", &filename))
return NULL;
- fp = fopen(filename, "rb");
+ fp = _Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -2245,7 +2245,7 @@ pymarshal_read_long_from_file(PyObject*
if (!PyArg_ParseTuple(args, "s:pymarshal_read_long_from_file", &filename))
return NULL;
- fp = fopen(filename, "rb");
+ fp = _Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -2271,7 +2271,7 @@ pymarshal_read_last_object_from_file(PyO
if (!PyArg_ParseTuple(args, "s:pymarshal_read_last_object_from_file", &filename))
return NULL;
- fp = fopen(filename, "rb");
+ fp = _Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
@@ -2295,7 +2295,7 @@ pymarshal_read_object_from_file(PyObject
if (!PyArg_ParseTuple(args, "s:pymarshal_read_object_from_file", &filename))
return NULL;
- fp = fopen(filename, "rb");
+ fp = _Py_fopen(filename, "rb");
if (fp == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
diff -r 8aa032b26552 Modules/getpath.c
--- a/Modules/getpath.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/getpath.c Tue Apr 19 14:28:02 2016 +0200
@@ -341,7 +341,7 @@ search_for_exec_prefix(char *argv0_path,
strcpy(exec_prefix, argv0_path);
joinpath(exec_prefix, "pybuilddir.txt");
if (isfile(exec_prefix)) {
- FILE *f = fopen(exec_prefix, "r");
+ FILE *f = _Py_fopen(exec_prefix, "r");
if (f == NULL)
errno = 0;
else {
diff -r 8aa032b26552 Modules/main.c
--- a/Modules/main.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/main.c Tue Apr 19 14:28:02 2016 +0200
@@ -148,12 +148,13 @@ static void RunStartupFile(PyCompilerFla
{
char *startup = Py_GETENV("PYTHONSTARTUP");
if (startup != NULL && startup[0] != '\0') {
- FILE *fp = fopen(startup, "r");
+ FILE *fp = _Py_fopen(startup, "r");
if (fp != NULL) {
(void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
PyErr_Clear();
fclose(fp);
- } else {
+ }
+ else {
int save_errno;
save_errno = errno;
PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
@@ -602,13 +603,15 @@ Py_Main(int argc, char **argv)
}
if (sts==-1 && filename!=NULL) {
- if ((fp = fopen(filename, "r")) == NULL) {
+ fp = _Py_fopen(filename, "r");
+ if (fp == NULL) {
fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
argv[0], filename, errno, strerror(errno));
return 2;
}
- else if (skipfirstline) {
+
+ if (skipfirstline) {
int ch;
/* Push back first newline so line numbers
remain the same */
diff -r 8aa032b26552 Modules/mmapmodule.c
--- a/Modules/mmapmodule.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/mmapmodule.c Tue Apr 19 14:28:02 2016 +0200
@@ -1250,14 +1250,17 @@ new_mmap_object(PyTypeObject *type, PyOb
PyErr_SetFromErrno(mmap_module_error);
return NULL;
}
+ _Py_try_set_non_inheritable(devzero);
#endif
- } else {
+ }
+ else {
m_obj->fd = dup(fd);
if (m_obj->fd == -1) {
Py_DECREF(m_obj);
PyErr_SetFromErrno(mmap_module_error);
return NULL;
}
+ _Py_try_set_non_inheritable(m_obj->fd);
}
m_obj->data = mmap(NULL, map_size,
diff -r 8aa032b26552 Modules/posixmodule.c
--- a/Modules/posixmodule.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/posixmodule.c Tue Apr 19 14:28:02 2016 +0200
@@ -4855,8 +4855,7 @@ static PyObject *
if (dup2(p_fd[0].rd, 0) == 0)
{
close(p_fd[0].rd);
- i = fcntl(p_fd[0].wr, F_GETFD, 0);
- fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
+ _Py_try_set_non_inheritable(p_fd[0].wr);
if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
{
close(p_fd[0].wr);
@@ -4874,8 +4873,7 @@ static PyObject *
if (dup2(p_fd[1].wr, 1) == 1)
{
close(p_fd[1].wr);
- i = fcntl(p_fd[1].rd, F_GETFD, 0);
- fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
+ _Py_try_set_non_inheritable(p_fd[1].rd);
if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
{
close(p_fd[1].rd);
@@ -4897,8 +4895,7 @@ static PyObject *
if (dup2(p_fd[2].wr, 2) == 2)
{
close(p_fd[2].wr);
- i = fcntl(p_fd[2].rd, F_GETFD, 0);
- fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
+ _Py_try_set_non_inheritable(p_fd[2].rd);
if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
{
close(p_fd[2].rd);
diff -r 8aa032b26552 Modules/zipimport.c
--- a/Modules/zipimport.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Modules/zipimport.c Tue Apr 19 14:28:02 2016 +0200
@@ -725,7 +725,7 @@ read_directory(const char *archive)
}
strcpy(path, archive);
- fp = fopen(archive, "rb");
+ fp = _Py_fopen(archive, "rb");
if (fp == NULL) {
PyErr_Format(ZipImportError, "can't open Zip file: "
"'%.200s'", archive);
@@ -936,7 +936,7 @@ get_data(const char *archive, PyObject *
return NULL;
}
- fp = fopen(archive, "rb");
+ fp = _Py_fopen(archive, "rb");
if (!fp) {
PyErr_Format(PyExc_IOError,
"zipimport: can not open file %s", archive);
diff -r 8aa032b26552 PCbuild/pythoncore.vcxproj
--- a/PCbuild/pythoncore.vcxproj Mon Apr 18 03:45:18 2016 +0000
+++ b/PCbuild/pythoncore.vcxproj Tue Apr 19 14:28:02 2016 +0200
@@ -101,6 +101,7 @@
+
@@ -347,6 +348,7 @@
+
diff -r 8aa032b26552 Python/bltinmodule.c
--- a/Python/bltinmodule.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Python/bltinmodule.c Tue Apr 19 14:28:02 2016 +0200
@@ -794,7 +794,7 @@ builtin_execfile(PyObject *self, PyObjec
if (exists) {
Py_BEGIN_ALLOW_THREADS
- fp = fopen(filename, "r" PY_STDIOTEXTMODE);
+ fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
Py_END_ALLOW_THREADS
if (fp == NULL) {
diff -r 8aa032b26552 Python/errors.c
--- a/Python/errors.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Python/errors.c Tue Apr 19 14:28:02 2016 +0200
@@ -798,7 +798,7 @@ PyErr_ProgramText(const char *filename,
if (filename == NULL || *filename == '\0' || lineno <= 0)
return NULL;
- fp = fopen(filename, "r" PY_STDIOTEXTMODE);
+ fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
if (fp == NULL)
return NULL;
for (i = 0; i < lineno; i++) {
diff -r 8aa032b26552 Python/fileutils.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Python/fileutils.c Tue Apr 19 14:28:02 2016 +0200
@@ -0,0 +1,59 @@
+#include "Python.h"
+
+#ifdef MS_WINDOWS
+# include
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include
+#endif /* HAVE_FCNTL_H */
+
+void
+_Py_try_set_non_inheritable(int fd)
+{
+#ifdef MS_WINDOWS
+ HANDLE handle;
+ DWORD flags;
+
+ if (!_PyVerify_fd(fd)) {
+ return;
+ }
+
+ handle = (HANDLE)_get_osfhandle(fd);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return;
+ }
+
+ (void)SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+#else
+ int attr;
+
+ attr = fcntl(fd, F_GETFD);
+ if (attr < 0) {
+ return;
+ }
+
+ if (attr & FD_CLOEXEC) {
+ /* FD_CLOEXEC flag already set: nothing to do */
+ return;
+ }
+
+ (void)fcntl(fd, F_SETFD, attr | FD_CLOEXEC);
+#endif
+}
+
+FILE*
+_Py_fopen(const char *path, const char *mode)
+{
+ FILE *fp;
+ int fd;
+
+ fp = fopen(path, mode);
+ if (fp == NULL) {
+ return NULL;
+ }
+
+ fd = fileno(fp);
+ _Py_try_set_non_inheritable(fd);
+ return fp;
+}
diff -r 8aa032b26552 Python/import.c
--- a/Python/import.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Python/import.c Tue Apr 19 14:28:02 2016 +0200
@@ -790,9 +790,10 @@ check_compiled_module(char *pathname, ti
long magic;
long pyc_mtime;
- fp = fopen(cpathname, "rb");
+ fp = _Py_fopen(cpathname, "rb");
if (fp == NULL)
return NULL;
+
magic = PyMarshal_ReadLongFromFile(fp);
if (magic != pyc_magic) {
if (Py_VerboseFlag)
@@ -912,10 +913,11 @@ open_exclusive(char *filename, mode_t mo
);
if (fd < 0)
return NULL;
+ _Py_try_set_non_inheritable(fd);
return fdopen(fd, "wb");
#else
/* Best we can do -- on Windows this can't happen anyway */
- return fopen(filename, "wb");
+ return _Py_fopen(filename, "wb");
#endif
}
@@ -3086,9 +3088,10 @@ get_file(char *pathname, PyObject *fob,
if (fob == NULL) {
if (mode[0] == 'U')
mode = "r" PY_STDIOTEXTMODE;
- fp = fopen(pathname, mode);
- if (fp == NULL)
+ fp = _Py_fopen(pathname, mode);
+ if (fp == NULL) {
PyErr_SetFromErrno(PyExc_IOError);
+ }
}
else {
fp = PyFile_AsFile(fob);
diff -r 8aa032b26552 Python/pythonrun.c
--- a/Python/pythonrun.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Python/pythonrun.c Tue Apr 19 14:28:02 2016 +0200
@@ -936,10 +936,13 @@ PyRun_SimpleFileExFlags(FILE *fp, const
/* Try to run a pyc file. First, re-open in binary */
if (closeit)
fclose(fp);
- if ((fp = fopen(filename, "rb")) == NULL) {
+
+ fp = _Py_fopen(filename, "rb");
+ if (fp == NULL) {
fprintf(stderr, "python: Can't reopen .pyc file\n");
goto done;
}
+
/* Turn on optimization if a .pyo file is given */
if (strcmp(ext, ".pyo") == 0)
Py_OptimizeFlag = 1;
diff -r 8aa032b26552 Python/random.c
--- a/Python/random.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Python/random.c Tue Apr 19 14:28:02 2016 +0200
@@ -1,8 +1,8 @@
#include "Python.h"
#ifdef MS_WINDOWS
-#include
+# include
#else
-#include
+# include
#endif
#ifdef Py_DEBUG
@@ -174,6 +174,7 @@ dev_urandom_noraise(unsigned char *buffe
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0)
Py_FatalError("Failed to open /dev/urandom");
+ _Py_try_set_non_inheritable(fd);
while (0 < size)
{
@@ -200,7 +201,6 @@ dev_urandom_python(char *buffer, Py_ssiz
int fd;
Py_ssize_t n;
struct stat st;
- int attr;
if (size <= 0)
return 0;
@@ -234,11 +234,7 @@ dev_urandom_python(char *buffer, Py_ssiz
}
/* try to make the file descriptor non-inheritable, ignore errors */
- attr = fcntl(fd, F_GETFD);
- if (attr >= 0) {
- attr |= FD_CLOEXEC;
- (void)fcntl(fd, F_SETFD, attr);
- }
+ _Py_try_set_non_inheritable(fd);
if (urandom_cache.fd >= 0) {
/* urandom_fd was initialized by another thread while we were
diff -r 8aa032b26552 Python/traceback.c
--- a/Python/traceback.c Mon Apr 18 03:45:18 2016 +0000
+++ b/Python/traceback.c Tue Apr 19 14:28:02 2016 +0200
@@ -128,7 +128,7 @@ int
return -1;
/* This is needed by Emacs' compile command */
#define FMT " File \"%.500s\", line %d, in %.500s\n"
- xfp = fopen(filename, "r" PY_STDIOTEXTMODE);
+ xfp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
if (xfp == NULL) {
/* Search tail of filename in sys.path before giving up */
PyObject *path;
@@ -159,7 +159,7 @@ int
if (len > 0 && namebuf[len-1] != SEP)
namebuf[len++] = SEP;
strcpy(namebuf+len, tail);
- xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE);
+ xfp = _Py_fopen(namebuf, "r" PY_STDIOTEXTMODE);
if (xfp != NULL) {
break;
}