Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r13477 - main/branches/2.1.6/pym/_emerge
Date: Thu, 30 Apr 2009 07:02:09
Message-Id: E1LzQHX-0006h4-GD@stork.gentoo.org
1 Author: zmedico
2 Date: 2009-04-30 07:02:06 +0000 (Thu, 30 Apr 2009)
3 New Revision: 13477
4
5 Modified:
6 main/branches/2.1.6/pym/_emerge/__init__.py
7 Log:
8 Bug #264435 - Handle EAGAIN errors when writing to stdout, due to poorly
9 behaved subprocesses that set O_NONBLOCK mode on inherited file descriptors.
10 TODO: When possible, avoid having child processes inherit stdio file
11 descriptors from portage (maybe it can't be avoided with
12 PROPERTIES=interactive). (trunk r13306)
13
14 Modified: main/branches/2.1.6/pym/_emerge/__init__.py
15 ===================================================================
16 --- main/branches/2.1.6/pym/_emerge/__init__.py 2009-04-30 07:01:38 UTC (rev 13476)
17 +++ main/branches/2.1.6/pym/_emerge/__init__.py 2009-04-30 07:02:06 UTC (rev 13477)
18 @@ -2407,8 +2407,41 @@
19
20 if buf:
21 if not self.background:
22 - buf.tofile(files.stdout)
23 - files.stdout.flush()
24 + write_successful = False
25 + failures = 0
26 + while True:
27 + try:
28 + if not write_successful:
29 + buf.tofile(files.stdout)
30 + write_successful = True
31 + files.stdout.flush()
32 + break
33 + except IOError, e:
34 + if e.errno != errno.EAGAIN:
35 + raise
36 + del e
37 + failures += 1
38 + if failures > 50:
39 + # Avoid a potentially infinite loop. In
40 + # most cases, the failure count is zero
41 + # and it's unlikely to exceed 1.
42 + raise
43 +
44 + # This means that a subprocess has put an inherited
45 + # stdio file descriptor (typically stdin) into
46 + # O_NONBLOCK mode. This is not acceptable (see bug
47 + # #264435), so revert it. We need to use a loop
48 + # here since there's a race condition due to
49 + # parallel processes being able to change the
50 + # flags on the inherited file descriptor.
51 + # TODO: When possible, avoid having child processes
52 + # inherit stdio file descriptors from portage
53 + # (maybe it can't be avoided with
54 + # PROPERTIES=interactive).
55 + fcntl.fcntl(files.stdout.fileno(), fcntl.F_SETFL,
56 + fcntl.fcntl(files.stdout.fileno(),
57 + fcntl.F_GETFL) ^ os.O_NONBLOCK)
58 +
59 buf.tofile(files.log)
60 files.log.flush()
61 else: