From bca3a651575bc2ed35cc8a0a0a1e213892d4620b Mon Sep 17 00:00:00 2001 From: David Wilson Date: Thu, 11 Aug 2016 02:39:29 +0100 Subject: [PATCH] Use set_cloexec() everywhere. --- econtext/core.py | 27 ++++++++++++++++++--------- econtext/master.py | 1 + econtext/utils.py | 2 ++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/econtext/core.py b/econtext/core.py index 0901afc1..ec029cf5 100644 --- a/econtext/core.py +++ b/econtext/core.py @@ -5,6 +5,7 @@ Python external execution contexts. import Queue import cPickle import cStringIO +import fcntl import hmac import imp import logging @@ -74,6 +75,11 @@ class Dead(object): _DEAD = Dead() +def set_cloexec(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) + + def write_all(fd, s): written = 0 while written < len(s): @@ -477,6 +483,8 @@ class Waker(BasicStream): def __init__(self, broker): self._broker = broker rfd, wfd = os.pipe() + set_cloexec(rfd) + set_cloexec(wfd) self.read_side = Side(self, rfd) self.write_side = Side(self, wfd) broker.UpdateStream(self) @@ -494,14 +502,18 @@ class Waker(BasicStream): class IoLogger(BasicStream): _buf = '' - def __init__(self, broker, name): + def __init__(self, broker, name, dest_fd): self._broker = broker self._name = name self._log = logging.getLogger(name) rfd, wfd = os.pipe() + set_cloexec(rfd) + os.dup2(wfd, dest_fd) + os.close(wfd) + self.read_side = Side(self, rfd) - self.write_side = Side(self, wfd) + self.write_side = Side(self, dest_fd) self._broker.UpdateStream(self) def __repr__(self): @@ -655,14 +667,11 @@ class ExternalContext(object): sys.meta_path.append(self.importer) def _SetupStdio(self): - self.stdout_log = IoLogger(self.broker, 'stdout') - self.stderr_log = IoLogger(self.broker, 'stderr') - os.dup2(self.stdout_log.write_side.fd, 1) - os.dup2(self.stderr_log.write_side.fd, 2) + self.stdout_log = IoLogger(self.broker, 'stdout', 1) + self.stderr_log = IoLogger(self.broker, 'stderr', 2) - # Why is this necessary? - sys.stdout = os.fdopen(self.stdout_log.write_side.fd, 'w', 0) - sys.stderr = os.fdopen(self.stderr_log.write_side.fd, 'w', 0) + # Reopen with line buffering. + sys.stdout = open('/dev/stdout', 'w', 1) fp = file('/dev/null') try: diff --git a/econtext/master.py b/econtext/master.py index a2f31fab..7eb6a4e0 100644 --- a/econtext/master.py +++ b/econtext/master.py @@ -49,6 +49,7 @@ class Listener(econtext.core.BasicStream): self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.bind(address or ('0.0.0.0', 0)) self._sock.listen(backlog) + econtext.core.set_cloexec(self._sock.fileno()) self._listen_addr = self._sock.getsockname() self.read_side = econtext.core.Side(self, self._sock.fileno()) broker.UpdateStream(self) diff --git a/econtext/utils.py b/econtext/utils.py index 91671794..c2c109ca 100644 --- a/econtext/utils.py +++ b/econtext/utils.py @@ -2,12 +2,14 @@ import logging import econtext +import econtext.core import econtext.master def log_to_file(path, level=logging.DEBUG): log = logging.getLogger('') fp = open(path, 'w', 1) + econtext.core.set_cloexec(fp.fileno()) log.setLevel(level) log.handlers.insert(0, logging.StreamHandler(fp))