diff options
-rw-r--r-- | tools/hi-q.c | 158 |
1 files changed, 91 insertions, 67 deletions
diff --git a/tools/hi-q.c b/tools/hi-q.c index 39c68e3..114570f 100644 --- a/tools/hi-q.c +++ b/tools/hi-q.c @@ -299,7 +299,7 @@ bar int kidstatus; int rslt; - int loose_end = 0; + int loose_end = 0; // our original stdin typedef vector<string> VS; vector<jobber> filter; @@ -368,7 +368,7 @@ bar // This makes it safe to assume that nkids-1 is non-negative. if (nkids == 0) exit(0); // nothing to do - if (0 && verbose) for (unsigned int ii = 0; ii < nkids; ii++) { + if (verbose) for (unsigned int ii = 0; ii < nkids; ii++) { cerr << "hi-q filter[" << ii << "] :; "; for (VS::const_iterator token = filter[ii].cmd.begin(); token != filter[ii].cmd.end(); token++){ @@ -397,59 +397,66 @@ bar map<int,int> iiofpid; for (unsigned int ii=0; ii < nkids; ii++){ /* loop starting all kids */ -//xx fprintf(stderr, "Top of loop %d loose: %d\n", ii, loose_end); - + //xx cerr << "top of loop ... loose end " << loose_end << " for " << ii << endl; + if (loose_end > 20) exit(99); int kid_end; - if (filter[ii].mode != stub){ - int datapipe[2]; - - if (loose_end) { - close(0); - dup2(loose_end, 0); - close(loose_end); - } - - // Create a pipe, which will be used to connect - // this child's fd1 to the next child's fd0 ... - // except for the last kid, which reads both fd0 and fd1, - // while writing nothing. - rslt = pipe(datapipe); - if (rslt < 0) { - fprintf(stderr, "hi-q: could not create datapipe: "); - perror(0); - exeunt(ex_syserr); - } - - //xx fprintf(stderr, "pipe: %d %d\n", datapipe[0], datapipe[1]); + int datapipe[2]; + + switch (filter[ii].mode) { + case series: + case qq: + case sa: +// connect *old* loose end to this kid's stdin + //xx cerr << "moving old loose end " << loose_end << " to 0 for " << ii << endl; + if (loose_end) { + close(0); + dup2(loose_end, 0); + close(loose_end); + } + +// Create a pipe, which will be used to connect +// this child's fd1 to the next child's fd0 ... +// except for the last kid, which reads both fd0 and fd1, +// while writing nothing. + rslt = pipe(datapipe); + if (rslt < 0) { + fprintf(stderr, "hi-q: could not create datapipe: "); + perror(0); + exeunt(ex_syserr); + } + break; + case postspam: + case stub: + // do not need to create a pipe + break; + case fail: + cerr << "should never happen: invalid filter" << endl; + exeunt(ex_syserr); + } - // For N-1 kids, the loose end feeds forward. - // It will be written by this kid and read by the next kid. - // For the special kid, the loose end will be its nonstandard input. - // It will be written by us (hi-q) and read by the last kid. +// For N-1 kids, the loose end feeds forward. +// It will be written by this kid and read by the next kid. +// For the special kid, the loose end will be its nonstandard input. +// It will be written by us (hi-q) and read by the last kid. - switch (filter[ii].mode) { - case series: - case sa: - loose_end = datapipe[rEnd]; - kid_end = datapipe[wEnd]; - break; - case qq: - loose_end = datapipe[wEnd]; // reverse of normal "series" case - kid_end = datapipe[rEnd]; // reverse of normal "series" case - break; - case postspam: - case stub: // didn't need a connection at all - cerr << "ignoring fd " << datapipe[wEnd] - << " and " << datapipe[rEnd] - << endl; - xclose(datapipe[wEnd]); - xclose(datapipe[rEnd]); - break; - case fail: - cerr << "should never happen: invalid filter" << endl; - exeunt(ex_syserr); - } + switch (filter[ii].mode) { + case series: + case sa: + loose_end = datapipe[rEnd]; + kid_end = datapipe[wEnd]; + break; + case qq: + loose_end = datapipe[wEnd]; // reverse of normal "series" case + kid_end = datapipe[rEnd]; // reverse of normal "series" case + break; + case postspam: + case stub: + // no pipe even got created. + break; + case fail: + cerr << "should never happen:: invalid filter" << endl; + exeunt(ex_syserr); } kidpid[ii] = fork(); @@ -460,6 +467,7 @@ bar } iiofpid[kidpid[ii]] = ii; if (!kidpid[ii]) { /*** child code ***/ + if (verbose) cerr << "top of kid ... loose end " << loose_end << " for " << ii << endl; pid_t kidgroup(0); // process group for all kids is // equal to pid of kid#0 @@ -488,6 +496,7 @@ bar #endif close(resync[wEnd]); // send resync + //xx cerr << "after sending resync " << ii << endl; // ... now we must wait for everybody else, because ... // ... if we do the exec(), the new process group becomes invalid ... @@ -504,23 +513,38 @@ bar } } - if (filter[ii].mode != stub){ - close(loose_end); // the reading end is none of this kid's business - // except last kid: writing end - - // Note this does an implicit close on the previously-open fd1: - rslt = dup2(kid_end, 1); // the writing end is stdout for this kid - // except last kid: nonstandard input - if (rslt < 0) { - fprintf(stderr, "hi-q: kid %d: dup2(%d,1) failed: ", ii, kid_end); - perror(0); - exit(ex_syserr); - } - - close(kid_end); // use fd1 instead now - // OK, at this point this kid is set up to read fd0 and write fd1 - // (except last kid reads fd1 as well as fd0). + if (0) cerr << "before closing loose end " << loose_end + << " and kid end " << kid_end + << " for " << ii << endl; + switch (filter[ii].mode){ + case sa: + case qq: + case series: + close(loose_end); // the reading end is none of this kid's business + // except last kid: writing end + + // Note this does an implicit close on the previously-open fd1: + rslt = dup2(kid_end, 1); // the writing end is stdout for this kid + // except last kid: nonstandard input + if (rslt < 0) { + fprintf(stderr, "hi-q: kid %d: dup2(%d,1) failed: ", ii, kid_end); + perror(0); + exit(ex_syserr); + } + close(kid_end); // use fd1 instead now + // OK, at this point this kid is set up to read fd0 and write fd1 + // (except last kid reads fd1 as well as fd0). + break; + case stub: + case postspam: + // nothing to do + break; + case fail: + cerr << "should never happen: invalid filter" << endl; + exeunt(ex_syserr); + break; } + //// probe_fd(); int ntok = filter[ii].cmd.size(); |