summaryrefslogtreecommitdiffstats
path: root/pym/portage.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-09-26 21:07:15 +0000
committerZac Medico <zmedico@gentoo.org>2007-09-26 21:07:15 +0000
commitd1cf25a99a57c67fcc045410d766b6558fbb5cef (patch)
tree77d0c8bb32a2c73d4226db600a70c0300f62e727 /pym/portage.py
parent9016e31b0f17bb7c118edfcf60cf1342958a3fe7 (diff)
downloadportage-d1cf25a99a57c67fcc045410d766b6558fbb5cef.tar.gz
portage-d1cf25a99a57c67fcc045410d766b6558fbb5cef.tar.bz2
portage-d1cf25a99a57c67fcc045410d766b6558fbb5cef.zip
Set non-blocking mode on the pty master file descriptor while
the slave file descriptor is still held open since otherwise the fcntl call can fail on FreeBSD (the child process might have already exited and closed the slave file descriptor so we have to keep it open in order to avoid FreeBSD potentially generating an EAGAIN exception). This approach is cleaner than triggering the exception and being forced to handle it somehow. (trunk r7835) svn path=/main/branches/2.1.2/; revision=7837
Diffstat (limited to 'pym/portage.py')
-rw-r--r--pym/portage.py30
1 files changed, 14 insertions, 16 deletions
diff --git a/pym/portage.py b/pym/portage.py
index b2a2e4a2c..ef8c55893 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -2400,6 +2400,16 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
writemsg("openpty failed: '%s'\n" % str(e), noiselevel=1)
del e
master_fd, slave_fd = os.pipe()
+
+ # We must set non-blocking mode before we close the slave_fd
+ # since otherwise the fcntl call can fail on FreeBSD (the child
+ # process might have already exited and closed slave_fd so we
+ # have to keep it open in order to avoid FreeBSD potentially
+ # generating an EAGAIN exception).
+ import fcntl
+ fcntl.fcntl(master_fd, fcntl.F_SETFL,
+ fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
+
fd_pipes.setdefault(0, sys.stdin.fileno())
fd_pipes_orig = fd_pipes.copy()
if got_pty and os.isatty(fd_pipes_orig[1]):
@@ -2446,7 +2456,7 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
try:
mypids.extend(spawn_func(mystring, env=env, **keywords))
finally:
- if slave_fd:
+ if logfile:
os.close(slave_fd)
if sesandbox:
selinux.setexec(None)
@@ -2461,26 +2471,14 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
iwtd = [master_file]
owtd = []
ewtd = []
- import array, fcntl, select
- fd_flags = {}
- for f in iwtd:
- fd_flags[f] = fcntl.fcntl(f.fileno(), fcntl.F_GETFL)
+ import array, select
buffsize = 65536
eof = False
- # Use non-blocking mode to prevent read
- # calls from blocking indefinitely.
- try:
- fcntl.fcntl(master_file.fileno(), fcntl.F_SETFL,
- fd_flags[master_file] | os.O_NONBLOCK)
- except EnvironmentError, e:
- if e.errno != errno.EAGAIN:
- raise
- del e
- # The EAGAIN error signals eof on FreeBSD.
- eof = True
while not eof:
events = select.select(iwtd, owtd, ewtd)
for f in events[0]:
+ # Use non-blocking mode to prevent read
+ # calls from blocking indefinitely.
buf = array.array('B')
try:
buf.fromfile(f, buffsize)