$NetBSD: patch-ab,v 1.7 2013/10/04 18:36:16 joerg Exp $ --- team.c.orig 1995-07-01 15:33:24.000000000 +0000 +++ team.c @@ -58,8 +58,8 @@ static char Notice[] = upstream to it, which has much the same effect. */ -#define TeamLVOLSZ (1L<<10) -#define TeamHVOLSZ ((long unsigned) 3 * ((long unsigned) 1 << 30)) +#define TeamLVOLSZ (unsigned long long)(1L<<10) +#define TeamHVOLSZ ((unsigned long long) 3 * ((unsigned long long)1 << 62)) #define TeamLBUFSZ (64) /* Low buffer size */ #define TeamDBUFSZ (60*512) /* Default buffer size */ @@ -77,18 +77,34 @@ static char Notice[] = out for locking and variable number of arguments. */ +#include #include #include #include +#include +#include +#include #include #include #include #include +#ifdef HAVE_WAIT_H +#include +#endif + +#ifdef HAVE_PARAM_H +#include +#endif + #ifdef sun # undef F_SETLKW #endif +#if (defined(BSD) && BSD >= 199306) +# undef F_SETLKW +#endif + #if (PCG) # include "Extend.h" # include "Here.h" @@ -99,6 +115,7 @@ static char Notice[] = # define fast register # define global /* extern */ # define local static +# define When case # define when break; case # define otherwise break; default # define mode(which,name) typedef which name name; which name @@ -137,10 +154,12 @@ static char Notice[] = #endif /*VARARGS1*/ -mesg(a,b,c,d,e,f,g,h,i) - char *a; - int b,c,d,e,f,g,h,i; +__printflike(1, 2) +void +mesg(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); # if (defined F_SETLKW) struct flock l; l.l_whence = 0; l.l_start = 0L; l.l_len = 0L; @@ -149,28 +168,27 @@ mesg(a,b,c,d,e,f,g,h,i) # if (defined LOCK_EX) flock(fileno(stderr),LOCK_EX); # endif - fprintf(stderr,a,b,c,d,e,f,g,h,i); + vfprintf(stderr, fmt, ap); # if (defined LOCK_EX) flock(fileno(stderr),LOCK_UN); # endif # if (defined F_SETLKW) l.l_type = F_UNLCK; fcntl(fileno(stderr),F_SETLKW,&l); # endif + va_end(ap); } local bool verbose = false; local bool report = true; +local bool guyhaderror = false; -extern int errno; local time_t origin; extern time_t time of((time_t *)); extern int atoi of((const char *)); -extern char *malloc of((unsigned)); -extern char *calloc of((address,unsigned)); extern char *strchr of((const char *,int)); -extern int getopt of((int,char *[],const char *)); +/*extern int getopt of((int,char *[],const char *));*/ extern char *optarg; extern int optind; @@ -190,7 +208,7 @@ mode(struct,Fd) { int fd; short status; - long unsigned size; + unsigned long long size; }; local Fd FdIn,FdOut; @@ -199,7 +217,7 @@ local bool FdOpen on((fd,ffd,size)) is ( fast Fd *fd _ int ffd -_ long unsigned size +_ unsigned long long size ) { fd->status = (ffd >= 0) ? FdOPEN : FdCLOSED; @@ -252,12 +270,12 @@ _ fast Fd *from to->fd = from->fd; } -local long unsigned FdRetry on((fd,which,done,space)) is +local unsigned long long FdRetry on((fd,which,done,space)) is ( fast Fd *fd _ char *which -_ long unsigned done -_ long unsigned space +_ unsigned long long done +_ unsigned long long space ) { int tty; @@ -286,16 +304,21 @@ _ long unsigned space do { #if (defined i386 || defined sun) +# if !(defined(BSD) && (BSD >= 199306)) extern char *(sys_errlist[]); +# endif +# if (defined(BSD) && (BSD >= 199306)) && __STDC__ + const +# endif char *errmsg = sys_errlist[errno]; #else char errmsg[32]; (void) sprintf(errmsg,"Error %d",errno); #endif if (errno) - mesg("'%s' on %s after %luk. Continue [cyn] ? ",errmsg,which,done>>10); + mesg("'%s' on %s after %quk. Continue [cyn] ? ",errmsg,which,done>>10); else - mesg("EOF on %s after %luk. Continue [cyn] ? ",which,done>>10); + mesg("EOF on %s after %quk. Continue [cyn] ? ",which,done>>10); read(tty,reply,sizeof reply); } @@ -320,7 +343,7 @@ _ long unsigned space local unsigned FdCanDo on((remaining,available)) is ( fast address remaining -_ fast long unsigned available +_ fast unsigned long long available ) { return (remaining < available) @@ -332,16 +355,16 @@ local address FdRead on((fd,buffer,todo fast Fd *fd _ pointer buffer _ fast address todo -_ long unsigned done +_ unsigned long long done ) { - fast long unsigned space; + fast unsigned long long space; fast int bytesRead; fast address justDone; switch (fd->status) { - when FdEOF: return 0; + When FdEOF: return 0; when FdERROR: return -1; when FdCLOSED: return -1; @@ -365,7 +388,7 @@ _ long unsigned done return (justDone == 0) ? bytesRead : justDone; } - /*NOTREACHED*/ + return -1; } local address FdWrite on((fd,buffer,todo,done)) is @@ -373,16 +396,16 @@ local address FdWrite on((fd,buffer,tod fast Fd *fd _ pointer buffer _ fast address todo -_ long unsigned done +_ unsigned long long done ) { - fast long unsigned space; + fast unsigned long long space; fast int bytesWritten; fast address justDone; switch (fd->status) { - when FdEOF: return 0; + When FdEOF: return 0; when FdERROR: return -1; when FdCLOSED: return -1; @@ -406,7 +429,7 @@ _ long unsigned done return (justDone == 0) ? bytesWritten : justDone; } - /*NOTREACHED*/ + return -1; } /* @@ -453,7 +476,7 @@ mode(struct,StreamMsg) { Token token; short status; - long unsigned done; + unsigned long long done; }; local bool StreamSend on((fd,token,status,done)) is @@ -461,7 +484,7 @@ local bool StreamSend on((fd,token,stat fast Fd *fd _ Token token _ short status -_ long unsigned done +_ unsigned long long done ) { fast int n; @@ -483,7 +506,7 @@ local bool StreamReceive on((fd,tokenp, fast Fd *fd _ Token *tokenp _ short *statusp -_ long unsigned *donep +_ unsigned long long *donep ) { fast int n; @@ -536,7 +559,7 @@ _ Fd *downstream #define GuyRECEIVE(guy,tokenp,statusp,donep) \ StreamReceive(&guy->upStream,tokenp,statusp,donep) -local bool GuyStop of((Guy *,char *,long unsigned)); +local void GuyStop of((Guy *,char *,unsigned long long)); local bool GuyStart on((guy,bufsize)) is ( @@ -547,7 +570,7 @@ _ address bufsize fast char *buffer; Token token; short status; - long unsigned done; + unsigned long long done; bool received; static int bytesRead,bytesWritten; @@ -556,15 +579,15 @@ _ address bufsize buffer = (pointer) malloc((unsigned) bufsize); if (buffer == nil(pointer)) { - mesg("team: guy %d cannot allocate %u bytes\n", - guy->pid,bufsize); + mesg("team: guy %d cannot allocate %llu bytes\n", + guy->pid, (unsigned long long)bufsize); return false; } while ((received = GuyRECEIVE(guy,&token,&status,&done)) && token != TokenSTOP) switch (token) { - when TokenREAD: + When TokenREAD: FdIn.status = status; Mesg(("GuyStart reading %d chars\n",bufsize)); @@ -577,7 +600,7 @@ _ address bufsize done += bytesRead; if (verbose) - mesg("%luk read \r",done>>10); + mesg("%quk read \r",done>>10); if (!GuySEND(guy,TokenREAD,FdIn.status,done)) GuyStop(guy,"guy cannot send READ",done); @@ -595,7 +618,7 @@ _ address bufsize done += bytesWritten; if (verbose) - mesg("%luk written\r",done>>10); + mesg("%quk written\r",done>>10); if (!GuySEND(guy,TokenWRITE,FdOut.status,done)) GuyStop(guy,"guy cannot send WRITE",done); @@ -611,15 +634,14 @@ _ address bufsize GuyStop(guy,(received) ? nil(char *) : "error on upstream receive",0L); /*NOTREACHED*/ - - /*return true;*/ + exit(0); } -local bool GuyStop on((guy,errormsg,done)) is +local void GuyStop on((guy,errormsg,done)) is ( fast Guy *guy _ char *errormsg -_ long unsigned done +_ unsigned long long done ) { Mesg(("GuyStop guy %#o\n",guy)); @@ -627,8 +649,8 @@ _ long unsigned done if (done) { if (report) - mesg("%lu kilobytes, %lu seconds\r\n", - done>>10,(long unsigned) (time((time_t *) 0)-origin)); + mesg("%qu kilobytes, %llu seconds\r\n", + done>>10,(unsigned long long) (time((time_t *) 0)-origin)); else if (verbose) mesg("\n"); } @@ -637,7 +659,7 @@ _ long unsigned done { mesg("team: guy pid %u: %s\n",guy->pid,errormsg); call GuySEND(guy,TokenABORT,FdERROR,0L); - exit(1); + exit(2); /*NOTREACHED*/ } @@ -697,8 +719,8 @@ local bool TeamStart on((team,bufsize,i ( fast Team *team _ address bufsize -_ long unsigned isize -_ long unsigned osize +_ unsigned long long isize +_ unsigned long long osize ) { /* @@ -797,6 +819,9 @@ _ long unsigned osize { pid = getpid(); + /* Set SIGPIPE handling back to the default in the guys */ + signal(SIGPIPE, SIG_DFL); + if (!FdClose(&last_downstream)) perror("cannot close inherited first link"); @@ -816,13 +841,13 @@ _ long unsigned osize } } - if (!StreamSend(&last_downstream,TokenREAD,FdOPEN,0L)) + if (!StreamSend(&last_downstream,TokenREAD,FdOPEN,0L) && errno != EPIPE) { perror("cannot send first READ token"); return false; } - if (!StreamSend(&last_downstream,TokenWRITE,FdOPEN,0L)) + if (!StreamSend(&last_downstream,TokenWRITE,FdOPEN,0L) && errno != EPIPE) { perror("cannot send first WRITE token"); return false; @@ -864,6 +889,14 @@ local bool TeamWait on((team)) is --team->active; +#ifdef WIFEXITED + /* If a guy had an error, its exit status is 2. Also catch a killed guy */ + if ((WIFEXITED(status) && WEXITSTATUS(status) == 2) || + (WIFSIGNALED(status) && WTERMSIG(status) != SIGPIPE)) { + guyhaderror = true; + } +#endif + if (status != 0 && team->active != 0) return false; } @@ -900,8 +933,7 @@ local bool TeamClose on((team)) is fast Team *team ) { - for (team->size; team->size != 0; --team->size) - continue; + team->size = 0; free(team->guys); @@ -914,32 +946,32 @@ local void usage of((noparms)) syntax: team [-[vr]] [-iI[bkm] [-oO[bkm] [N[bkm] [P]]\n\ copies standard input to output\n\ -v gives ongoing report, -r final report\n\ - I is input volume size (default %lum)\n\ - O is output volume size (default %lum)\n\ - N is buffer size (default %luk)\n\ + I is input volume size (default %qum)\n\ + O is output volume size (default %qum)\n\ + N is buffer size (default %lluk)\n\ P is number of processes (default %u)\n\ (postfix b means *512, k means *1KB, m means *1MB)\n\ ", TeamHVOLSZ>>20,TeamHVOLSZ>>20, - TeamDBUFSZ>>10,TeamDTEAMSZ); + (unsigned long long)(TeamDBUFSZ>>10),TeamDTEAMSZ); exit(1); /*NOTREACHED*/ } -local long unsigned atos on((s)) is +local unsigned long long atos on((s)) is ( fast char *s ) { - fast unsigned long l; + fast unsigned long long l; for ( - s, l = 0L; + l = 0L; *s >= '0' && *s <= '9'; s++ ) - l = l*10L + (long unsigned) (*s-'0'); + l = l*10L + (unsigned long long) (*s-'0'); if (*s == 'b') l *= (1L<<9); if (*s == 'k') l *= (1L<<10); @@ -958,8 +990,8 @@ _ char *(argv[]) short unsigned teamsize; address bufsize; - long unsigned isize; - long unsigned osize; + unsigned long long isize; + unsigned long long osize; int opt; teamsize = TeamDTEAMSZ; @@ -971,11 +1003,11 @@ _ char *(argv[]) while ((opt = getopt(argc,argv,"vri:o:")) != -1) switch (opt) { - when 'i': + When 'i': isize = atos(optarg); if (isize < TeamLVOLSZ || isize > TeamHVOLSZ) { - fprintf(stderr,"team: invalid input volume size %lu\n",isize); + fprintf(stderr,"team: invalid input volume size %qu\n",isize); usage(); } @@ -983,7 +1015,7 @@ _ char *(argv[]) osize = atos(optarg); if (osize < TeamLVOLSZ || osize > TeamHVOLSZ) { - fprintf(stderr,"team: invalid output volume size %lu\n",osize); + fprintf(stderr,"team: invalid output volume size %qu\n",osize); usage(); } @@ -1004,8 +1036,8 @@ _ char *(argv[]) bufsize = (address) atos(argv[0]); if (bufsize < TeamLBUFSZ || bufsize > TeamHBUFSZ) { - fprintf(stderr,"team: invalid block size %u\n", - bufsize); + fprintf(stderr,"team: invalid block size %llu\n", + (unsigned long long)bufsize); usage(); } --argc, argv++; @@ -1032,6 +1064,11 @@ _ char *(argv[]) origin = time((time_t *) 0); + /* + * Ignore SIGPIPE in the parent as it affects the exit status reporting. + */ + signal(SIGPIPE, SIG_IGN); + if (!TeamStart(&team,bufsize,isize,osize)) { mesg("team: cannot start the team\n"); @@ -1055,5 +1092,11 @@ _ char *(argv[]) return 1; } + if (guyhaderror) + { + mesg("team: guy had error\n"); + return 1; + } + return 0; }