2024年2月9日发(作者:)
388
389 /* set the read end of the socket to non-blocking */
390 if (set_nonblock_fd(pipes[0]) == -1) {
391 log_error_time();
392 perror("cgi-fcntl");
393 close(pipes[0]);
394 close(pipes[1]);
395 return 0;
396 }
397 }
398
399 child_pid = fork();
400 switch(child_pid) {
401 case -1:
402 /* fork unsuccessful */
403 log_error_time();
404 perror("fork");
405
406 if (use_pipes) {
407 close(pipes[0]);
408 close(pipes[1]);
409 }
410 send_r_error(req);
411 /* FIXME: There is aproblem here. send_r_error would work
412 for NPH and CGI, but not for GUNZIP. Fix that. */
413 /* i'd like to send_r_error, */
414 return 0;
415 break;
416 case 0:
417 /* child */
418 if (req->is_cgi == CGI || req->is_cgi == NPH) {
419 char *foo = strdup(req->pathname);
420 char *c;
421
422 if (!foo) {
423 WARN("unable to strdup pathname for req->pathname");
424 _exit(1);
425 }
426 c = strrchr(foo, '/');
427 if (c) {
428 ++c;
429 *c = '0';
430 } else {
431 /* we have a serious problem */
432 log_error_time();
433 perror("chdir");
434 if (use_pipes)
435 close(pipes[1]);
436 _exit(1);
437 }
438 if (chdir(foo) != 0) {
439 log_error_time();
440 perror("chdir");
441 if (use_pipes)
442 close(pipes[1]);
443 _exit(1);
444 }
445 }
446 if (use_pipes) {
447 close(pipes[0]);
448 /* tie cgi's STDOUT to it's write end of pipe */
449 if (dup2(pipes[1], STDOUT_FILENO) == -1) {
450 log_error_time();
451 perror("dup2 - pipes");
452 close(pipes[1]);
453 _exit(1);
454 }
455 close(pipes[1]);
456 if (set_block_fd(STDOUT_FILENO) == -1) {
457 log_error_time();
458 perror("cgi-fcntl");
459 _exit(1);
460 }
461 } else {
462 /* tie stdout to socket */
463 if (dup2(req->fd, STDOUT_FILENO) == -1) {
464 log_error_time();
465 perror("dup2 - fd");
466 _exit(1);
467 }
468 /* Switch socket flags back to blocking */
469 if (set_block_fd(req->fd) == -1) {
470 log_error_time();
471 perror("cgi-fcntl");
472 _exit(1);
473 }
474 }
475 /* tie post_data_fd to POST stdin */
476 if (req->method == M_POST) { /* tie stdin to file */
477 lseek(req->post_data_fd, SEEK_SET, 0);
478 dup2(req->post_data_fd, STDIN_FILENO);
479 close(req->post_data_fd);
480 }
481 /* Close access log, so CGI program can't scribble
482 * where it shouldn't
483 */
484 close_access_log();
485
486 /*
487 * tie STDERR to cgi_log_fd
488 * cgi_log_fd will automatically close, close-on-exec rocks!
489 * if we don't tied STDERR (current log_error) to cgi_log_fd,
490 * then we ought to close it.
491 */
492 if (!cgi_log_fd)
493 dup2(devnullfd, STDERR_FILENO);
494 else
495 dup2(cgi_log_fd, STDERR_FILENO);
496
497 if (req->is_cgi) {
498 char *aargv[CGI_ARGC_MAX + 1];
499 create_argv(req, aargv);
500 execve(req->pathname, aargv, req->cgi_env);
501 } else {
502 if (req->pathname[strlen(req->pathname) - 1] == '/')
503 execl(dirmaker, dirmaker, req->pathname, req->request_uri,
发布评论