Don't use fstat for readable pipe chars in dtexec.
authorMike Stroyan <mike@stroyan.net>
Sun, 9 Sep 2012 21:44:45 +0000 (15:44 -0600)
committerJon Trulson <jon@radscan.com>
Mon, 10 Sep 2012 00:23:45 +0000 (18:23 -0600)
The dtexec code assumes that fstat reports pipe's readable chars.
Linux always reports 0 for st_size of a pipe.
Instead read one character when select reports readable.
Note EOF when select says readable but read returns 0.

cde/programs/dtexec/Main.c

index 3624588711653995607eb06a24f0f40445c1c2af..60c6d2282045daf1ac9853cc40ddceaf94f08996 100644 (file)
@@ -1163,7 +1163,6 @@ main (
     int    junki,i;
     char  *tmpBuffer;
     int    errorBytes;
-    struct stat statBuffer;
     int    firstPass, tmpi;
     char  *tmpProgName = NULL;
 
@@ -1390,28 +1389,31 @@ main (
                    firstPass = 1;
 
                    while (1) {
-                       if ( fstat(errorpipeG[0], &statBuffer) ) {
-                           break;
+                       char buf;
+                       nfound =select(MAXSOCKS, FD_SET_CAST(&readfds), FD_SET_CAST(NULL),
+                            FD_SET_CAST(NULL), &timeoutShort);
+                       if (nfound > 0) {
+                           tmpi = read (errorpipeG[0], &buf, 1);
+                       } else {
+                           tmpi = 0;
                        }
-                       else if ( statBuffer.st_size > 0 ) {
+
+                       if ( tmpi > 0 ) {
                            /*
                             * Grow buffer to hold entire error stream.
                             */
                            firstPass = 0;
                            if (tmpBuffer == NULL)
                                tmpBuffer = (char *) malloc(
-                                               statBuffer.st_size + 1);
+                                               tmpi + 1);
                            else
                                tmpBuffer = (char *) realloc( tmpBuffer,
-                                               errorBytes +
-                                               statBuffer.st_size + 1);
+                                               errorBytes + tmpi + 1);
                            /*
                             * Drain error pipe.
                             */
-                           tmpi = read (errorpipeG[0], &tmpBuffer[errorBytes],
-                                               statBuffer.st_size);
-                           if (tmpi > 0)                       /* else let fstat() redetect problem */
-                               errorBytes += tmpi;
+                           tmpBuffer[errorBytes] = buf;
+                           errorBytes += tmpi;
                            tmpBuffer[errorBytes] = '\0';
 
                            if (errorBytes < 65535) {