Use F_GETFD/F_SETFD for FD_CLOEXEC.
authorZac Medico <zmedico@gentoo.org>
Sun, 1 Sep 2013 19:37:58 +0000 (12:37 -0700)
committerZac Medico <zmedico@gentoo.org>
Sun, 1 Sep 2013 19:37:58 +0000 (12:37 -0700)
This mixup may have caused bug #456296 (see commit
e43524dc88774f768441dcb386a534166a53f7fa).

pym/_emerge/AsynchronousLock.py
pym/_emerge/EbuildMetadataPhase.py
pym/_emerge/FifoIpcDaemon.py
pym/_emerge/PipeReader.py
pym/_emerge/SpawnProcess.py
pym/portage/dbapi/_MergeProcess.py
pym/portage/locks.py
pym/portage/util/_async/PipeLogger.py
pym/portage/util/_eventloop/EventLoop.py

index c2dbf2d3c4311e0e7adb0f1a226a4fa579217a39..cfe98b09f55c77f5658412f08706c686855f299f 100644 (file)
@@ -165,16 +165,17 @@ class _LockProcess(AbstractPollTask):
                self._files['pipe_in'] = in_pr
                self._files['pipe_out'] = out_pw
 
-               fcntl_flags = os.O_NONBLOCK
+               fcntl.fcntl(in_pr, fcntl.F_SETFL,
+                       fcntl.fcntl(in_pr, fcntl.F_GETFL) | os.O_NONBLOCK)
+
                try:
                        fcntl.FD_CLOEXEC
                except AttributeError:
                        pass
                else:
