ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/ranimate.c
(Generate patch)

Comparing ray/src/util/ranimate.c (file contents):
Revision 2.1 by greg, Fri Jan 12 12:16:17 1996 UTC vs.
Revision 2.4 by greg, Mon Jan 22 17:19:37 1996 UTC

# Line 9 | Line 9 | static char SCCSid[] = "$SunId$ LBL";
9   */
10  
11   #include "standard.h"
12 + #include <ctype.h>
13   #include <sys/types.h>
14   #include <sys/stat.h>
15   #include "view.h"
16   #include "vars.h"
17 + #include "netproc.h"
18                                  /* input variables */
19   #define HOST            0               /* rendering host machine */
20   #define RENDER          1               /* rendering options */
# Line 87 | Line 89 | char   rresopt[32];            /* rendering resolution options */
89   char    fresopt[32];            /* filter resolution options */
90   int     pfiltalways;            /* always use pfilt? */
91  
92 + struct pslot {
93 +        int     pid;                    /* process ID (0 if empty) */
94 +        int     fout;                   /* output frame number */
95 +        int     (*rcvf)();              /* recover function */
96 + }       *pslot;                 /* process slots */
97 + int     npslots;                /* number of process slots */
98 +
99 + int     lastpid;                /* ID of last completed background process */
100 + PSERVER *lastpserver;           /* last process server used */
101 +
102 + #define phostname(ps)   ((ps)->hostname[0] ? (ps)->hostname : astat.host)
103 +
104 + struct pslot    *findpslot();
105 +
106   VIEW    *getview();
107   char    *getexp();
108  
# Line 138 | Line 154 | char   *argv[];
154                                                  /* print variables */
155          if (explicate)
156                  printvars(stdout);
157 +                                                /* set up process servers */
158 +        sethosts();
159                                                  /* run animation */
160          animate();
161                                                  /* all done */
# Line 145 | Line 163 | char   *argv[];
163                  argv[i] = vval(NEXTANIM);       /* just change input file */
164                  if (!silent)
165                          printargs(argc, argv, stdout);
166 <                if (!noaction) {
167 <                        execvp(progname, argv);         /* pass to next */
150 <                        quit(1);                        /* shouldn't return */
151 <                }
166 >                execvp(progname, argv);         /* pass to next */
167 >                quit(1);                        /* shouldn't return */
168          }
169          quit(0);
170   userr:
# Line 222 | Line 238 | putastat()                     /* put out current status */
238          char    buf[256];
239          FILE    *fp;
240  
241 +        if (noaction)
242 +                return;
243          sprintf(buf, "%s/%s", vval(DIRECTORY), SFNAME);
244          if ((fp = fopen(buf, "w")) == NULL) {
245                  perror(buf);
# Line 263 | Line 281 | setdefaults()                  /* set default values */
281   {
282          char    buf[256];
283  
284 <        if (vdef(OCTREE) == vdef(ANIMATE)) {
284 >        if (vdef(ANIMATE)) {
285 >                vval(OCTREE) = NULL;
286 >                vdef(OCTREE) = 0;
287 >        } else if (!vdef(OCTREE)) {
288                  fprintf(stderr, "%s: either %s or %s must be defined\n",
289                                  progname, vnam(OCTREE), vnam(ANIMATE));
290                  quit(1);
# Line 272 | Line 293 | setdefaults()                  /* set default values */
293                  fprintf(stderr, "%s: %s undefined\n", progname, vnam(VIEWFILE));
294                  quit(1);
295          }
296 +        if (!vdef(HOST)) {
297 +                vval(HOST) = LHOSTNAME;
298 +                vdef(HOST)++;
299 +        }
300          if (!vdef(START)) {
301                  vval(START) = "1";
302                  vdef(START)++;
# Line 320 | Line 345 | setdefaults()                  /* set default values */
345   }
346  
347  
348 + sethosts()                      /* set up process servers */
349 + {
350 +        extern char     *iskip();
351 +        char    buf[256], *dir, *uname;
352 +        int     np;
353 +        register char   *cp;
354 +        int     i;
355 +
356 +        npslots = 0;
357 +        if (noaction)
358 +                return;
359 +        for (i = 0; i < vdef(HOST); i++) {      /* add each host */
360 +                dir = uname = NULL;
361 +                np = 1;
362 +                strcpy(cp=buf, nvalue(HOST, i));        /* copy to buffer */
363 +                cp = sskip(cp);                         /* skip host name */
364 +                while (isspace(*cp))
365 +                        *cp++ = '\0';
366 +                if (*cp) {                              /* has # processes? */
367 +                        np = atoi(cp);
368 +                        if ((cp = iskip(cp)) == NULL || (*cp && !isspace(*cp)))
369 +                                badvalue(HOST);
370 +                        while (isspace(*cp))
371 +                                cp++;
372 +                        if (*cp) {                      /* has directory? */
373 +                                dir = cp;
374 +                                cp = sskip(cp);                 /* skip dir. */
375 +                                while (isspace(*cp))
376 +                                        *cp++ = '\0';
377 +                                if (*cp) {                      /* has user? */
378 +                                        uname = cp;
379 +                                        if (*sskip(cp))
380 +                                                badvalue(HOST);
381 +                                }
382 +                        }
383 +                }
384 +                if (addpserver(buf, dir, uname, np) == NULL) {
385 +                        if (!nowarn)
386 +                                fprintf(stderr,
387 +                                        "%s: cannot execute on host \"%s\"\n",
388 +                                                progname, buf);
389 +                } else
390 +                        npslots += np;
391 +        }
392 +        if (npslots == 0) {
393 +                fprintf(stderr, "%s: no working process servers\n", progname);
394 +                quit(1);
395 +        }
396 +        pslot = (struct pslot *)calloc(npslots, sizeof(struct pslot));
397 +        if (pslot == NULL) {
398 +                perror("malloc");
399 +                quit(1);
400 +        }
401 + }
402 +
403 +
404   getradfile(rfname)              /* run rad and get needed variables */
405   char    *rfname;
406   {
# Line 406 | Line 487 | animate()                      /* run animation */
487                  astat.rnext = astat.fnext = astat.tnext = vint(START);
488          putastat();
489                                          /* render in batches */
490 <        while (astat.rnext <= vint(END)) {
490 >        while (astat.tnext <= vint(END)) {
491                  renderframes(frames_batch);
492                  filterframes();
493                  transferframes();
# Line 466 | Line 547 | int    nframes;
547                  }
548          }
549          if (vdef(ANIMATE))              /* wait for renderings to finish */
550 <                animwait(0);
550 >                bwait(0);
551          else {                          /* else if walk-through */
552                  fclose(fp);             /* close view file */
553                  walkwait(astat.rnext, lastframe, vfname);       /* walk it */
554                  unlink(vfname);         /* remove view file */
555          }
475        if (vdef(ARCHIVE))              /* archive results */
476                archive(astat.rnext, lastframe);
556          astat.rnext = i;                /* update status */
557          putastat();
558   }
# Line 494 | Line 573 | filterframes()                         /* catch up with filtering */
573                                          progname, i);
574                          quit(1);
575                  }
576 <                dofilt(i, vp, getexp(i));               /* filter frame */
576 >                dofilt(i, vp, getexp(i), 0);            /* filter frame */
577          }
578 <        filtwait(0);                    /* wait for filter processes */
578 >        bwait(0);                       /* wait for filter processes */
579 >        archive(astat.fnext, i-1);      /* archive originals */
580          astat.fnext = i;                /* update status */
581          putastat();
582   }
# Line 539 | Line 619 | animrend(frame, vp)                    /* start animation frame */
619   int     frame;
620   VIEW    *vp;
621   {
622 +        extern int      recover();
623          char    combuf[2048];
624          char    fname[128];
625  
# Line 546 | Line 627 | VIEW   *vp;
627          strcat(fname, ".unf");
628          if (access(fname, F_OK) == 0)
629                  return;
630 <        sprintf(combuf, "%s %d | rpict%s%s %s > %s", vval(ANIMATE), frame,
630 >        sprintf(combuf, "%s %d | rpict%s%s -w0 %s > %s", vval(ANIMATE), frame,
631                          rendopt, viewopt(vp), rresopt, fname);
632 <        if (runcom(combuf)) {
552 <                fprintf(stderr, "%s: error rendering frame %d\n",
553 <                                progname, frame);
554 <                quit(1);
555 <        }
632 >        bruncom(combuf, frame, recover);        /* run in background */
633   }
634  
635  
559 animwait(nwait)                         /* wait for renderings to finish */
560 int     nwait;
561 {
562        /* currently does nothing since parallel rendering not working */
563 }
564
565
636   walkwait(first, last, vfn)              /* walk-through frames */
637   int     first, last;
638   char    *vfn;
639   {
640          char    combuf[2048];
641 +        char    *inspoint;
642          register int    i;
643  
644          if (!noaction && vint(INTERP))          /* create dummy frames */
# Line 578 | Line 649 | char   *vfn;
649                                  close(open(combuf, O_RDONLY|O_CREAT, 0666));
650                          }
651                                          /* create command */
652 <        sprintf(combuf, "rpict%s ", rendopt);
652 >        sprintf(combuf, "rpict%s -w0", rendopt);
653          if (vint(INTERP) || atoi(vval(MBLUR)))
654 <                sprintf(combuf+strlen(combuf), "-z %s.zbf ", vval(BASENAME));
655 <        sprintf(combuf+strlen(combuf), "-o %s.unf %s -S %d %s < %s",
656 <                        vval(BASENAME), rresopt, first, vval(OCTREE), vfn);
657 <        if (runcom(combuf)) {
658 <                fprintf(stderr,
659 <                "%s: error rendering walk-through frames %d through %d\n",
654 >                sprintf(combuf+strlen(combuf), " -z %s.zbf", vval(BASENAME));
655 >        sprintf(combuf+strlen(combuf), " -o %s.unf %s -S %d",
656 >                        vval(BASENAME), rresopt, first);
657 >        inspoint = combuf + strlen(combuf);
658 >        sprintf(inspoint, " %s < %s", vval(OCTREE), vfn);
659 >                                        /* run in parallel */
660 >        if (pruncom(combuf, inspoint, (last-first+1)/(vint(INTERP)+1))) {
661 >                fprintf(stderr, "%s: error rendering frames %d through %d\n",
662                                  progname, first, last);
663                  quit(1);
664          }
# Line 599 | Line 672 | char   *vfn;
672   }
673  
674  
675 + int
676   recover(frame)                          /* recover the specified frame */
677   int     frame;
678   {
679 +        static int      *rfrm;          /* list of recovered frames */
680 +        static int      nrfrms = 0;
681          char    combuf[2048];
682          char    fname[128];
683          register char   *cp;
684 <
684 >        register int    i;
685 >                                        /* check to see if recovered already */
686 >        for (i = nrfrms; i--; )
687 >                if (rfrm[i] == frame)
688 >                        return(0);
689 >                                        /* build command */
690          sprintf(fname, vval(BASENAME), frame);
691          if (vdef(ANIMATE))
692 <                sprintf(combuf, "%s %d | rpict%s",
692 >                sprintf(combuf, "%s %d | rpict%s -w0",
693                                  vval(ANIMATE), frame, rendopt);
694          else
695 <                sprintf(combuf, "rpict%s", rendopt);
695 >                sprintf(combuf, "rpict%s -w0", rendopt);
696          cp = combuf + strlen(combuf);
697          if (vint(INTERP) || atoi(vval(MBLUR))) {
698                  sprintf(cp, " -z %s.zbf", fname);
# Line 623 | Line 704 | int    frame;
704                  *cp++ = ' ';
705                  strcpy(cp, vval(OCTREE));
706          }
707 <        if (runcom(combuf)) {
708 <                fprintf(stderr, "%s: error recovering frame %d\n",
709 <                                progname, frame);
707 >        if (runcom(combuf))             /* run command */
708 >                return(1);
709 >                                        /* add frame to recovered list */
710 >        if (nrfrms)
711 >                rfrm = (int *)realloc((char *)rfrm, (nrfrms+1)*sizeof(int));
712 >        else
713 >                rfrm = (int *)malloc(sizeof(int));
714 >        if (rfrm == NULL) {
715 >                perror("malloc");
716                  quit(1);
717          }
718 +        rfrm[nrfrms++] = frame;
719 +        return(0);
720   }
721  
722  
723 < archive(first, last)                    /* archive finished renderings */
723 > int
724 > frecover(frame)                         /* recover filtered frame */
725 > int     frame;
726 > {
727 >        VIEW    *vp;
728 >        char    *ex;
729 >
730 >        vp = getview(frame);
731 >        ex = getexp(frame);
732 >        if (dofilt(frame, vp, ex, 2) && dofilt(frame, vp, ex, 1))
733 >                return(1);
734 >        return(0);
735 > }
736 >
737 >
738 > archive(first, last)                    /* archive and remove renderings */
739   int     first, last;
740   {
741 + #define RMCOML  (sizeof(rmcom)-1)
742 +        static char     rmcom[] = "rm -f";
743 +        int     offset = RMCOML;
744          char    combuf[10240];
638        int     offset;
745          struct stat     stb;
746          register char   *cp;
747          register int    i;
748  
749 <        strcpy(cp=combuf, vval(ARCHIVE));
750 <        while (*cp) cp++;
751 <        offset = cp - combuf;
749 >        if (noaction)
750 >                return;
751 >        if (vdef(ARCHIVE) && strlen(vval(ARCHIVE)) > offset)
752 >                offset = strlen(vval(ARCHIVE));
753 >        cp = combuf + offset;
754          *cp++ = ' ';                            /* make argument list */
755          for (i = first; i <= last; i++) {
756                  sprintf(cp, vval(BASENAME), i);
# Line 661 | Line 769 | int    first, last;
769          *--cp = '\0';
770          if (cp <= combuf + offset)              /* no files? */
771                  return;
772 <        if (runcom(combuf)) {                   /* run archive command */
773 <                fprintf(stderr,
772 >        if (vdef(ARCHIVE)) {                    /* run archive command */
773 >                i = strlen(vval(ARCHIVE));
774 >                strncpy(combuf+offset-i, vval(ARCHIVE), i);
775 >                if (runcom(combuf+offset-i)) {
776 >                        fprintf(stderr,
777                  "%s: error running archive command on frames %d through %d\n",
778 <                                progname, first, last);
779 <                quit(1);
778 >                                        progname, first, last);
779 >                        quit(1);
780 >                }
781          }
782 +                                                /* run remove command */
783 +        strncpy(combuf+offset-RMCOML, rmcom, RMCOML);
784 +        runcom(combuf+offset-RMCOML);
785 + #undef RMCOML
786   }
787  
788  
789 < dofilt(frame, vp, ep)                           /* filter frame */
789 > int
790 > dofilt(frame, vp, ep, rvr)                      /* filter frame */
791   int     frame;
792   VIEW    *vp;
793   char    *ep;
794 + int     rvr;
795   {
796 +        extern int      frecover();
797          char    fnbefore[128], fnafter[128];
798          char    combuf[1024], fname[128];
799          int     usepinterp, usepfilt;
800 <        int     frbefore, frafter, triesleft;
800 >        int     frseq[2];
801                                                  /* check what is needed */
802          usepinterp = atoi(vval(MBLUR));
803          usepfilt = pfiltalways | ep==NULL;
804                                                  /* compute rendered views */
805 <        frbefore = frame - ((frame-1) % (vint(INTERP)+1));
806 <        frafter = frbefore + vint(INTERP) + 1;
807 <        if (frafter > vint(END))
808 <                frafter = vint(END);
809 <        if (frafter == frame) {                 /* pfilt only */
810 <                frbefore = frafter;
805 >        frseq[0] = frame - ((frame-1) % (vint(INTERP)+1));
806 >        frseq[1] = frseq[0] + vint(INTERP) + 1;
807 >        if (frseq[1] > vint(END))
808 >                frseq[1] = vint(END);
809 >        if (frseq[1] == frame) {                        /* pfilt only */
810 >                frseq[0] = frseq[1];
811                  usepinterp = 0;                 /* update what's needed */
812                  usepfilt |= vflt(OVERSAMP)>1.01 || strcmp(ep,"1");
813 <                triesleft = 2;
695 <        } else if (frbefore == frame) {         /* no interpolation */
696 <                                                /* remove unneeded files */
697 <                if (frbefore-vint(INTERP)-1 >= 1) {
698 <                        sprintf(fname, vval(BASENAME), frbefore-vint(INTERP)-1);
699 <                        sprintf(combuf, "rm -f %s.unf %s.zbf", fname, fname);
700 <                        runcom(combuf);
701 <                }
813 >        } else if (frseq[0] == frame) {         /* no interpolation */
814                                                  /* update what's needed */
815 <                if (usepinterp)
704 <                        triesleft = 3;
705 <                else {
815 >                if (!usepinterp)
816                          usepfilt |= vflt(OVERSAMP)>1.01 || strcmp(ep,"1");
817 <                        triesleft = 2;
708 <                }
709 <        } else {                                /* interpolation needed */
817 >        } else                                  /* interpolation needed */
818                  usepinterp++;
819 <                triesleft = 3;
820 <        }
821 <        if (frafter >= astat.rnext) {           /* next batch unavailable */
822 <                frafter = frbefore;
823 <                if (triesleft > 2)
824 <                        triesleft = 2;
825 <        }
718 <        sprintf(fnbefore, vval(BASENAME), frbefore);
719 <        sprintf(fnafter, vval(BASENAME), frafter);
720 < tryit:                                          /* generate command */
819 >        if (frseq[1] >= astat.rnext)            /* next batch unavailable */
820 >                frseq[1] = frseq[0];
821 >        sprintf(fnbefore, vval(BASENAME), frseq[0]);
822 >        sprintf(fnafter, vval(BASENAME), frseq[1]);
823 >        if (rvr == 1 && recover(frseq[0]))      /* recover before frame? */
824 >                return(1);
825 >                                                /* generate command */
826          if (usepinterp) {                       /* using pinterp */
827 +                if (rvr == 2 && recover(frseq[1]))      /* recover after? */
828 +                        return(1);
829                  if (atoi(vval(MBLUR))) {
830                          FILE    *fp;            /* motion blurring */
831                          sprintf(fname, "%s/vw0", vval(DIRECTORY));
# Line 743 | Line 850 | tryit:                                         /* generate command */
850                          putc('\n', fp); fclose(fp);
851                          sprintf(combuf,
852          "(pmblur %s %d %s/vw0 %s/vw1; rm -f %s/vw0 %s/vw1) | pinterp -B",
853 <                                *sskip(vval(MBLUR)) ? sskip(vval(MBLUR)) : "1",
853 >                        *sskip(vval(MBLUR)) ? sskip2(vval(MBLUR),1) : "1",
854                                          atoi(vval(MBLUR)), vval(DIRECTORY),
855                                          vval(DIRECTORY), vval(DIRECTORY),
856                                          vval(DIRECTORY), vval(DIRECTORY));
# Line 751 | Line 858 | tryit:                                         /* generate command */
858                          strcpy(combuf, "pinterp");
859                  strcat(combuf, viewopt(vp));
860                  if (vbool(RTRACE))
861 <                        sprintf(combuf+strlen(combuf), " -ff -fr '%s %s'",
861 >                        sprintf(combuf+strlen(combuf), " -ff -fr '%s -w0 %s'",
862                                          rendopt, vval(OCTREE));
863                  if (vdef(PINTERP))
864                          sprintf(combuf+strlen(combuf), " %s", vval(PINTERP));
# Line 762 | Line 869 | tryit:                                         /* generate command */
869                                          fresopt, ep);
870                  sprintf(combuf+strlen(combuf), " %s.unf %s.zbf",
871                                  fnbefore, fnbefore);
872 <                if (frafter != frbefore)
872 >                if (frseq[1] != frseq[0])
873                           sprintf(combuf+strlen(combuf), " %s.unf %s.zbf",
874                                          fnafter, fnafter);
875                  if (usepfilt) {                 /* also pfilt */
# Line 778 | Line 885 | tryit:                                         /* generate command */
885                                  sprintf(combuf+strlen(combuf), " %s", fresopt);
886                  }
887          } else if (usepfilt) {                  /* pfilt only */
888 +                if (rvr == 2)
889 +                        return(1);
890                  if (vdef(PFILT))
891                          sprintf(combuf, "pfilt %s", vval(PFILT));
892                  else
# Line 789 | Line 898 | tryit:                                         /* generate command */
898                          sprintf(combuf+strlen(combuf), " %s %s.unf",
899                                          fresopt, fnbefore);
900          } else {                                /* else just check it */
901 +                if (rvr == 2)
902 +                        return(1);
903                  sprintf(combuf, "ra_rgbe -r %s.unf", fnbefore);
904          }
905                                                  /* output file name */
906          sprintf(fname, vval(BASENAME), frame);
907          sprintf(combuf+strlen(combuf), " > %s.pic", fname);
908 <        if (runcom(combuf))                     /* run filter command */
909 <                switch (--triesleft) {
910 <                case 2:                         /* try to recover frafter */
911 <                        recover(frafter);
801 <                        goto tryit;
802 <                case 1:                         /* try to recover frbefore */
803 <                        recover(frbefore);
804 <                        goto tryit;
805 <                default:                        /* we've really failed */
806 <                        fprintf(stderr,
807 <                        "%s: unrecoverable filtering error on frame %d\n",
808 <                                        progname, frame);
809 <                        quit(1);
810 <                }
908 >        if (rvr)                                /* in recovery */
909 >                return(runcom(combuf));
910 >        bruncom(combuf, frame, frecover);       /* else run in background */
911 >        return(0);
912   }
913  
914  
814 filtwait(nwait)                 /* wait for filtering processes to finish */
815 int     nwait;
816 {
817        /* currently does nothing since parallel filtering not working */
818 }
819
820
915   VIEW *
916   getview(n)                      /* get view number n */
917   int     n;
# Line 937 | Line 1031 | int    n;
1031   }
1032  
1033  
1034 < runcom(cs)                      /* run command */
1034 > struct pslot *
1035 > findpslot(pid)                  /* find or allocate a process slot */
1036 > int     pid;
1037 > {
1038 >        register struct pslot   *psempty = NULL;
1039 >        register int    i;
1040 >
1041 >        for (i = 0; i < npslots; i++) {         /* look for match */
1042 >                if (pslot[i].pid == pid)
1043 >                        return(pslot+i);
1044 >                if (psempty == NULL && pslot[i].pid == 0)
1045 >                        psempty = pslot+i;
1046 >        }
1047 >        return(psempty);                /* return emtpy slot (error if NULL) */
1048 > }
1049 >
1050 >
1051 > int
1052 > donecom(ps, pn, status)         /* clean up after finished process */
1053 > PSERVER *ps;
1054 > int     pn;
1055 > int     status;
1056 > {
1057 >        register PROC   *pp;
1058 >
1059 >        pp = ps->proc + pn;
1060 >        if (pp->elen) {                 /* pass errors */
1061 >                if (ps->hostname[0])
1062 >                        fprintf(stderr, "%s: ", ps->hostname);
1063 >                fprintf(stderr, "Error output from: %s\n", pp->com);
1064 >                fputs(pp->errs, stderr);
1065 >                fflush(stderr);
1066 >                if (ps->hostname[0])
1067 >                        status = 1;     /* because rsh doesn't return status */
1068 >        }
1069 >        freestr(pp->com);               /* free command string */
1070 >        lastpid = pp->pid;              /* record PID for bwait() */
1071 >        lastpserver = ps;               /* record server for serverdown() */
1072 >        return(status);
1073 > }
1074 >
1075 >
1076 > int
1077 > serverdown()                    /* check status of last process server */
1078 > {
1079 >        if (pserverOK(lastpserver))     /* server still up? */
1080 >                return(0);
1081 >        delpserver(lastpserver);        /* else delete it */
1082 >        if (pslist == NULL) {
1083 >                fprintf(stderr, "%s: all process servers are down\n",
1084 >                                progname);
1085 >                quit(1);
1086 >        }
1087 >        return(1);
1088 > }
1089 >
1090 >
1091 > int
1092 > bruncom(com, fout, rf)          /* run a command in the background */
1093 > char    *com;
1094 > int     fout;
1095 > int     (*rf)();
1096 > {
1097 >        int     pid;
1098 >        register struct pslot   *psl;
1099 >
1100 >        if (!silent)
1101 >                printf("\t%s &\n", com);        /* echo command */
1102 >        if (noaction)
1103 >                return(0);
1104 >        fflush(stdout);
1105 >                                        /* else start it when we can */
1106 >        while ((pid = startjob(NULL, savestr(com), donecom)) == -1)
1107 >                bwait(1);
1108 >        if (!silent) {
1109 >                PSERVER *ps;
1110 >                int     psn = pid;
1111 >                ps = findjob(&psn);
1112 >                printf("\tProcess started on %s\n", phostname(ps));
1113 >                fflush(stdout);
1114 >        }
1115 >        psl = findpslot(pid);           /* record info. in appropriate slot */
1116 >        psl->pid = pid;
1117 >        psl->fout = fout;
1118 >        psl->rcvf = rf;
1119 >        return(pid);
1120 > }
1121 >
1122 >
1123 > bwait(ncoms)                            /* wait for batch job(s) to finish */
1124 > int     ncoms;
1125 > {
1126 >        int     status;
1127 >        register struct pslot   *psl;
1128 >
1129 >        if (noaction)
1130 >                return;
1131 >        while ((status = wait4job(NULL, -1)) != -1) {
1132 >                psl = findpslot(lastpid);
1133 >                if (status) {           /* attempt recovery */
1134 >                        serverdown();   /* check server */
1135 >                        if (psl->rcvf == NULL || (*psl->rcvf)(psl->fout)) {
1136 >                                fprintf(stderr,
1137 >                                        "%s: error rendering frame %d\n",
1138 >                                                progname, psl->fout);
1139 >                                quit(1);
1140 >                        }
1141 >                }
1142 >                psl->pid = 0;           /* free process slot */
1143 >                if (!--ncoms)
1144 >                        return;         /* done enough */
1145 >        }
1146 > }
1147 >
1148 >
1149 > int
1150 > pruncom(com, ppins, maxcopies)  /* run a command in parallel over network */
1151 > char    *com, *ppins;
1152 > int     maxcopies;
1153 > {
1154 >        int     retstatus = 0;
1155 >        int     hostcopies;
1156 >        char    com1buf[10240], *com1, *endcom1;
1157 >        int     status;
1158 >        register PSERVER        *ps;
1159 >
1160 >        if (!silent)
1161 >                printf("\t%s &\n", com);        /* echo command */
1162 >        if (noaction)
1163 >                return(0);
1164 >        fflush(stdout);
1165 >                                        /* start jobs on each server */
1166 >        for (ps = pslist; ps != NULL; ps = ps->next) {
1167 >                hostcopies = 0;
1168 >                if (maxcopies > 1 && ps->nprocs > 1 && ppins != NULL) {
1169 >                        strcpy(com1=com1buf, com);      /* build -PP command */
1170 >                        sprintf(com1+(ppins-com), " -PP %s/%s.persist",
1171 >                                        vval(DIRECTORY), phostname(ps));
1172 >                        strcat(com1, ppins);
1173 >                        endcom1 = com1 + strlen(com1);
1174 >                        sprintf(endcom1, "; kill `sed -n '1s/^[^ ]* //p' %s/%s.persist`",
1175 >                                        vval(DIRECTORY), phostname(ps));
1176 >                } else {
1177 >                        com1 = com;
1178 >                        endcom1 = NULL;
1179 >                }
1180 >                while (maxcopies > 0 &&
1181 >                                startjob(ps, savestr(com1), donecom) != -1) {
1182 >                        sleep(10);
1183 >                        hostcopies++;
1184 >                        maxcopies--;
1185 >                        if (endcom1 != NULL)
1186 >                                *endcom1 = '\0';
1187 >                }
1188 >                if (!silent && hostcopies) {
1189 >                        if (hostcopies > 1)
1190 >                                printf("\t%d duplicate processes", hostcopies);
1191 >                        else
1192 >                                printf("\tProcess");
1193 >                        printf(" started on %s\n", phostname(ps));
1194 >                        fflush(stdout);
1195 >                }
1196 >        }
1197 >                                        /* wait for jobs to finish */
1198 >        while ((status = wait4job(NULL, -1)) != -1)
1199 >                if (status)
1200 >                        retstatus += !serverdown();     /* check server */
1201 >        return(retstatus);
1202 > }
1203 >
1204 >
1205 > runcom(cs)                      /* run a command locally and wait for it */
1206   char    *cs;
1207   {
1208          if (!silent)            /* echo it */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines