| 33 |  | time_t  endtime;                /* time we should end by */ | 
| 34 |  | time_t  reporttime;             /* time for next report */ | 
| 35 |  |  | 
| 36 | + | long    maxdisk;                /* maximum file space (bytes) */ | 
| 37 | + |  | 
| 38 |  | int     rtargc = 1;             /* rtrace command */ | 
| 39 |  | char    *rtargv[128] = {"rtrace", NULL}; | 
| 40 |  |  | 
| 129 |  | { | 
| 130 |  | extern int      global_packet(); | 
| 131 |  | register int    i; | 
| 132 | < | /* check output device */ | 
| 133 | < | if (outdev != NULL) | 
| 134 | < | open_display(outdev); | 
| 132 | > |  | 
| 133 | > | if (outdev != NULL)                     /* open output device */ | 
| 134 | > | disp_open(outdev); | 
| 135 |  | else if (ncprocs > 0)                   /* else use global ray feed */ | 
| 136 |  | init_global(); | 
| 137 | + | /* record disk space limit */ | 
| 138 | + | if (!vdef(DISKSPACE)) | 
| 139 | + | maxdisk = 0; | 
| 140 | + | else | 
| 141 | + | maxdisk = 1024.*1024.*vflt(DISKSPACE); | 
| 142 |  | /* record end time */ | 
| 143 |  | if (!vdef(TIME) || vflt(TIME) <= FTINY) | 
| 144 |  | endtime = 0; | 
| 145 |  | else | 
| 146 |  | endtime = starttime + vflt(TIME)*3600.; | 
| 147 |  | /* set up memory cache */ | 
| 148 | < | hdcachesize = 1024.*1024.*vflt(CACHE); | 
| 148 | > | if (outdev == NULL) | 
| 149 | > | hdcachesize = 0;        /* manual flushing */ | 
| 150 | > | else if (vdef(CACHE)) | 
| 151 | > | hdcachesize = 1024.*1024.*vflt(CACHE); | 
| 152 |  | /* open report file */ | 
| 153 |  | if (vdef(REPORT)) { | 
| 154 |  | register char   *s = sskip2(vval(REPORT), 1); | 
| 197 |  | register PACKET *p; | 
| 198 |  | time_t  t; | 
| 199 |  | long    l; | 
| 200 | < | /* check display */ | 
| 201 | < | if (outdev != NULL && !disp_check(idle)) | 
| 202 | < | return(0); | 
| 200 | > |  | 
| 201 | > | if (outdev != NULL)             /* check display */ | 
| 202 | > | if (!disp_check(idle)) | 
| 203 | > | return(0); | 
| 204 |  | /* display only? */ | 
| 205 |  | if (ncprocs <= 0) | 
| 206 |  | return(1); | 
| 207 |  | /* check file size */ | 
| 208 | < | if ((l = 1024.*1024.*vflt(DISKSPACE)) > 0 && | 
| 209 | < | hdfiluse(hdlist[0]->fd, 0) + hdmemuse(0) >= l) | 
| 208 | > | if (maxdisk > 0 && hdfilen(hdlist[0]->fd) >= maxdisk) { | 
| 209 | > | error(WARNING, "file limit exceeded"); | 
| 210 |  | return(0); | 
| 211 | + | } | 
| 212 |  | /* check time */ | 
| 213 |  | if (endtime > 0 || reporttime > 0) | 
| 214 |  | t = time(NULL); | 
| 215 | < | if (endtime > 0 && t >= endtime) | 
| 215 | > | if (endtime > 0 && t >= endtime) { | 
| 216 | > | error(WARNING, "time limit exceeded"); | 
| 217 |  | return(0); | 
| 218 | + | } | 
| 219 |  | if (reporttime > 0 && t >= reporttime) | 
| 220 |  | report(t); | 
| 221 |  | /* get packets to process */ | 
| 300 |  | sprintf(vval(OCTREE), "%s.oct", froot); | 
| 301 |  | vdef(OCTREE)++; | 
| 302 |  | } | 
| 289 | – | if (!vdef(DISKSPACE)) { | 
| 290 | – | sprintf(errmsg, | 
| 291 | – | "no %s setting, assuming 100 Mbytes available", | 
| 292 | – | vnam(DISKSPACE)); | 
| 293 | – | error(WARNING, errmsg); | 
| 294 | – | vval(DISKSPACE) = "100"; | 
| 295 | – | vdef(DISKSPACE)++; | 
| 296 | – | } | 
| 297 | – | if (!vdef(CACHE)) { | 
| 298 | – | sprintf(errmsg, | 
| 299 | – | "no %s setting, assuming 10 Mbytes available", | 
| 300 | – | vnam(CACHE)); | 
| 301 | – | error(WARNING, errmsg); | 
| 302 | – | vval(CACHE) = "10"; | 
| 303 | – | vdef(CACHE)++; | 
| 304 | – | } | 
| 303 |  | if (!vdef(OBSTRUCTIONS)) { | 
| 304 |  | vval(OBSTRUCTIONS) = "T"; | 
| 305 |  | vdef(OBSTRUCTIONS)++; | 
| 318 |  | HDGRID  *gp; | 
| 319 |  | { | 
| 320 |  | long    endloc = 0; | 
| 321 | + | int     fd; | 
| 322 |  | FILE    *fp; | 
| 323 |  | /* open & truncate file */ | 
| 324 |  | if ((fp = fopen(hdkfile, "w+")) == NULL) { | 
| 332 |  | fputc('\n', fp); | 
| 333 |  | putw(HOLOMAGIC, fp);            /* put magic number & terminus */ | 
| 334 |  | fwrite(&endloc, sizeof(long), 1, fp); | 
| 335 | < | fflush(fp);                     /* flush buffer */ | 
| 336 | < | hdinit(fileno(fp), gp);         /* allocate and initialize index */ | 
| 337 | < | /* we're dropping fp here.... */ | 
| 335 | > | fd = dup(fileno(fp)); | 
| 336 | > | fclose(fp);                     /* flush and close stdio stream */ | 
| 337 | > | hdinit(fd, gp);                 /* allocate and initialize index */ | 
| 338 |  | } | 
| 339 |  |  | 
| 340 |  |  | 
| 364 |  |  | 
| 365 |  | loadholo()                      /* start loading a holodeck from fname */ | 
| 366 |  | { | 
| 367 | + | extern long     ftell(); | 
| 368 |  | FILE    *fp; | 
| 369 | < | long    endloc; | 
| 370 | < | /* open input file */ | 
| 371 | < | if ((fp = fopen(hdkfile, "r+")) == NULL) { | 
| 372 | < | sprintf(errmsg, "cannot open \"%s\" for appending", hdkfile); | 
| 369 | > | int     fd; | 
| 370 | > | long    fpos; | 
| 371 | > | /* open holodeck file */ | 
| 372 | > | if ((fp = fopen(hdkfile, ncprocs>0 ? "r+" : "r")) == NULL) { | 
| 373 | > | sprintf(errmsg, "cannot open \"%s\" for %s", hdkfile, | 
| 374 | > | ncprocs>0 ? "appending" : "reading"); | 
| 375 |  | error(SYSTEM, errmsg); | 
| 376 |  | } | 
| 377 |  | /* load variables from header */ | 
| 382 |  | hdkfile); | 
| 383 |  | error(USER, errmsg); | 
| 384 |  | } | 
| 385 | < | fread(&endloc, sizeof(long), 1, fp); | 
| 386 | < | if (endloc != 0) | 
| 385 | > | fread(&fpos, sizeof(long), 1, fp); | 
| 386 | > | if (fpos != 0) | 
| 387 |  | error(WARNING, "ignoring multiple sections in holodeck file"); | 
| 388 | < | fseek(fp, 0L, 1);                       /* align system file pointer */ | 
| 389 | < | hdinit(fileno(fp), NULL);               /* allocate and load index */ | 
| 390 | < | /* we're dropping fp here.... */ | 
| 388 | > | fpos = ftell(fp);                       /* get stdio position */ | 
| 389 | > | fd = dup(fileno(fp)); | 
| 390 | > | fclose(fp);                             /* done with stdio */ | 
| 391 | > | lseek(fd, fpos, 0);                     /* align system file pointer */ | 
| 392 | > | hdinit(fd, NULL);                       /* allocate and load index */ | 
| 393 |  | } | 
| 394 |  |  | 
| 395 |  |  | 
| 396 |  | done_packets(pl)                /* handle finished packets */ | 
| 397 |  | PACKET  *pl; | 
| 398 |  | { | 
| 399 | + | static int      nunflushed = 0; | 
| 400 |  | register PACKET *p; | 
| 401 |  |  | 
| 402 |  | while (pl != NULL) { | 
| 406 |  | (char *)hdnewrays(hdlist[p->hd],p->bi,p->nr), | 
| 407 |  | p->nr*sizeof(RAYVAL)); | 
| 408 |  | if (outdev != NULL)     /* display it */ | 
| 409 | < | disp_packet(p); | 
| 409 | > | disp_packet((PACKHEAD *)p); | 
| 410 | > | else | 
| 411 | > | nunflushed += p->nr; | 
| 412 | > | nraysdone += p->nr; | 
| 413 | > | npacksdone++; | 
| 414 |  | } | 
| 406 | – | nraysdone += p->nr; | 
| 407 | – | npacksdone++; | 
| 415 |  | p->nr = 0;                      /* push onto free list */ | 
| 416 |  | p->next = freepacks; | 
| 417 |  | freepacks = p; | 
| 418 |  | } | 
| 419 | + | if (nunflushed >= 256*RPACKSIZ) { | 
| 420 | + | hdflush(NULL);                  /* flush holodeck buffers */ | 
| 421 | + | nunflushed = 0; | 
| 422 | + | } | 
| 423 |  | } | 
| 424 |  |  | 
| 425 |  |  | 
| 426 |  | getradfile(rfargs)              /* run rad and get needed variables */ | 
| 427 |  | char    *rfargs; | 
| 428 |  | { | 
| 429 | < | static short    mvar[] = {VIEW,OCTREE,EXPOSURE,-1}; | 
| 429 | > | static short    mvar[] = {OCTREE,EXPOSURE,-1}; | 
| 430 |  | static char     tf1[] = TEMPLATE; | 
| 431 |  | char    tf2[64]; | 
| 432 |  | char    combuf[256]; | 
| 525 |  | { | 
| 526 |  | int     status = 0; | 
| 527 |  |  | 
| 528 | + | if (outdev != NULL)             /* close display */ | 
| 529 | + | disp_close(); | 
| 530 |  | if (hdlist[0] != NULL) {        /* flush holodeck */ | 
| 531 |  | if (ncprocs > 0) { | 
| 532 |  | done_packets(flush_queue()); | 
| 535 |  | if (vdef(REPORT)) { | 
| 536 |  | long    fsiz, fuse; | 
| 537 |  | report(0); | 
| 538 | < | fsiz = lseek(hdlist[0]->fd, 0L, 2); | 
| 538 | > | fsiz = hdfilen(hdlist[0]->fd); | 
| 539 |  | fuse = hdfiluse(hdlist[0]->fd, 1); | 
| 540 |  | fprintf(stderr, | 
| 541 |  | "%s: %.1f Mbyte holodeck file, %.1f%% fragmentation\n", |