-                       fcntl_flags |= fcntl.FD_CLOEXEC
+                       fcntl.fcntl(in_pr, fcntl.F_SETFD,
+                               fcntl.fcntl(in_pr, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
-               fcntl.fcntl(in_pr, fcntl.F_SETFL,
-                       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
index 7418aba9f7a2a870c6186b84ba6ce281259f81fe..7882b6369191777290ea028cd4624c46f10c449f 100644 (file)
@@ -91,16 +91,16 @@ class EbuildMetadataPhase(SubProcess):
 
                master_fd, slave_fd = os.pipe()
 
-               fcntl_flags = os.O_NONBLOCK
+               fcntl.fcntl(master_fd, fcntl.F_SETFL,
+                       fcntl.fcntl(master_fd, fcntl.F_GETFL) | 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) | fcntl_flags)
+                       fcntl.fcntl(master_fd, fcntl.F_SETFD,
+                               fcntl.fcntl(master_fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                fd_pipes[slave_fd] = slave_fd
                settings["PORTAGE_PIPE_FD"] = str(slave_fd)
index 113e49da8e1bb8cb098c269189c5e92394e626bf..662aec11c8ab0ccc8eb930e793675e9445b0746e 100644 (file)
@@ -33,9 +33,9 @@ class FifoIpcDaemon(AbstractPollTask):
                        except AttributeError:
                                pass
                        else:
-                               fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFL,
+                               fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFD,
                                        fcntl.fcntl(self._files.pipe_in,
-                                               fcntl.F_GETFL) | fcntl.FD_CLOEXEC)
+                                               fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                self._reg_id = self.scheduler.io_add_watch(
                        self._files.pipe_in,
@@ -59,9 +59,9 @@ class FifoIpcDaemon(AbstractPollTask):
                        except AttributeError:
                                pass
                        else:
-                               fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFL,
+                               fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFD,
                                        fcntl.fcntl(self._files.pipe_in,
-                                               fcntl.F_GETFL) | fcntl.FD_CLOEXEC)
+                                               fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                self._reg_id = self.scheduler.io_add_watch(
                        self._files.pipe_in,
index be93be323ac77c8b571880560fb6c752a100f073..c7eef1d79b4b5c38c5303e343e0612997661d9d2 100644 (file)
@@ -26,18 +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():
                        fd = isinstance(f, int) and f or f.fileno()
                        fcntl.fcntl(fd, fcntl.F_SETFL,
-                               fcntl.fcntl(fd, fcntl.F_GETFL) | fcntl_flags)
+                               fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
+                       try:
+                               fcntl.FD_CLOEXEC
+                       except AttributeError:
+                               pass
+                       else:
+                               fcntl.fcntl(fd, fcntl.F_SETFD,
+                                       fcntl.fcntl(fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
                        self._reg_ids.add(self.scheduler.io_add_watch(fd,
                                self._registered_events, output_handler))
                self._registered = True
index 994f3ddbb9dff638b26a83b98f3420cc519f6778..2c2e1a9826d46cd738773f863acfdc7fb753186c 100644 (file)
@@ -19,6 +19,8 @@ from portage.const import BASH_BINARY
 from portage.util._async.PipeLogger import PipeLogger
 
 # On Darwin, FD_CLOEXEC triggers errno 35 for stdout (bug #456296)
+# TODO: Test this again now that it's been fixed to use
+# F_GETFD/F_SETFD instead of F_GETFL/F_SETFL.
 _disable_cloexec_stdout = platform.system() in ("Darwin",)
 
 class SpawnProcess(SubProcess):
@@ -130,12 +132,14 @@ class SpawnProcess(SubProcess):
                                        pass
                                else:
                                        try:
-                                               fcntl.fcntl(stdout_fd, fcntl.F_SETFL,
+                                               fcntl.fcntl(stdout_fd, fcntl.F_SETFD,
                                                        fcntl.fcntl(stdout_fd,
-                                                       fcntl.F_GETFL) | fcntl.FD_CLOEXEC)
+                                                       fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
                                        except IOError:
                                                # FreeBSD may return "Inappropriate ioctl for device"
-                                               # error here (ENOTTY).
+                                               # error here (ENOTTY). TODO: Test this again now that
+                                               # it's been fixed to use F_GETFD/F_SETFD instead of
+                                               # F_GETFL/F_SETFL.
                                                pass
 
                self._pipe_logger = PipeLogger(background=self.background,
index fba61e82f9df86c51b8fb480fcf9aa37b1bfee5c..d7280f082e85bf202619f96dbbf904183f446df1 100644 (file)
@@ -117,16 +117,17 @@ class MergeProcess(ForkProcess):
 
                elog_reader_fd, elog_writer_fd = os.pipe()
 
-               fcntl_flags = os.O_NONBLOCK
+               fcntl.fcntl(elog_reader_fd, fcntl.F_SETFL,
+                       fcntl.fcntl(elog_reader_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
+
                try:
                        fcntl.FD_CLOEXEC
                except AttributeError:
                        pass
                else:
-                       fcntl_flags |= fcntl.FD_CLOEXEC
+                       fcntl.fcntl(elog_reader_fd, fcntl.F_SETFD,
+                               fcntl.fcntl(elog_reader_fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
-               fcntl.fcntl(elog_reader_fd, fcntl.F_SETFL,
-                       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
index 87aaf94a21fd02c9952f96a641796512a0fab6d3..4f356c9c1b948fa2ccfb8812ad0d347a4dbc0d3a 100644 (file)
@@ -239,8 +239,8 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
                except AttributeError:
                        pass
                else:
-                       fcntl.fcntl(myfd, fcntl.F_SETFL,
-                               fcntl.fcntl(myfd, fcntl.F_GETFL) | fcntl.FD_CLOEXEC)
+                       fcntl.fcntl(myfd, fcntl.F_SETFD,
+                               fcntl.fcntl(myfd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                _open_fds.add(myfd)
 
index d0b13237847ecc14506fb10533d4519ec49e068a..06d820097509f2368c427728224290faa28f2302 100644 (file)
@@ -38,21 +38,21 @@ 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
-
                if isinstance(self.input_fd, int):
                        fd = self.input_fd
                else:
                        fd = self.input_fd.fileno()
 
                fcntl.fcntl(fd, fcntl.F_SETFL,
-                       fcntl.fcntl(fd, fcntl.F_GETFL) | fcntl_flags)
+                       fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
+
+               try:
+                       fcntl.FD_CLOEXEC
+               except AttributeError:
+                       pass
+               else:
+                       fcntl.fcntl(fd, fcntl.F_SETFD,
+                               fcntl.fcntl(fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                self._reg_id = self.scheduler.io_add_watch(fd,
                        self._registered_events, self._output_handler)
index 3742055e99136d860ede52e90191439a99c4052e..46a1f09f902610ec2a052729046449b1adc60f4c 100644 (file)
@@ -91,9 +91,9 @@ class EventLoop(object):
                                        except AttributeError:
                                                pass
                                        else:
-                                               fcntl.fcntl(epoll_obj.fileno(), fcntl.F_SETFL,
+                                               fcntl.fcntl(epoll_obj.fileno(), fcntl.F_SETFD,
                                                        fcntl.fcntl(epoll_obj.fileno(),
-                                                               fcntl.F_GETFL) | fcntl.FD_CLOEXEC)
+                                                               fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                                self._poll_obj = _epoll_adapter(epoll_obj)
                                self.IO_ERR = select.EPOLLERR
@@ -315,17 +315,18 @@ class EventLoop(object):
                        if self._sigchld_read is None:
                                self._sigchld_read, self._sigchld_write = os.pipe()
 
-                               fcntl_flags = os.O_NONBLOCK
+                               fcntl.fcntl(self._sigchld_read, fcntl.F_SETFL,
+                                       fcntl.fcntl(self._sigchld_read,
+                                       fcntl.F_GETFL) | 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) | fcntl_flags)
+                                       fcntl.fcntl(self._sigchld_read, fcntl.F_SETFD,
+                                               fcntl.fcntl(self._sigchld_read,
+                                               fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
 
                        # The IO watch is dynamically registered and unregistered as
                        # needed, since we don't want to consider it as a valid source