diff options
Diffstat (limited to 'tools')
| -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(); | 
