summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-07-22 21:19:50 -0700
committerJohn Denker <jsd@av8n.com>2012-07-22 21:19:50 -0700
commitc5d0c7e88a27bcbd976a1ce56a31318b587bd8ff (patch)
tree818344941edf660dbf2ec610c89067b27c80b0b0
parent8164bf28464ad3e7628c422d6f02e3b515702d12 (diff)
change from if-statements to switch-statements, to make sure all cases get handled
-rw-r--r--tools/hi-q.c158
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();