--- 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 <sys/file.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#ifdef HAVE_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_PARAM_H
+#include <sys/param.h>
+#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;
   }
 
