[pypy-commit] pypy py3.5-noninherit: copy the logic from 3.5 to inherit some file descriptors
arigo
pypy.commits at gmail.com
Fri Aug 26 14:03:39 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5-noninherit
Changeset: r86583:f00bf6596800
Date: 2016-08-26 20:03 +0200
http://bitbucket.org/pypy/pypy/changeset/f00bf6596800/
Log: copy the logic from 3.5 to inherit some file descriptors
diff --git a/pypy/module/_posixsubprocess/_posixsubprocess.c b/pypy/module/_posixsubprocess/_posixsubprocess.c
--- a/pypy/module/_posixsubprocess/_posixsubprocess.c
+++ b/pypy/module/_posixsubprocess/_posixsubprocess.c
@@ -106,6 +106,30 @@
}
+RPY_EXTERN
+int rpy_set_inheritable(int fd, int inheritable); /* rposix.py */
+
+static int
+make_inheritable(long *py_fds_to_keep, ssize_t num_fds_to_keep,
+ int errpipe_write)
+{
+ long i;
+
+ for (i = 0; i < num_fds_to_keep; ++i) {
+ long fd = py_fds_to_keep[i];
+ if (fd == errpipe_write) {
+ /* errpipe_write is part of py_fds_to_keep. It must be closed at
+ exec(), but kept open in the child process until exec() is
+ called. */
+ continue;
+ }
+ if (rpy_set_inheritable((int)fd, 1) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+
/* Close all file descriptors in the range start_fd inclusive to
* end_fd exclusive except for those in py_fds_to_keep. If the
* range defined by [start_fd, end_fd) is large this will take a
@@ -329,6 +353,9 @@
/* Buffer large enough to hold a hex integer. We can't malloc. */
char hex_errno[sizeof(saved_errno)*2+1];
+ if (make_inheritable(py_fds_to_keep, num_fds_to_keep, errpipe_write) < 0)
+ goto error;
+
/* Close parent's pipe ends. */
if (p2cwrite != -1) {
POSIX_CALL(close(p2cwrite));
@@ -352,26 +379,25 @@
dup2() removes the CLOEXEC flag but we must do it ourselves if dup2()
would be a no-op (issue #10806). */
if (p2cread == 0) {
- int old = fcntl(p2cread, F_GETFD);
- if (old != -1)
- fcntl(p2cread, F_SETFD, old & ~FD_CLOEXEC);
- } else if (p2cread != -1) {
+ if (rpy_set_inheritable(p2cread, 1) < 0)
+ goto error;
+ }
+ else if (p2cread != -1)
POSIX_CALL(dup2(p2cread, 0)); /* stdin */
+
+ if (c2pwrite == 1) {
+ if (rpy_set_inheritable(c2pwrite, 1) < 0)
+ goto error;
}
- if (c2pwrite == 1) {
- int old = fcntl(c2pwrite, F_GETFD);
- if (old != -1)
- fcntl(c2pwrite, F_SETFD, old & ~FD_CLOEXEC);
- } else if (c2pwrite != -1) {
+ else if (c2pwrite != -1)
POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */
+
+ if (errwrite == 2) {
+ if (rpy_set_inheritable(errwrite, 1) < 0)
+ goto error;
}
- if (errwrite == 2) {
- int old = fcntl(errwrite, F_GETFD);
- if (old != -1)
- fcntl(errwrite, F_SETFD, old & ~FD_CLOEXEC);
- } else if (errwrite != -1) {
+ else if (errwrite != -1)
POSIX_CALL(dup2(errwrite, 2)); /* stderr */
- }
/* Close pipe fds. Make sure we don't close the same fd more than */
/* once, or standard fds. */
diff --git a/pypy/module/_posixsubprocess/_posixsubprocess.h b/pypy/module/_posixsubprocess/_posixsubprocess.h
--- a/pypy/module/_posixsubprocess/_posixsubprocess.h
+++ b/pypy/module/_posixsubprocess/_posixsubprocess.h
@@ -1,3 +1,4 @@
+#include <unistd.h> /* for ssize_t */
#include "src/precommondefs.h"
RPY_EXTERN void
diff --git a/pypy/module/_posixsubprocess/interp_subprocess.py b/pypy/module/_posixsubprocess/interp_subprocess.py
--- a/pypy/module/_posixsubprocess/interp_subprocess.py
+++ b/pypy/module/_posixsubprocess/interp_subprocess.py
@@ -5,6 +5,7 @@
from rpython.rtyper.tool import rffi_platform as platform
from rpython.translator import cdir
from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.rlib import rposix
from pypy.interpreter.error import (
OperationError, exception_from_saved_errno, oefmt, wrap_oserror)
@@ -36,6 +37,7 @@
compile_extra.append("-DHAVE_SETSID")
eci = eci.merge(
+ rposix.eci_inheritable,
ExternalCompilationInfo(
compile_extra=compile_extra))
diff --git a/pypy/module/_posixsubprocess/test/test_subprocess.py b/pypy/module/_posixsubprocess/test/test_subprocess.py
--- a/pypy/module/_posixsubprocess/test/test_subprocess.py
+++ b/pypy/module/_posixsubprocess/test/test_subprocess.py
@@ -75,3 +75,18 @@
n = 1
raises(OverflowError, _posixsubprocess.fork_exec,
1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
+
+ def test_pass_fds_make_inheritable(self):
+ import subprocess, posix
+
+ fd1, fd2 = posix.pipe()
+ assert posix.get_inheritable(fd1) is False
+ assert posix.get_inheritable(fd2) is False
+
+ subprocess.check_call(['/usr/bin/env', 'python', '-c',
+ 'import os;os.write(%d,b"K")' % fd2],
+ close_fds=True, pass_fds=[fd2])
+ res = posix.read(fd1, 1)
+ assert res == b"K"
+ posix.close(fd1)
+ posix.close(fd2)
More information about the pypy-commit
mailing list