#!mkcmd # $Id: tmbuf.m,v 1.6 2008/07/10 19:27:51 ksb Exp $ # # XXX we don't take a max number of lines. # XXX we don't take a max wait time (for first read) from '' from '' from '' from '' from '' from '' from '' from '' require "std_help.m" "std_version.m" basename "tmbuf" "" number { named "iDelay" init "5" param "seconds" help "time to stall between lines (default %qi)" } boolean 'e' { named "bErrOnEOF" init "0" help "exit nonzero at EOF, even if some input was processed" } # allow "minutes option" which is a bad user interface -- ksb function 'm' { hidden update "%rtN = %a;%rtT;%rtn *= 60;" } int 't' { named "iMaxdelay" "pcMaxDelay" init "0" param "seconds" help "total time to delay after first read (default forever)" } exit { named "Pump" } %i static char rcsid[] = "$Id: tmbuf.m,v 1.6 2008/07/10 19:27:51 ksb Exp $"; #if FREEBSD || IBMR2 #include #endif #if !defined(PIPSIZ) #define PIPSIZ 8192 #endif %% %c /* get out if the long term timer goes off (ksb) */ void AlarmHandler(i) int i; { exit(0); } /* batch up messages that are close in time to each other (ksb+wam) */ static void Pump(int dummy) /*ARGSUSED*/ { auto struct timeval tmout; auto fd_set myfdset; auto int fFirst; register int cc, rc; register char *pcCursor; auto char acLine[PIPSIZ]; if (SIG_ERR == signal(SIGALRM, AlarmHandler)) { fprintf(stderr, "%s: signal: %s\n", progname, strerror(errno)); exit(1); } /* Stop on error or EOF but we don't want to exit nonzero * if we've actually done some real data. We'll wait until * we get executed again and fail at the beginning of * the new process. */ fFirst = 1; do { if (0 == (cc = read(0, acLine, sizeof(acLine)))) { exit(bErrOnEOF || fFirst); } if (-1 == cc) { fprintf(stderr, "%s: read: %s\n", progname, strerror(errno)); exit(fFirst); } if (fFirst) { fFirst = 0; alarm(iMaxdelay); } /* if the output is blocked we might have to spin here */ pcCursor = acLine; for (rc = 0; 0 != cc && -1 != rc; pcCursor += rc, cc -= rc) { rc = write(1, pcCursor, cc); } FD_SET(0, & myfdset); tmout.tv_usec = 0; tmout.tv_sec = iDelay; } while (0 < select(1, &myfdset, (fd_set *)0, (fd_set *)0, & tmout)); } %%