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

Comparing ray/src/util/rad.c (file contents):
Revision 2.53 by greg, Thu Mar 20 12:50:07 1997 UTC vs.
Revision 2.66 by greg, Thu Jul 3 15:00:19 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1995 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Executive program for oconv, rpict and pfilt
6   */
7  
8   #include "standard.h"
9 +
10 + #include <ctype.h>
11 +
12 + #include "platform.h"
13 + #include "view.h"
14   #include "paths.h"
15   #include "vars.h"
14 #include <ctype.h>
15 #include <sys/types.h>
16  
17 <                                /* variables */
18 < #define OBJECT          0               /* object files */
19 < #define SCENE           1               /* scene files */
20 < #define MATERIAL        2               /* material files */
21 < #define ILLUM           3               /* mkillum input files */
22 < #define MKILLUM         4               /* mkillum options */
23 < #define RENDER          5               /* rendering options */
24 < #define OCONV           6               /* oconv options */
25 < #define PFILT           7               /* pfilt options */
26 < #define VIEW            8               /* view(s) for picture(s) */
27 < #define ZONE            9               /* simulation zone */
28 < #define QUALITY         10              /* desired rendering quality */
29 < #define OCTREE          11              /* octree file name */
30 < #define PICTURE         12              /* picture file root name */
31 < #define AMBFILE         13              /* ambient file name */
32 < #define OPTFILE         14              /* rendering options file */
33 < #define EXPOSURE        15              /* picture exposure setting */
34 < #define RESOLUTION      16              /* maximum picture resolution */
35 < #define UP              17              /* view up (X, Y or Z) */
36 < #define INDIRECT        18              /* indirection in lighting */
37 < #define DETAIL          19              /* level of scene detail */
38 < #define PENUMBRAS       20              /* shadow penumbras are desired */
39 < #define VARIABILITY     21              /* level of light variability */
40 < #define REPORT          22              /* report frequency and errfile */
41 < #define RAWFILE         23              /* raw picture file root name */
17 >                                /* variables (alphabetical by name) */
18 > #define AMBFILE         0               /* ambient file name */
19 > #define DETAIL          1               /* level of scene detail */
20 > #define EXPOSURE        2               /* picture exposure setting */
21 > #define EYESEP          3               /* interocular distance */
22 > #define ILLUM           4               /* mkillum input files */
23 > #define INDIRECT        5               /* indirection in lighting */
24 > #define MATERIAL        6               /* material files */
25 > #define MKILLUM         7               /* mkillum options */
26 > #define OBJECT          8               /* object files */
27 > #define OCONV           9               /* oconv options */
28 > #define OCTREE          10              /* octree file name */
29 > #define OPTFILE         11              /* rendering options file */
30 > #define PENUMBRAS       12              /* shadow penumbras are desired */
31 > #define PFILT           13              /* pfilt options */
32 > #define PICTURE         14              /* picture file root name */
33 > #define QUALITY         15              /* desired rendering quality */
34 > #define RAWFILE         16              /* raw picture file root name */
35 > #define RENDER          17              /* rendering options */
36 > #define REPORT          18              /* report frequency and errfile */
37 > #define RESOLUTION      19              /* maximum picture resolution */
38 > #define SCENE           20              /* scene files */
39 > #define UP              21              /* view up (X, Y or Z) */
40 > #define VARIABILITY     22              /* level of light variability */
41 > #define VIEWS           23              /* view(s) for picture(s) */
42   #define ZFILE           24              /* distance file root name */
43 + #define ZONE            25              /* simulation zone */
44                                  /* total number of variables */
45 < int NVARS = 25;
45 > int NVARS = 26;
46  
47   VARIABLE        vv[] = {                /* variable-value pairs */
48 <        {"objects",     3,      0,      NULL,   catvalues},
49 <        {"scene",       3,      0,      NULL,   catvalues},
50 <        {"materials",   3,      0,      NULL,   catvalues},
48 >        {"AMBFILE",     3,      0,      NULL,   onevalue},
49 >        {"DETAIL",      3,      0,      NULL,   qualvalue},
50 >        {"EXPOSURE",    3,      0,      NULL,   fltvalue},
51 >        {"EYESEP",      3,      0,      NULL,   fltvalue},
52          {"illum",       3,      0,      NULL,   catvalues},
53 +        {"INDIRECT",    3,      0,      NULL,   intvalue},
54 +        {"materials",   3,      0,      NULL,   catvalues},
55          {"mkillum",     3,      0,      NULL,   catvalues},
56 <        {"render",      3,      0,      NULL,   catvalues},
56 >        {"objects",     3,      0,      NULL,   catvalues},
57          {"oconv",       3,      0,      NULL,   catvalues},
54        {"pfilt",       2,      0,      NULL,   catvalues},
55        {"view",        2,      0,      NULL,   NULL},
56        {"ZONE",        2,      0,      NULL,   onevalue},
57        {"QUALITY",     3,      0,      NULL,   qualvalue},
58          {"OCTREE",      3,      0,      NULL,   onevalue},
59        {"PICTURE",     3,      0,      NULL,   onevalue},
60        {"AMBFILE",     3,      0,      NULL,   onevalue},
59          {"OPTFILE",     3,      0,      NULL,   onevalue},
60 <        {"EXPOSURE",    3,      0,      NULL,   fltvalue},
60 >        {"PENUMBRAS",   3,      0,      NULL,   boolvalue},
61 >        {"pfilt",       2,      0,      NULL,   catvalues},
62 >        {"PICTURE",     3,      0,      NULL,   onevalue},
63 >        {"QUALITY",     3,      0,      NULL,   qualvalue},
64 >        {"RAWFILE",     3,      0,      NULL,   onevalue},
65 >        {"render",      3,      0,      NULL,   catvalues},
66 >        {"REPORT",      3,      0,      NULL,   onevalue},
67          {"RESOLUTION",  3,      0,      NULL,   onevalue},
68 +        {"scene",       3,      0,      NULL,   catvalues},
69          {"UP",          2,      0,      NULL,   onevalue},
65        {"INDIRECT",    3,      0,      NULL,   intvalue},
66        {"DETAIL",      3,      0,      NULL,   qualvalue},
67        {"PENUMBRAS",   3,      0,      NULL,   boolvalue},
70          {"VARIABILITY", 3,      0,      NULL,   qualvalue},
71 <        {"REPORT",      3,      0,      NULL,   onevalue},
70 <        {"RAWFILE",     3,      0,      NULL,   onevalue},
71 >        {"view",        2,      0,      NULL,   NULL},
72          {"ZFILE",       2,      0,      NULL,   onevalue},
73 +        {"ZONE",        2,      0,      NULL,   onevalue},
74   };
75  
76                                  /* overture calculation file */
77 < #ifdef NIX
78 < char    overfile[] = "overture.unf";
77 > #ifdef NULL_DEVICE
78 > char    overfile[] = NULL_DEVICE;
79   #else
80 < char    overfile[] = "/dev/null";
80 > char    overfile[] = "overture.unf";
81   #endif
82  
83 < extern time_t   fdate(), time();
83 > extern time_t   time();
84  
85   time_t  scenedate;              /* date of latest scene or object file */
86   time_t  octreedate;             /* date of octree */
# Line 94 | Line 96 | int    nowarn = 0;             /* no warnings */
96   int     explicate = 0;          /* explicate variables */
97   int     silent = 0;             /* do work silently */
98   int     touchonly = 0;          /* touch files only */
99 < int     noaction = 0;           /* don't do anything */
99 > int     nprocs = 1;             /* maximum executing processes */
100   int     sayview = 0;            /* print view out */
101   char    *rvdevice = NULL;       /* rview output device */
102   char    *viewselect = NULL;     /* specific view only */
103  
104   int     overture = 0;           /* overture calculation needed */
105  
106 + int     children_running = 0;   /* set negative in children */
107 +
108   char    *progname;              /* global argv[0] */
109   char    *rifname;               /* global rad input file name */
110  
111 < char    radname[MAXPATH];       /* root Radiance file name */
111 > char    radname[PATH_MAX];      /* root Radiance file name */
112  
113  
114   main(argc, argv)
# Line 123 | Line 127 | char   *argv[];
127                          silent++;
128                          break;
129                  case 'n':
130 <                        noaction++;
130 >                        nprocs = 0;
131                          break;
132 +                case 'N':
133 +                        nprocs = atoi(argv[++i]);
134 +                        if (nprocs < 0)
135 +                                nprocs = 0;
136 +                        break;
137                  case 't':
138                          touchonly++;
139                          break;
# Line 183 | Line 192 | char   *argv[];
192          quit(0);
193   userr:
194          fprintf(stderr,
195 < "Usage: %s [-s][-n][-t][-e][-V][-v view][-o dev] rfile [VAR=value ..]\n",
195 > "Usage: %s [-w][-s][-n|-N npr][-t][-e][-V][-v view][-o dev] rfile [VAR=value ..]\n",
196                          progname);
197          quit(1);
198   }
# Line 208 | Line 217 | time_t
217   checklast(fnames)                       /* check files and find most recent */
218   register char   *fnames;
219   {
220 <        char    thisfile[MAXPATH];
220 >        char    thisfile[PATH_MAX];
221          time_t  thisdate, lastdate = 0;
213        register char   *cp;
222  
223          if (fnames == NULL)
224                  return(0);
225 <        while (*fnames) {
226 <                while (isspace(*fnames)) fnames++;
227 <                cp = thisfile;
228 <                while (*fnames && !isspace(*fnames))
221 <                        *cp++ = *fnames++;
222 <                *cp = '\0';
225 >        while ((fnames = nextword(thisfile, PATH_MAX, fnames)) != NULL) {
226 >                if (thisfile[0] == '!' ||
227 >                                (thisfile[0] == '\\' && thisfile[1] == '!'))
228 >                        continue;
229                  if (!(thisdate = fdate(thisfile)))
230                          syserr(thisfile);
231                  if (thisdate > lastdate)
# Line 234 | Line 240 | newfname(orig, pred)           /* create modified file name */
240   char    *orig;
241   int     pred;
242   {
237        extern char     *rindex();
243          register char   *cp;
244          register int    n;
245          int     suffix;
# Line 264 | Line 269 | checkfiles()                   /* check for existence and modified tim
269                          syserr(progname);
270                  sprintf(vval(OCTREE), "%s.oct", radname);
271                  vdef(OCTREE)++;
272 +        } else if (vval(OCTREE)[0] == '!') {
273 +                fprintf(stderr, "%s: illegal '%s' specification\n",
274 +                                progname, vnam(OCTREE));
275 +                quit(1);
276          }
277          octreedate = fdate(vval(OCTREE));
278          if (vdef(ILLUM)) {              /* illum requires secondary octrees */
# Line 297 | Line 306 | double org[3], *sizp;
306          register int    i;
307  
308          if (osiz <= FTINY)
309 <                if (noaction && fdate(oct1name) <
309 >                if (!nprocs && fdate(oct1name) <
310                                  (scenedate>illumdate?scenedate:illumdate)) {
311                                                          /* run getbbox */
312                          sprintf(buf, "getbbox -w -h %s",
# Line 338 | Line 347 | double org[3], *sizp;
347  
348   setdefaults()                   /* set default values for unassigned var's */
349   {
350 <        double  org[3], size;
350 >        double  org[3], lim[3], size;
351          char    buf[128];
352  
353          if (!vdef(ZONE)) {
# Line 348 | Line 357 | setdefaults()                  /* set default values for unassigned v
357                  vval(ZONE) = savqstr(buf);
358                  vdef(ZONE)++;
359          }
360 +        if (!vdef(EYESEP)) {
361 +                if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf",
362 +                                &org[0], &lim[0], &org[1], &lim[1],
363 +                                &org[2], &lim[2]) != 6)
364 +                        badvalue(ZONE);
365 +                sprintf(buf, "%f",
366 +                        0.01*(lim[0]-org[0]+lim[1]-org[1]+lim[2]-org[2]));
367 +                vval(EYESEP) = savqstr(buf);
368 +                vdef(EYESEP)++;
369 +        }
370          if (!vdef(INDIRECT)) {
371                  vval(INDIRECT) = "0";
372                  vdef(INDIRECT)++;
# Line 364 | Line 383 | setdefaults()                  /* set default values for unassigned v
383                  vval(PICTURE) = radname;
384                  vdef(PICTURE)++;
385          }
386 <        if (!vdef(VIEW)) {
387 <                vval(VIEW) = "X";
388 <                vdef(VIEW)++;
386 >        if (!vdef(VIEWS)) {
387 >                vval(VIEWS) = "X";
388 >                vdef(VIEWS)++;
389          }
390          if (!vdef(DETAIL)) {
391                  vval(DETAIL) = "M";
# Line 386 | Line 405 | setdefaults()                  /* set default values for unassigned v
405   oconv()                         /* run oconv and mkillum if necessary */
406   {
407          static char     illumtmp[] = "ilXXXXXX";
408 <        char    combuf[1024], ocopts[64], mkopts[64];
408 >        char    combuf[PATH_MAX], ocopts[64], mkopts[64];
409  
410          oconvopts(ocopts);              /* get options */
411          if (octreedate < scenedate) {   /* check date on original octree */
# Line 616 | Line 635 | char   *po;
635                  overture = 0;
636          switch (vscale(VARIABILITY)) {
637          case LOW:
638 <                op = addarg(op, "-aw 128 -aa .4 -ad 64");
638 >                op = addarg(op, "-aa .4 -ad 64");
639                  break;
640          case MEDIUM:
641 <                op = addarg(op, "-aw 1024 -aa .3 -ad 128");
641 >                op = addarg(op, "-aa .3 -ad 128");
642                  break;
643          case HIGH:
644                  op = addarg(op, "-aa .25 -ad 256");
# Line 695 | Line 714 | char   *po;
714                  overture = 0;
715          switch (vscale(VARIABILITY)) {
716          case LOW:
717 <                op = addarg(op, "-aw 128 -aa .25 -ad 196 -as 0");
717 >                op = addarg(op, "-aa .25 -ad 196 -as 0");
718                  break;
719          case MEDIUM:
720 <                op = addarg(op, "-aw 1024 -aa .2 -ad 400 -as 64");
720 >                op = addarg(op, "-aa .2 -ad 400 -as 64");
721                  break;
722          case HIGH:
723                  op = addarg(op, "-aa .15 -ad 768 -as 196");
# Line 771 | Line 790 | char   *po;
790                  overture = 0;
791          switch (vscale(VARIABILITY)) {
792          case LOW:
793 <                op = addarg(op, "-aw 128 -aa .15 -ad 256 -as 0");
793 >                op = addarg(op, "-aa .15 -ad 256 -as 0");
794                  break;
795          case MEDIUM:
796 <                op = addarg(op, "-aw 1024 -aa .125 -ad 512 -as 256");
796 >                op = addarg(op, "-aa .125 -ad 512 -as 256");
797                  break;
798          case HIGH:
799                  op = addarg(op, "-aa .08 -ad 1024 -as 512");
# Line 811 | Line 830 | char   *ro;
830                          syserr(vval(OPTFILE));
831                  sprintf(ro, " @%s", vval(OPTFILE));
832          }
833 < #ifdef MSDOS
833 > #ifdef _WIN32
834          else if (n > 50) {
835                  setenv("ROPT", ro+1);
836                  strcpy(ro, " $ROPT");
# Line 830 | Line 849 | register char  *po;
849          }
850          switch (vscale(QUALITY)) {
851          case MEDIUM:
852 <                po = addarg(po, "-r 1");
852 >                po = addarg(po, "-r .6");
853                  break;
854          case HIGH:
855                  po = addarg(po, "-m .25");
# Line 967 | Line 986 | register char  *vs;
986          if (cp == viewopts)             /* append any additional options */
987                  vs++;           /* skip prefixed space if unneeded */
988          strcpy(cp, vs);
989 < #ifdef MSDOS
989 > #ifdef _WIN32
990          if (strlen(viewopts) > 40) {
991                  setenv("VIEW", viewopts);
992                  return("$VIEW");
# Line 999 | Line 1018 | char   *vn;            /* returned view name */
1018                  }
1019                                                  /* view number? */
1020                  if (isint(viewselect))
1021 <                        return(specview(nvalue(VIEW, atoi(viewselect)-1)));
1021 >                        return(specview(nvalue(VIEWS, atoi(viewselect)-1)));
1022                                                  /* check list */
1023 <                while ((mv = nvalue(VIEW, n++)) != NULL)
1023 >                while ((mv = nvalue(VIEWS, n++)) != NULL)
1024                          if (matchword(viewselect, mv))
1025                                  return(specview(mv));
1026                  return(specview(viewselect));   /* standard view? */
1027          }
1028 <        mv = nvalue(VIEW, n);           /* use view n */
1028 >        mv = nvalue(VIEWS, n);          /* use view n */
1029          if (vn != NULL & mv != NULL) {
1030                  register char   *mv2 = mv;
1031                  if (*mv2 != '-')
# Line 1021 | Line 1040 | char   *vn;            /* returned view name */
1040   printview(vopts)                        /* print out selected view */
1041   register char   *vopts;
1042   {
1043 <        extern char     *atos(), *getenv();
1044 <        char    buf[256];
1026 <        FILE    *fp;
1043 >        VIEW    vwr;
1044 >        char    buf[128];
1045          register char   *cp;
1046 <
1046 > again:
1047          if (vopts == NULL)
1048                  return(-1);
1049 <        fputs("VIEW=", stdout);
1050 <        do {
1051 <                if (matchword(vopts, "-vf")) {          /* expand view file */
1052 <                        vopts = sskip(vopts);
1053 <                        if (!*atos(buf, sizeof(buf), vopts))
1036 <                                return(-1);
1037 <                        if ((fp = fopen(buf, "r")) == NULL)
1038 <                                return(-1);
1039 <                        for (buf[sizeof(buf)-2] = '\n';
1040 <                                        fgets(buf, sizeof(buf), fp) != NULL &&
1041 <                                                buf[0] != '\n';
1042 <                                        buf[sizeof(buf)-2] = '\n') {
1043 <                                if (buf[sizeof(buf)-2] != '\n') {
1044 <                                        ungetc(buf[sizeof(buf)-2], fp);
1045 <                                        buf[sizeof(buf)-2] = '\0';
1046 <                                }
1047 <                                if (matchword(buf, "VIEW=") ||
1048 <                                                matchword(buf, "rview")) {
1049 <                                        for (cp = sskip(buf); *cp && *cp != '\n'; cp++)
1050 <                                                putchar(*cp);
1051 <                                }
1052 <                        }
1053 <                        fclose(fp);
1054 <                        vopts = sskip(vopts);
1055 <                } else {
1056 <                        while (isspace(*vopts))
1057 <                                vopts++;
1058 <                        putchar(' ');
1059 < #ifdef MSDOS
1060 <                        if (*vopts == '$') {            /* expand env. var. */
1061 <                                if (!*atos(buf, sizeof(buf), vopts+1))
1062 <                                        return(-1);
1063 <                                if ((cp = getenv(buf)) == NULL)
1064 <                                        return(-1);
1065 <                                fputs(cp, stdout);
1066 <                                vopts = sskip(vopts);
1067 <                        } else
1049 > #ifdef _WIN32
1050 >        if (vopts[0] == '$') {
1051 >                vopts = getenv(vopts+1);
1052 >                goto again;
1053 >        }
1054   #endif
1055 <                                while (*vopts && !isspace(*vopts))
1056 <                                        putchar(*vopts++);
1057 <                }
1058 <        } while (*vopts++);
1059 <        putchar('\n');
1055 >        copystruct(&vwr, &stdview);
1056 >        sscanview(&vwr, cp=vopts);              /* set initial options */
1057 >        while ((cp = strstr(cp, "-vf ")) != NULL &&
1058 >                        *atos(buf, sizeof(buf), cp += 4)) {
1059 >                viewfile(buf, &vwr, NULL);      /* load -vf file */
1060 >                sscanview(&vwr, cp);            /* reset tail */
1061 >        }
1062 >        fputs(VIEWSTR, stdout);
1063 >        fprintview(&vwr, stdout);               /* print full spec. */
1064 >        fputc('\n', stdout);
1065          return(0);
1066   }
1067  
# Line 1079 | Line 1070 | rview(opts, po)                                /* run rview with first view */
1070   char    *opts, *po;
1071   {
1072          char    *vw;
1073 <        char    combuf[512];
1073 >        char    combuf[PATH_MAX];
1074                                          /* build command */
1075          if (touchonly || (vw = getview(0, NULL)) == NULL)
1076                  return;
# Line 1101 | Line 1092 | char   *opts, *po;
1092   rpict(opts, po)                         /* run rpict and pfilt for each view */
1093   char    *opts, *po;
1094   {
1095 <        char    combuf[1024];
1096 <        char    rawfile[MAXPATH], picfile[MAXPATH];
1097 <        char    zopt[MAXPATH+4], rep[MAXPATH+16], res[32];
1095 >        char    combuf[PATH_MAX];
1096 >        char    rawfile[PATH_MAX], picfile[PATH_MAX];
1097 >        char    zopt[PATH_MAX+4], rep[PATH_MAX+16], res[32];
1098          char    pfopts[128];
1099          char    vs[32], *vw;
1100          int     vn, mult;
# Line 1148 | Line 1139 | char   *opts, *po;
1139                  else
1140                          badvalue(REPORT);
1141          }
1142 <                                        /* do each view */
1152 <        vn = 0;
1142 >        vn = 0;                                 /* do each view */
1143          while ((vw = getview(vn++, vs)) != NULL) {
1144                  if (sayview)
1145                          printview(vw);
# Line 1176 | Line 1166 | char   *opts, *po;
1166                                  touch(picfile);
1167                          continue;
1168                  }
1169 +                if (next_process())             /* parallel running? */
1170 +                        continue;
1171 +                /* XXX Remember to call finish_process() */
1172                                                  /* build rpict command */
1173                  if (rfdt >= oct1date)           /* recover */
1174                          sprintf(combuf, "rpict%s%s%s%s -ro %s %s",
# Line 1192 | Line 1185 | char   *opts, *po;
1185                                                  progname, vs);
1186                                          quit(1);
1187                                  }
1188 < #ifdef NIX
1188 > #ifndef NULL_DEVICE
1189                                  rmfile(overfile);
1190   #endif
1191                          }
# Line 1227 | Line 1220 | char   *opts, *po;
1220                          mvfile(rawfile, combuf);
1221                  } else
1222                          rmfile(rawfile);
1223 +                finish_process();               /* leave if child */
1224          }
1225 +        wait_process(1);                /* wait for children to finish */
1226   }
1227  
1228  
# Line 1236 | Line 1231 | char   *fn;
1231   {
1232          if (!silent)
1233                  printf("\ttouch %s\n", fn);
1234 <        if (noaction)
1234 >        if (!nprocs)
1235                  return(0);
1236   #ifdef notused
1237          if (access(fn, F_OK) == -1)             /* create it */
# Line 1252 | Line 1247 | char   *cs;
1247   {
1248          if (!silent)            /* echo it */
1249                  printf("\t%s\n", cs);
1250 <        if (noaction)
1250 >        if (!nprocs)
1251                  return(0);
1252          fflush(stdout);         /* flush output and pass to shell */
1253          return(system(cs));
# Line 1263 | Line 1258 | rmfile(fn)                     /* remove a file */
1258   char    *fn;
1259   {
1260          if (!silent)
1261 < #ifdef MSDOS
1261 > #ifdef _WIN32
1262                  printf("\tdel %s\n", fn);
1263   #else
1264                  printf("\trm -f %s\n", fn);
1265   #endif
1266 <        if (noaction)
1266 >        if (!nprocs)
1267                  return(0);
1268          return(unlink(fn));
1269   }
# Line 1278 | Line 1273 | mvfile(fold, fnew)             /* move a file */
1273   char    *fold, *fnew;
1274   {
1275          if (!silent)
1276 < #ifdef MSDOS
1276 > #ifdef _WIN32
1277                  printf("\trename %s %s\n", fold, fnew);
1278   #else
1279                  printf("\tmv %s %s\n", fold, fnew);
1280   #endif
1281 <        if (noaction)
1281 >        if (!nprocs)
1282                  return(0);
1283          return(rename(fold, fnew));
1284   }
1285  
1286  
1287 < #ifdef MSDOS
1287 > #ifdef RHAS_FORK_EXEC
1288 > int
1289 > next_process()                  /* fork the next process (max. nprocs) */
1290 > {
1291 >        int     child_pid;
1292 >
1293 >        if (nprocs <= 1)
1294 >                return(0);              /* it's us or no one */
1295 >        if (children_running < 0) {
1296 >                fprintf(stderr, "%s: internal error 1 in spawn_process()\n",
1297 >                                progname);
1298 >                quit(1);
1299 >        }
1300 >        if (children_running >= nprocs)
1301 >                wait_process(0);        /* wait for someone to finish */
1302 >        fflush(stdout);
1303 >        child_pid = fork();             /* split process */
1304 >        if (child_pid == 0) {           /* we're the child */
1305 >                children_running = -1;
1306 >                return(0);
1307 >        }
1308 >        if (child_pid > 0) {            /* we're the parent */
1309 >                ++children_running;
1310 >                return(1);
1311 >        }
1312 >        fprintf(stderr, "%s: warning -- fork() failed\n", progname);
1313 >        return(0);
1314 > }
1315 >
1316 > wait_process(all)                       /* wait for process(es) to finish */
1317 > int     all;
1318 > {
1319 >        int     ourstatus = 0;
1320 >        int     pid, status;
1321 >
1322 >        if (all)
1323 >                all = children_running;
1324 >        else if (children_running > 0)
1325 >                all = 1;
1326 >        while (all-- > 0) {
1327 >                pid = wait(&status);
1328 >                if (pid < 0)
1329 >                        syserr(progname);
1330 >                status = status>>8 & 0xff;
1331 >                --children_running;
1332 >                if (status != 0) {      /* child's problem is our problem */
1333 >                        if (ourstatus == 0 & children_running > 0)
1334 >                                fprintf(stderr, "%s: waiting for remaining processes\n",
1335 >                                                progname);
1336 >                        ourstatus = status;
1337 >                        all = children_running;
1338 >                }
1339 >        }
1340 >        if (ourstatus != 0)
1341 >                quit(ourstatus);        /* bad status from child */
1342 > }
1343 > #else   /* ! RHAS_FORK_EXEC */
1344 > int
1345 > next_process()
1346 > {
1347 >        return(0);                      /* cannot start new process */
1348 > }
1349 > wait_process(all)
1350 > int     all;
1351 > {
1352 >        (void)all;                      /* no one to wait for */
1353 > }
1354 > #endif  /* ! RHAS_FORK_EXEC */
1355 >
1356 > finish_process()                        /* exit a child process */
1357 > {
1358 >        if (children_running >= 0)
1359 >                return;                 /* in parent -- noop */
1360 >        exit(0);
1361 > }
1362 >
1363 > #ifdef _WIN32
1364   setenv(vname, value)            /* set an environment variable */
1365   char    *vname, *value;
1366   {
# Line 1326 | Line 1397 | char   *s;
1397   }
1398  
1399  
1400 + void
1401   quit(ec)                        /* exit program */
1402   int     ec;
1403   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines