From 67f618433366316dca8e8c5cdc08e106e268c81a Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 3 Jan 2013 20:16:17 -0800 Subject: Enable FD_CLOEXEC for non-blocking pipes. --- pym/_emerge/AsynchronousLock.py | 13 +++++++++++-- pym/_emerge/EbuildMetadataPhase.py | 13 +++++++++++-- pym/_emerge/FifoIpcDaemon.py | 29 ++++++++++++++++++++++++++++- pym/_emerge/PipeReader.py | 12 ++++++++++-- pym/portage/dbapi/_MergeProcess.py | 11 ++++++++++- pym/portage/util/_async/PipeLogger.py | 12 ++++++++++-- pym/portage/util/_eventloop/EventLoop.py | 13 +++++++++++-- 7 files changed, 91 insertions(+), 12 deletions(-) diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py index 2de1acdcf..fd66a9455 100644 --- a/pym/_emerge/AsynchronousLock.py +++ b/pym/_emerge/AsynchronousLock.py @@ -1,4 +1,4 @@ -# Copyright 2010-2012 Gentoo Foundation +# Copyright 2010-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import dummy_threading @@ -164,8 +164,17 @@ class _LockProcess(AbstractPollTask): self._files = {} self._files['pipe_in'] = in_pr self._files['pipe_out'] = out_pw + + fcntl_flags = os.O_NONBLOCK + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl_flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(in_pr, fcntl.F_SETFL, - fcntl.fcntl(in_pr, fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(in_pr, fcntl.F_GETFL) | fcntl_flags) self._reg_id = self.scheduler.io_add_watch(in_pr, self.scheduler.IO_IN, self._output_handler) self._registered = True diff --git a/pym/_emerge/EbuildMetadataPhase.py b/pym/_emerge/EbuildMetadataPhase.py index 89734e045..4806f5c2d 100644 --- a/pym/_emerge/EbuildMetadataPhase.py +++ b/pym/_emerge/EbuildMetadataPhase.py @@ -1,4 +1,4 @@ -# Copyright 1999-2012 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from _emerge.SubProcess import SubProcess @@ -91,8 +91,17 @@ class EbuildMetadataPhase(SubProcess): files = self._files master_fd, slave_fd = os.pipe() + + fcntl_flags = os.O_NONBLOCK + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl_flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(master_fd, fcntl.F_SETFL, - fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(master_fd, fcntl.F_GETFL) | fcntl_flags) fd_pipes[self._metadata_fd] = slave_fd diff --git a/pym/_emerge/FifoIpcDaemon.py b/pym/_emerge/FifoIpcDaemon.py index 959c00769..113e49da8 100644 --- a/pym/_emerge/FifoIpcDaemon.py +++ b/pym/_emerge/FifoIpcDaemon.py @@ -1,6 +1,12 @@ -# Copyright 2010-2012 Gentoo Foundation +# Copyright 2010-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +try: + import fcntl +except ImportError: + # http://bugs.jython.org/issue1074 + fcntl = None + from portage import os from _emerge.AbstractPollTask import AbstractPollTask from portage.cache.mappings import slot_dict_class @@ -21,6 +27,16 @@ class FifoIpcDaemon(AbstractPollTask): self._files.pipe_in = \ os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK) + if fcntl is not None: + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFL, + fcntl.fcntl(self._files.pipe_in, + fcntl.F_GETFL) | fcntl.FD_CLOEXEC) + self._reg_id = self.scheduler.io_add_watch( self._files.pipe_in, self._registered_events, self._input_handler) @@ -36,6 +52,17 @@ class FifoIpcDaemon(AbstractPollTask): os.close(self._files.pipe_in) self._files.pipe_in = \ os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK) + + if fcntl is not None: + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFL, + fcntl.fcntl(self._files.pipe_in, + fcntl.F_GETFL) | fcntl.FD_CLOEXEC) + self._reg_id = self.scheduler.io_add_watch( self._files.pipe_in, self._registered_events, self._input_handler) diff --git a/pym/_emerge/PipeReader.py b/pym/_emerge/PipeReader.py index 7209e9e93..bb4e0dc1c 100644 --- a/pym/_emerge/PipeReader.py +++ b/pym/_emerge/PipeReader.py @@ -1,4 +1,4 @@ -# Copyright 1999-2012 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from portage import os @@ -26,9 +26,17 @@ class PipeReader(AbstractPollTask): else: output_handler = self._output_handler + fcntl_flags = os.O_NONBLOCK + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl_flags |= fcntl.FD_CLOEXEC + for f in self.input_files.values(): fcntl.fcntl(f.fileno(), fcntl.F_SETFL, - fcntl.fcntl(f.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(f.fileno(), fcntl.F_GETFL) | fcntl_flags) self._reg_ids.add(self.scheduler.io_add_watch(f.fileno(), self._registered_events, output_handler)) self._registered = True diff --git a/pym/portage/dbapi/_MergeProcess.py b/pym/portage/dbapi/_MergeProcess.py index e2534cf9d..1442d56ac 100644 --- a/pym/portage/dbapi/_MergeProcess.py +++ b/pym/portage/dbapi/_MergeProcess.py @@ -114,8 +114,17 @@ class MergeProcess(ForkProcess): """ elog_reader_fd, elog_writer_fd = os.pipe() + + fcntl_flags = os.O_NONBLOCK + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl_flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(elog_reader_fd, fcntl.F_SETFL, - fcntl.fcntl(elog_reader_fd, fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(elog_reader_fd, fcntl.F_GETFL) | fcntl_flags) blockers = None if self.blockers is not None: # Query blockers in the main process, since closing diff --git a/pym/portage/util/_async/PipeLogger.py b/pym/portage/util/_async/PipeLogger.py index 0905e47f9..376ebfef7 100644 --- a/pym/portage/util/_async/PipeLogger.py +++ b/pym/portage/util/_async/PipeLogger.py @@ -1,4 +1,4 @@ -# Copyright 2008-2012 Gentoo Foundation +# Copyright 2008-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import fcntl @@ -38,8 +38,16 @@ class PipeLogger(AbstractPollTask): uid=portage.portage_uid, gid=portage.portage_gid, mode=0o660) + fcntl_flags = os.O_NONBLOCK + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl_flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(self.input_fd, fcntl.F_SETFL, - fcntl.fcntl(self.input_fd, fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.fcntl(self.input_fd, fcntl.F_GETFL) | fcntl_flags) self._reg_id = self.scheduler.io_add_watch(self.input_fd, self._registered_events, self._output_handler) diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py index 6c2341bcd..ad64406c0 100644 --- a/pym/portage/util/_eventloop/EventLoop.py +++ b/pym/portage/util/_eventloop/EventLoop.py @@ -1,4 +1,4 @@ -# Copyright 1999-2012 Gentoo Foundation +# Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import errno @@ -308,9 +308,18 @@ class EventLoop(object): if self._use_signal: if self._sigchld_read is None: self._sigchld_read, self._sigchld_write = os.pipe() + + fcntl_flags = os.O_NONBLOCK + try: + fcntl.FD_CLOEXEC + except AttributeError: + pass + else: + fcntl_flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(self._sigchld_read, fcntl.F_SETFL, fcntl.fcntl(self._sigchld_read, - fcntl.F_GETFL) | os.O_NONBLOCK) + fcntl.F_GETFL) | fcntl_flags) # The IO watch is dynamically registered and unregistered as # needed, since we don't want to consider it as a valid source -- cgit v1.2.3-1-g7c22