diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2011-02-21 08:47:52 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2011-02-28 11:57:21 +0200 |
commit | e195a85ea4a6153d0851653e02fa70aff1bbb651 (patch) | |
tree | 887725cb9be253c67d41c83f00df6d42ea2b1ce3 | |
parent | a89e10461a2503ca329225bbf6c71ae9e19313e3 (diff) | |
download | rpm-e195a85ea4a6153d0851653e02fa70aff1bbb651.tar.gz |
Fix braindamage in the depgen helper collector loop (RhBug:675002)
- Read any remaining data before exiting on SIGCHLD
- Only perform one read() per loop, otherwise it could block
- Handle EINTR while read()'ing
(cherry picked from commit 771993d1fc6db95ae92ebe0200f7003554ea32da)
-rw-r--r-- | build/rpmfc.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/build/rpmfc.c b/build/rpmfc.c index 56bcb1242..29334e23f 100644 --- a/build/rpmfc.c +++ b/build/rpmfc.c @@ -272,12 +272,6 @@ static StringBuf getOutputFrom(ARGV_t argv, break; } - /* Child exited, we're done */ - if (FD_ISSET(sigpipe, &ibits)) { - while (read(sigpipe, buf, sizeof(buf)) > 0) {}; - break; - } - /* Write data to child */ if (writeBytesLeft > 0 && FD_ISSET(toProg[1], &obits)) { size_t nb = (1024 < writeBytesLeft) ? 1024 : writeBytesLeft; @@ -293,11 +287,20 @@ static StringBuf getOutputFrom(ARGV_t argv, /* Read when we get data back from the child */ if (FD_ISSET(fromProg[0], &ibits)) { - int nbr; - while ((nbr = read(fromProg[0], buf, sizeof(buf)-1)) > 0) { - buf[nbr] = '\0'; - appendStringBuf(readBuff, buf); + int nbr = read(fromProg[0], buf, sizeof(buf)-1); + if (nbr < 0 && errno == EINTR) continue; + if (nbr < 0) { + myerrno = errno; + break; } + buf[nbr] = '\0'; + appendStringBuf(readBuff, buf); + } + + /* Child exited, we're done */ + if (FD_ISSET(sigpipe, &ibits)) { + while (read(sigpipe, buf, sizeof(buf)) > 0) {}; + break; } } |