teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone
Blob Blame History Raw
commit 771993d1fc6db95ae92ebe0200f7003554ea32da
Author: Panu Matilainen <pmatilai@redhat.com>
Date:   Mon Feb 21 08:47:52 2011 +0200

    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

diff --git a/build/rpmfc.c b/build/rpmfc.c
index 56bcb12..29334e2 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;
 	}
     }