$NetBSD: patch-ab,v 1.5 2006/07/18 18:03:47 minskim Exp $

--- team.c.orig	1995-07-01 08:33:24.000000000 -0700
+++ 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		*/
@@ -80,15 +80,28 @@ static char Notice[] =
 #include <errno.h>
 #include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #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
 
+#if (defined(BSD) && BSD >= 199306)
+# undef F_SETLKW
+#endif
+
 #if (PCG)
 # include "Extend.h"
 # include "Here.h"
@@ -99,6 +112,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
@@ -160,14 +174,12 @@ mesg(a,b,c,d,e,f,g,h,i)
 
 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 *));
@@ -190,7 +202,7 @@ mode(struct,Fd)
 {
   int 	    fd;
   short	    status;
-  long unsigned   size;
+  unsigned long long   size;
 };
 
 local Fd		FdIn,FdOut;
@@ -199,7 +211,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 +264,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 +298,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 +337,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 +349,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;
 
@@ -373,16 +390,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;
 
@@ -453,7 +470,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 +478,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 +500,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 +553,7 @@ _ Fd			  *downstream
 #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 *,unsigned long long));
 
 local bool		GuyStart on((guy,bufsize)) is
 (
@@ -547,7 +564,7 @@ _ address		  bufsize
   fast char		  *buffer;
   Token 		  token;
   short 		  status;
-  long unsigned		  done;
+  unsigned long long	  done;
   bool		  received;
   static int 		  bytesRead,bytesWritten;
 
@@ -564,7 +581,7 @@ _ address		  bufsize
   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 +594,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 +612,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);
@@ -619,7 +636,7 @@ local bool		GuyStop on((guy,errormsg,don
 (
   fast Guy		  *guy
 _ char			  *errormsg
-_ long unsigned		  done
+_ unsigned long long	  done
 )
 {
   Mesg(("GuyStop guy %#o\n",guy));
@@ -627,8 +644,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, %lu seconds\r\n",
+	  done>>10,(unsigned long long) (time((time_t *) 0)-origin));
     else if (verbose)
       mesg("\n");
   }
@@ -637,7 +654,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 +714,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 +814,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 +836,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 +884,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;
   }
@@ -914,8 +942,8 @@ 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\
+  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 +955,19 @@ syntax: team [-[vr]] [-iI[bkm] [-oO[bkm]
   /*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;
     *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 +986,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 +999,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 +1011,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();
       }
 
@@ -1032,6 +1060,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 +1088,11 @@ _ char			  *(argv[])
     return 1;
   }
 
+  if (guyhaderror)
+  {
+    mesg("team: guy had error\n");
+    return 1;
+  }
+
   return 0;
 }
