- Timestamp:
- Jan 17, 2007, 8:48:23 PM (14 years ago)
- Location:
- zzuf/trunk/src
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
zzuf/trunk/src/Makefile.am
r1683 r1692 4 4 5 5 bin_PROGRAMS = zzuf 6 zzuf_SOURCES = zzuf.c $(COMMON) md5.c md5.h timer.c timer.h6 zzuf_SOURCES = zzuf.c $(COMMON) opts.c opts.h md5.c md5.h timer.c timer.h 7 7 zzuf_CFLAGS = -DLIBDIR=\"$(libdir)/zzuf\" 8 8 zzuf_LDFLAGS = @MATH_LIBS@ -
zzuf/trunk/src/zzuf.c
r1681 r1692 39 39 40 40 #include "libzzuf.h" 41 #include "opts.h" 41 42 #include "random.h" 42 43 #include "fd.h" … … 45 46 #include "timer.h" 46 47 47 static void loop_stdin( void);48 49 static void spawn_children( void);50 static void clean_children( void);51 static void read_children( void);48 static void loop_stdin(struct opts *opts); 49 50 static void spawn_children(struct opts *opts); 51 static void clean_children(struct opts *opts); 52 static void read_children(struct opts *opts); 52 53 53 54 static char const *sig2str(int); … … 60 61 #endif 61 62 62 static struct child_list63 {64 enum status65 {66 STATUS_FREE,67 STATUS_RUNNING,68 STATUS_SIGTERM,69 STATUS_SIGKILL,70 STATUS_EOF,71 } status;72 73 pid_t pid;74 int fd[3]; /* 0 is debug, 1 is stderr, 2 is stdout */75 int bytes, seed;76 double ratio;77 int64_t date;78 struct md5 *ctx;79 } *child_list;80 static int maxforks = 1, child_count = 0, maxcrashes = 1, crashes = 0;81 82 static char **newargv;83 static char *protect = NULL, *refuse = NULL;84 static uint32_t seed = DEFAULT_SEED;85 static uint32_t endseed = DEFAULT_SEED + 1;86 static double minratio = DEFAULT_RATIO;87 static double maxratio = DEFAULT_RATIO;88 static int quiet = 0;89 static int maxbytes = -1;90 static int md5 = 0;91 static int checkexit = 0;92 static int verbose = 0;93 static int maxmem = -1;94 static int64_t maxtime = -1;95 static int64_t delay = 0;96 static int64_t lastlaunch = 0;97 98 63 #define ZZUF_FD_SET(fd, p_fdset, maxfd) \ 99 64 if(fd >= 0) \ … … 109 74 int main(int argc, char *argv[]) 110 75 { 111 char *parser, *include, *exclude; 76 struct opts _opts, *opts = &_opts; 77 char *tmp, *include, *exclude; 112 78 int i, cmdline = 0; 113 79 114 80 include = exclude = NULL; 81 82 _zz_opts_init(opts); 115 83 116 84 #if defined(HAVE_GETOPT_H) … … 164 132 break; 165 133 case 'B': /* --max-bytes */ 166 maxbytes = atoi(optarg);134 opts->maxbytes = atoi(optarg); 167 135 break; 168 136 case 'c': /* --cmdline */ … … 170 138 break; 171 139 case 'C': /* --max-crashes */ 172 maxcrashes = atoi(optarg);173 if( maxcrashes <= 0)174 maxcrashes = 0;140 opts->maxcrashes = atoi(optarg); 141 if(opts->maxcrashes <= 0) 142 opts->maxcrashes = 0; 175 143 break; 176 144 case 'd': /* --debug */ … … 178 146 break; 179 147 case 'D': /* --delay */ 180 delay = (int64_t)(atof(optarg) * 1000000.0);148 opts->delay = (int64_t)(atof(optarg) * 1000000.0); 181 149 break; 182 150 case 'E': /* --exclude */ … … 185 153 { 186 154 printf("%s: invalid regex -- `%s'\n", argv[0], optarg); 155 _zz_opts_fini(opts); 187 156 return EXIT_FAILURE; 188 157 } 189 158 break; 190 159 case 'F': /* --max-forks */ 191 maxforks= atoi(optarg) > 1 ? atoi(optarg) : 1;160 opts->maxchild = atoi(optarg) > 1 ? atoi(optarg) : 1; 192 161 break; 193 162 case 'i': /* --stdin */ … … 199 168 { 200 169 printf("%s: invalid regex -- `%s'\n", argv[0], optarg); 170 _zz_opts_fini(opts); 201 171 return EXIT_FAILURE; 202 172 } 203 173 break; 204 174 case 'm': /* --md5 */ 205 md5 = 1;175 opts->md5 = 1; 206 176 break; 207 177 case 'M': /* --max-memory */ 208 178 setenv("ZZUF_MEMORY", "1", 1); 209 maxmem = atoi(optarg);179 opts->maxmem = atoi(optarg); 210 180 break; 211 181 case 'n': /* --network */ … … 213 183 break; 214 184 case 'P': /* --protect */ 215 protect = optarg;185 opts->protect = optarg; 216 186 break; 217 187 case 'q': /* --quiet */ 218 quiet = 1;188 opts->quiet = 1; 219 189 break; 220 190 case 'r': /* --ratio */ 221 parser= strchr(optarg, ':');222 minratio = atof(optarg);223 maxratio = parser ? atof(parser + 1) :minratio;191 tmp = strchr(optarg, ':'); 192 opts->minratio = atof(optarg); 193 opts->maxratio = tmp ? atof(tmp + 1) : opts->minratio; 224 194 break; 225 195 case 'R': /* --refuse */ 226 refuse = optarg;196 opts->refuse = optarg; 227 197 break; 228 198 case 's': /* --seed */ 229 parser= strchr(optarg, ':');230 seed = atol(optarg);231 endseed = parser ? (uint32_t)atoi(parser + 1) :seed + 1;199 tmp = strchr(optarg, ':'); 200 opts->seed = atol(optarg); 201 opts->endseed = tmp ? (uint32_t)atoi(tmp + 1) : opts->seed + 1; 232 202 break; 233 203 case 'S': /* --signal */ … … 235 205 break; 236 206 case 'T': /* --max-time */ 237 maxtime = (int64_t)(atof(optarg) * 1000000.0);207 opts->maxtime = (int64_t)(atof(optarg) * 1000000.0); 238 208 break; 239 209 case 'x': /* --check-exit */ 240 checkexit = 1;210 opts->checkexit = 1; 241 211 break; 242 212 case 'v': /* --verbose */ 243 verbose = 1;213 opts->verbose = 1; 244 214 break; 245 215 case 'h': /* --help */ 246 216 usage(); 217 _zz_opts_fini(opts); 247 218 return 0; 248 219 case 'V': /* --version */ 249 220 version(); 221 _zz_opts_fini(opts); 250 222 return 0; 251 223 default: 252 224 printf("%s: invalid option -- %c\n", argv[0], c); 253 225 printf(MOREINFO, argv[0]); 226 _zz_opts_fini(opts); 254 227 return EXIT_FAILURE; 255 228 } … … 260 233 #endif 261 234 262 _zz_setratio( minratio,maxratio);263 _zz_setseed( seed);235 _zz_setratio(opts->minratio, opts->maxratio); 236 _zz_setseed(opts->seed); 264 237 265 238 /* If asked to read from the standard input */ 266 239 if(optind >= argc) 267 240 { 268 if( endseed !=seed + 1)241 if(opts->endseed != opts->seed + 1) 269 242 { 270 243 printf("%s: seed ranges are incompatible with stdin fuzzing\n", 271 244 argv[0]); 272 245 printf(MOREINFO, argv[0]); 246 _zz_opts_fini(opts); 273 247 return EXIT_FAILURE; 274 248 } 275 249 276 loop_stdin(); 277 250 loop_stdin(opts); 251 252 _zz_opts_fini(opts); 278 253 return EXIT_SUCCESS; 279 254 } … … 299 274 if(exclude) 300 275 setenv("ZZUF_EXCLUDE", exclude, 1); 301 if( protect)302 setenv("ZZUF_PROTECT", protect, 1);303 if( refuse)304 setenv("ZZUF_REFUSE", refuse, 1);276 if(opts->protect) 277 setenv("ZZUF_PROTECT", opts->protect, 1); 278 if(opts->refuse) 279 setenv("ZZUF_REFUSE", opts->refuse, 1); 305 280 306 281 /* Allocate memory for children handling */ 307 child_list = malloc(maxforks * sizeof(struct child_list));308 for(i = 0; i < maxforks; i++)309 child_list[i].status = STATUS_FREE;310 child_count= 0;282 opts->child = malloc(opts->maxchild * sizeof(struct child)); 283 for(i = 0; i < opts->maxchild; i++) 284 opts->child[i].status = STATUS_FREE; 285 opts->nchild = 0; 311 286 312 287 /* Preload libzzuf.so */ … … 314 289 315 290 /* Create new argv */ 316 newargv = malloc((argc - optind + 1) * sizeof(char *));317 memcpy( newargv, argv + optind, (argc - optind) * sizeof(char *));318 newargv[argc - optind] = (char *)NULL;291 opts->newargv = malloc((argc - optind + 1) * sizeof(char *)); 292 memcpy(opts->newargv, argv + optind, (argc - optind) * sizeof(char *)); 293 opts->newargv[argc - optind] = (char *)NULL; 319 294 320 295 /* Main loop */ 321 while( child_count || seed <endseed)296 while(opts->nchild || opts->seed < opts->endseed) 322 297 { 323 298 /* Spawn new children, if necessary */ 324 spawn_children( );299 spawn_children(opts); 325 300 326 301 /* Cleanup dead or dying children */ 327 clean_children( );302 clean_children(opts); 328 303 329 304 /* Read data from children */ 330 read_children(); 331 332 if(maxcrashes && crashes >= maxcrashes && child_count == 0) 305 read_children(opts); 306 307 if(opts->maxcrashes && opts->crashes >= opts->maxcrashes 308 && opts->nchild == 0) 333 309 break; 334 310 } 335 311 336 312 /* Clean up */ 337 free(newargv); 338 free(child_list); 339 340 return crashes ? EXIT_FAILURE : EXIT_SUCCESS; 341 } 342 343 static void loop_stdin(void) 313 _zz_opts_fini(opts); 314 315 return opts->crashes ? EXIT_FAILURE : EXIT_SUCCESS; 316 } 317 318 static void loop_stdin(struct opts *opts) 344 319 { 345 320 uint8_t md5sum[16]; 346 321 struct md5 *ctx = NULL; 347 322 348 if( md5)323 if(opts->md5) 349 324 ctx = _zz_md5_init(); 350 325 351 if( protect)352 _zz_protect( protect);353 if( refuse)354 _zz_refuse( refuse);326 if(opts->protect) 327 _zz_protect(opts->protect); 328 if(opts->refuse) 329 _zz_refuse(opts->refuse); 355 330 356 331 _zz_fd_init(); … … 369 344 _zz_addpos(0, ret); 370 345 371 if( md5)346 if(opts->md5) 372 347 _zz_md5_add(ctx, buf, ret); 373 348 else while(ret) … … 380 355 } 381 356 382 if( md5)357 if(opts->md5) 383 358 { 384 359 _zz_md5_fini(md5sum, ctx); 385 360 fprintf(stdout, "zzuf[s=%i,r=%g]: %.02x%.02x%.02x%.02x%.02x" 386 361 "%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x\n", 387 seed, minratio, md5sum[0], md5sum[1], md5sum[2], md5sum[3],388 md5sum[ 4], md5sum[5], md5sum[6], md5sum[7],389 md5sum[8], md5sum[9], md5sum[10], md5sum[11], 390 md5sum[1 2], md5sum[13], md5sum[14], md5sum[15]);362 opts->seed, opts->minratio, md5sum[0], md5sum[1], md5sum[2], 363 md5sum[3], md5sum[4], md5sum[5], md5sum[6], md5sum[7], 364 md5sum[8], md5sum[9], md5sum[10], md5sum[11], md5sum[12], 365 md5sum[13], md5sum[14], md5sum[15]); 391 366 fflush(stdout); 392 367 } … … 444 419 } 445 420 446 static void spawn_children( void)421 static void spawn_children(struct opts *opts) 447 422 { 448 423 static int const files[] = { DEBUG_FILENO, STDERR_FILENO, STDOUT_FILENO }; … … 453 428 int i, j; 454 429 455 if( child_count == maxforks)430 if(opts->nchild == opts->maxchild) 456 431 return; /* no slot */ 457 432 458 if( seed ==endseed)433 if(opts->seed == opts->endseed) 459 434 return; /* job finished */ 460 435 461 if( maxcrashes && crashes >=maxcrashes)436 if(opts->maxcrashes && opts->crashes >= opts->maxcrashes) 462 437 return; /* all jobs crashed */ 463 438 464 if( delay > 0 && lastlaunch +delay > now)439 if(opts->delay > 0 && opts->lastlaunch + opts->delay > now) 465 440 return; /* too early */ 466 441 467 442 /* Find the empty slot */ 468 for(i = 0; i < maxforks; i++)469 if( child_list[i].status == STATUS_FREE)443 for(i = 0; i < opts->maxchild; i++) 444 if(opts->child[i].status == STATUS_FREE) 470 445 break; 471 446 … … 487 462 case 0: 488 463 /* We’re the child */ 489 if( maxmem >= 0)464 if(opts->maxmem >= 0) 490 465 { 491 466 struct rlimit rlim; 492 rlim.rlim_cur = maxmem * 1000000;493 rlim.rlim_max = maxmem * 1000000;467 rlim.rlim_cur = opts->maxmem * 1000000; 468 rlim.rlim_max = opts->maxmem * 1000000; 494 469 setrlimit(RLIMIT_AS, &rlim); 495 470 } … … 508 483 509 484 /* Set environment variables */ 510 sprintf(buf, "%i", seed);485 sprintf(buf, "%i", opts->seed); 511 486 setenv("ZZUF_SEED", buf, 1); 512 sprintf(buf, "%g", minratio);487 sprintf(buf, "%g", opts->minratio); 513 488 setenv("ZZUF_MINRATIO", buf, 1); 514 sprintf(buf, "%g", maxratio);489 sprintf(buf, "%g", opts->maxratio); 515 490 setenv("ZZUF_MAXRATIO", buf, 1); 516 491 517 492 /* Run our process */ 518 if(execvp( newargv[0],newargv))493 if(execvp(opts->newargv[0], opts->newargv)) 519 494 { 520 perror( newargv[0]);495 perror(opts->newargv[0]); 521 496 exit(EXIT_FAILURE); 522 497 } … … 525 500 526 501 /* We’re the parent, acknowledge spawn */ 527 child_list[i].date = now;528 child_list[i].pid = pid;502 opts->child[i].date = now; 503 opts->child[i].pid = pid; 529 504 for(j = 0; j < 3; j++) 530 505 { 531 506 close(fd[j][1]); 532 child_list[i].fd[j] = fd[j][0];533 } 534 child_list[i].bytes = 0;535 child_list[i].seed =seed;536 child_list[i].ratio = _zz_getratio();537 child_list[i].status = STATUS_RUNNING;538 if( md5)539 child_list[i].ctx = _zz_md5_init();540 541 if( verbose)507 opts->child[i].fd[j] = fd[j][0]; 508 } 509 opts->child[i].bytes = 0; 510 opts->child[i].seed = opts->seed; 511 opts->child[i].ratio = _zz_getratio(); 512 opts->child[i].status = STATUS_RUNNING; 513 if(opts->md5) 514 opts->child[i].ctx = _zz_md5_init(); 515 516 if(opts->verbose) 542 517 fprintf(stderr, "zzuf[s=%i,r=%g]: launched %s\n", 543 child_list[i].seed, child_list[i].ratio, newargv[0]); 544 545 lastlaunch = now; 546 child_count++; 547 seed++; 548 549 _zz_setseed(seed); 550 } 551 552 static void clean_children(void) 518 opts->child[i].seed, opts->child[i].ratio, 519 opts->newargv[0]); 520 521 opts->lastlaunch = now; 522 opts->nchild++; 523 opts->seed++; 524 525 _zz_setseed(opts->seed); 526 } 527 528 static void clean_children(struct opts *opts) 553 529 { 554 530 int64_t now = _zz_time(); … … 556 532 557 533 /* Terminate children if necessary */ 558 for(i = 0; i < maxforks; i++) 559 { 560 if(child_list[i].status == STATUS_RUNNING 561 && maxbytes >= 0 && child_list[i].bytes > maxbytes) 562 { 563 if(verbose) 534 for(i = 0; i < opts->maxchild; i++) 535 { 536 if(opts->child[i].status == STATUS_RUNNING 537 && opts->maxbytes >= 0 538 && opts->child[i].bytes > opts->maxbytes) 539 { 540 if(opts->verbose) 564 541 fprintf(stderr, "zzuf[s=%i,r=%g]: " 565 542 "data output exceeded, sending SIGTERM\n", 566 child_list[i].seed, child_list[i].ratio);567 kill( child_list[i].pid, SIGTERM);568 child_list[i].date = now;569 child_list[i].status = STATUS_SIGTERM;570 } 571 572 if( child_list[i].status == STATUS_RUNNING573 && maxtime >= 0574 && now > child_list[i].date +maxtime)575 { 576 if( verbose)543 opts->child[i].seed, opts->child[i].ratio); 544 kill(opts->child[i].pid, SIGTERM); 545 opts->child[i].date = now; 546 opts->child[i].status = STATUS_SIGTERM; 547 } 548 549 if(opts->child[i].status == STATUS_RUNNING 550 && opts->maxtime >= 0 551 && now > opts->child[i].date + opts->maxtime) 552 { 553 if(opts->verbose) 577 554 fprintf(stderr, "zzuf[s=%i,r=%g]: " 578 555 "running time exceeded, sending SIGTERM\n", 579 child_list[i].seed, child_list[i].ratio);580 kill( child_list[i].pid, SIGTERM);581 child_list[i].date = now;582 child_list[i].status = STATUS_SIGTERM;556 opts->child[i].seed, opts->child[i].ratio); 557 kill(opts->child[i].pid, SIGTERM); 558 opts->child[i].date = now; 559 opts->child[i].status = STATUS_SIGTERM; 583 560 } 584 561 } 585 562 586 563 /* Kill children if necessary (still there after 2 seconds) */ 587 for(i = 0; i < maxforks; i++)588 { 589 if( child_list[i].status == STATUS_SIGTERM590 && now > child_list[i].date + 2000000)591 { 592 if( verbose)564 for(i = 0; i < opts->maxchild; i++) 565 { 566 if(opts->child[i].status == STATUS_SIGTERM 567 && now > opts->child[i].date + 2000000) 568 { 569 if(opts->verbose) 593 570 fprintf(stderr, "zzuf[s=%i,r=%g]: " 594 571 "not responding, sending SIGKILL\n", 595 child_list[i].seed, child_list[i].ratio);596 kill( child_list[i].pid, SIGKILL);597 child_list[i].status = STATUS_SIGKILL;572 opts->child[i].seed, opts->child[i].ratio); 573 kill(opts->child[i].pid, SIGKILL); 574 opts->child[i].status = STATUS_SIGKILL; 598 575 } 599 576 } 600 577 601 578 /* Collect dead children */ 602 for(i = 0; i < maxforks; i++)579 for(i = 0; i < opts->maxchild; i++) 603 580 { 604 581 uint8_t md5sum[16]; … … 606 583 pid_t pid; 607 584 608 if( child_list[i].status != STATUS_SIGKILL609 && child_list[i].status != STATUS_SIGTERM610 && child_list[i].status != STATUS_EOF)585 if(opts->child[i].status != STATUS_SIGKILL 586 && opts->child[i].status != STATUS_SIGTERM 587 && opts->child[i].status != STATUS_EOF) 611 588 continue; 612 589 613 pid = waitpid( child_list[i].pid, &status, WNOHANG);590 pid = waitpid(opts->child[i].pid, &status, WNOHANG); 614 591 if(pid <= 0) 615 592 continue; 616 593 617 if( checkexit && WIFEXITED(status) && WEXITSTATUS(status))594 if(opts->checkexit && WIFEXITED(status) && WEXITSTATUS(status)) 618 595 { 619 596 fprintf(stderr, "zzuf[s=%i,r=%g]: exit %i\n", 620 child_list[i].seed, child_list[i].ratio,597 opts->child[i].seed, opts->child[i].ratio, 621 598 WEXITSTATUS(status)); 622 crashes++;599 opts->crashes++; 623 600 } 624 601 else if(WIFSIGNALED(status) 625 602 && !(WTERMSIG(status) == SIGTERM 626 && child_list[i].status == STATUS_SIGTERM))603 && opts->child[i].status == STATUS_SIGTERM)) 627 604 { 628 605 fprintf(stderr, "zzuf[s=%i,r=%g]: signal %i%s%s\n", 629 child_list[i].seed, child_list[i].ratio,606 opts->child[i].seed, opts->child[i].ratio, 630 607 WTERMSIG(status), sig2str(WTERMSIG(status)), 631 (WTERMSIG(status) == SIGKILL && maxmem >= 0) ?608 (WTERMSIG(status) == SIGKILL && opts->maxmem >= 0) ? 632 609 " (memory exceeded?)" : ""); 633 crashes++;610 opts->crashes++; 634 611 } 635 612 636 613 for(j = 0; j < 3; j++) 637 if(child_list[i].fd[j] >= 0) 638 close(child_list[i].fd[j]); 639 640 if(md5) 641 { 642 _zz_md5_fini(md5sum, child_list[i].ctx); 643 fprintf(stdout, "zzuf[s=%i,r=%g]: %.02x%.02x%.02x%.02x%.02x" 644 "%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x\n", 645 child_list[i].seed, child_list[i].ratio, md5sum[0], 646 md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5], 647 md5sum[6], md5sum[7], md5sum[8], md5sum[9], md5sum[10], 648 md5sum[11], md5sum[12], md5sum[13], md5sum[14], md5sum[15]); 614 if(opts->child[i].fd[j] >= 0) 615 close(opts->child[i].fd[j]); 616 617 if(opts->md5) 618 { 619 _zz_md5_fini(md5sum, opts->child[i].ctx); 620 fprintf(stdout, "zzuf[s=%i,r=%g]: %.02x%.02x%.02x%.02x%.02x%.02x" 621 "%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x%.02x\n", 622 opts->child[i].seed, opts->child[i].ratio, 623 md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], 624 md5sum[5], md5sum[6], md5sum[7], md5sum[8], md5sum[9], 625 md5sum[10], md5sum[11], md5sum[12], md5sum[13], 626 md5sum[14], md5sum[15]); 649 627 fflush(stdout); 650 628 } 651 child_list[i].status = STATUS_FREE;652 child_count--;653 } 654 } 655 656 static void read_children( void)629 opts->child[i].status = STATUS_FREE; 630 opts->nchild--; 631 } 632 } 633 634 static void read_children(struct opts *opts) 657 635 { 658 636 struct timeval tv; … … 662 640 /* Read data from all sockets */ 663 641 FD_ZERO(&fdset); 664 for(i = 0; i < maxforks; i++)665 { 666 if( child_list[i].status != STATUS_RUNNING)642 for(i = 0; i < opts->maxchild; i++) 643 { 644 if(opts->child[i].status != STATUS_RUNNING) 667 645 continue; 668 646 669 647 for(j = 0; j < 3; j++) 670 ZZUF_FD_SET( child_list[i].fd[j], &fdset, maxfd);648 ZZUF_FD_SET(opts->child[i].fd[j], &fdset, maxfd); 671 649 } 672 650 tv.tv_sec = 0; … … 680 658 681 659 /* XXX: cute (i, j) iterating hack */ 682 for(i = 0, j = 0; i < maxforks; i += (j == 2), j = (j + 1) % 3)660 for(i = 0, j = 0; i < opts->maxchild; i += (j == 2), j = (j + 1) % 3) 683 661 { 684 662 uint8_t buf[BUFSIZ]; 685 663 686 if( child_list[i].status != STATUS_RUNNING)664 if(opts->child[i].status != STATUS_RUNNING) 687 665 continue; 688 666 689 if(!ZZUF_FD_ISSET( child_list[i].fd[j], &fdset))667 if(!ZZUF_FD_ISSET(opts->child[i].fd[j], &fdset)) 690 668 continue; 691 669 692 ret = read( child_list[i].fd[j], buf, BUFSIZ - 1);670 ret = read(opts->child[i].fd[j], buf, BUFSIZ - 1); 693 671 if(ret > 0) 694 672 { 695 673 /* We got data */ 696 674 if(j != 0) 697 child_list[i].bytes += ret;698 699 if( md5 && j == 2)700 _zz_md5_add( child_list[i].ctx, buf, ret);701 else if(! quiet || j == 0)675 opts->child[i].bytes += ret; 676 677 if(opts->md5 && j == 2) 678 _zz_md5_add(opts->child[i].ctx, buf, ret); 679 else if(!opts->quiet || j == 0) 702 680 write((j < 2) ? STDERR_FILENO : STDOUT_FILENO, buf, ret); 703 681 } … … 705 683 { 706 684 /* End of file reached */ 707 close(child_list[i].fd[j]); 708 child_list[i].fd[j] = -1; 709 710 if(child_list[i].fd[0] == -1 && child_list[i].fd[1] == -1 711 && child_list[i].fd[2] == -1) 712 child_list[i].status = STATUS_EOF; 685 close(opts->child[i].fd[j]); 686 opts->child[i].fd[j] = -1; 687 688 if(opts->child[i].fd[0] == -1 689 && opts->child[i].fd[1] == -1 690 && opts->child[i].fd[2] == -1) 691 opts->child[i].status = STATUS_EOF; 713 692 } 714 693 }
Note: See TracChangeset
for help on using the changeset viewer.