--- team.c.orig Sat Jul 1 23:33:24 1995 +++ team.c Sat Dec 16 18:34:07 2006 @@ -58,12 +58,14 @@ upstream to it, which has much the same effect. */ -#define TeamLVOLSZ (1L<<10) -#define TeamHVOLSZ ((long unsigned) 3 * ((long unsigned) 1 << 30)) +#define UOFF_T uint64_t + +#define TeamLVOLSZ (UOFF_T)(1L<<10) +#define TeamHVOLSZ ((UOFF_T) 3 * ((UOFF_T) 1 << 62)) #define TeamLBUFSZ (64) /* Low buffer size */ #define TeamDBUFSZ (60*512) /* Default buffer size */ -#define TeamHBUFSZ (1L<<20) /* High buffer size */ +#define TeamHBUFSZ (1L<<26) /* High buffer size */ #define TeamDTEAMSZ 4 /* Default # of processes */ #define TeamHTEAMSZ 16 /* High # of processes */ @@ -84,11 +86,23 @@ #include #include #include +#ifdef HAVE_WAIT_H +#include +#endif + +#ifdef HAVE_PARAM_H +#include +#endif + #ifdef sun # undef F_SETLKW #endif +#ifdef __FreeBSD__ +# undef F_SETLKW +#endif + #if (PCG) # include "Extend.h" # include "Here.h" @@ -160,6 +174,7 @@ local bool verbose = false; local bool report = true; +local bool guyhaderror = false; extern int errno; local time_t origin; @@ -190,7 +205,7 @@ { int fd; short status; - long unsigned size; + UOFF_T size; }; local Fd FdIn,FdOut; @@ -199,7 +214,7 @@ ( fast Fd *fd _ int ffd -_ long unsigned size +_ UOFF_T size ) { fd->status = (ffd >= 0) ? FdOPEN : FdCLOSED; @@ -252,12 +267,12 @@ to->fd = from->fd; } -local long unsigned FdRetry on((fd,which,done,space)) is +local UOFF_T FdRetry on((fd,which,done,space)) is ( fast Fd *fd _ char *which -_ long unsigned done -_ long unsigned space +_ UOFF_T done +_ UOFF_T space ) { int tty; @@ -286,16 +301,21 @@ 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 +340,7 @@ local unsigned FdCanDo on((remaining,available)) is ( fast address remaining -_ fast long unsigned available +_ fast UOFF_T available ) { return (remaining < available) @@ -332,10 +352,10 @@ fast Fd *fd _ pointer buffer _ fast address todo -_ long unsigned done +_ UOFF_T done ) { - fast long unsigned space; + fast UOFF_T space; fast int bytesRead; fast address justDone; @@ -373,10 +393,10 @@ fast Fd *fd _ pointer buffer _ fast address todo -_ long unsigned done +_ UOFF_T done ) { - fast long unsigned space; + fast UOFF_T space; fast int bytesWritten; fast address justDone; @@ -453,7 +473,7 @@ { Token token; short status; - long unsigned done; + UOFF_T done; }; local bool StreamSend on((fd,token,status,done)) is @@ -461,7 +481,7 @@ fast Fd *fd _ Token token _ short status -_ long unsigned done +_ UOFF_T done ) { fast int n; @@ -483,7 +503,7 @@ fast Fd *fd _ Token *tokenp _ short *statusp -_ long unsigned *donep +_ UOFF_T *donep ) { fast int n; @@ -536,7 +556,7 @@ #define GuyRECEIVE(guy,tokenp,statusp,donep) \ StreamReceive(&guy->upStream,tokenp,statusp,donep) -local bool GuyStop of((Guy *,char *,long unsigned)); +local bool GuyStop of((Guy *,char *,UOFF_T)); local bool GuyStart on((guy,bufsize)) is ( @@ -547,8 +567,8 @@ fast char *buffer; Token token; short status; - long unsigned done; - bool received; + UOFF_T done; + bool received; static int bytesRead,bytesWritten; Mesg(("GuyStart guy %#o bufsize %u\n",guy,bufsize)); @@ -577,7 +597,7 @@ 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 +615,7 @@ 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); @@ -619,7 +639,7 @@ ( fast Guy *guy _ char *errormsg -_ long unsigned done +_ UOFF_T done ) { Mesg(("GuyStop guy %#o\n",guy)); @@ -627,8 +647,8 @@ if (done) { if (report) - mesg("%lu kilobytes, %lu seconds\r\n", - done>>10,(long unsigned) (time((time_t *) 0)-origin)); + mesg("%qu kilobytes, %lu seconds\r\n", + done>>10,(UOFF_T) (time((time_t *) 0)-origin)); else if (verbose) mesg("\n"); } @@ -637,7 +657,7 @@ { mesg("team: guy pid %u: %s\n",guy->pid,errormsg); call GuySEND(guy,TokenABORT,FdERROR,0L); - exit(1); + exit(2); /*NOTREACHED*/ } @@ -697,8 +717,8 @@ ( fast Team *team _ address bufsize -_ long unsigned isize -_ long unsigned osize +_ UOFF_T isize +_ UOFF_T osize ) { /* @@ -797,6 +817,9 @@ { 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 +839,13 @@ } } - 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 +887,14 @@ --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; } @@ -914,8 +945,8 @@ 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\ + I is input volume size (default %qum)\n\ + O is output volume size (default %qum)\n\ N is buffer size (default %luk)\n\ P is number of processes (default %u)\n\ (postfix b means *512, k means *1KB, m means *1MB)\n\ @@ -927,19 +958,19 @@ /*NOTREACHED*/ } -local long unsigned atos on((s)) is +local UOFF_T atos on((s)) is ( fast char *s ) { - fast unsigned long l; + fast UOFF_T l; for ( s, l = 0L; *s >= '0' && *s <= '9'; s++ ) - l = l*10L + (long unsigned) (*s-'0'); + l = l*10L + (UOFF_T) (*s-'0'); if (*s == 'b') l *= (1L<<9); if (*s == 'k') l *= (1L<<10); @@ -958,8 +989,8 @@ short unsigned teamsize; address bufsize; - long unsigned isize; - long unsigned osize; + UOFF_T isize; + UOFF_T osize; int opt; teamsize = TeamDTEAMSZ; @@ -975,7 +1006,7 @@ 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 +1014,7 @@ 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(); } @@ -1032,6 +1063,11 @@ 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"); @@ -1052,6 +1088,12 @@ if (!TeamClose(&team)) { mesg("team: cannot close the team\n"); + return 1; + } + + if (guyhaderror) + { + mesg("team: guy had error\n"); return 1; }