X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fprocess.c;h=8263437c136ce2c86d94937ae96cd6a006f24791;hb=4e6ca956f56b7a7f7284a4cd8788873ba57b229c;hp=1f6b00fc99191a67ae50158a32cc6cc27b59d1c9;hpb=67a4917b07031b387beafaedce413b4207214059;p=openvswitch diff --git a/lib/process.c b/lib/process.c index 1f6b00fc..8263437c 100644 --- a/lib/process.c +++ b/lib/process.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,10 +32,15 @@ #include "poll-loop.h" #include "socket-util.h" #include "util.h" - -#define THIS_MODULE VLM_process #include "vlog.h" +VLOG_DEFINE_THIS_MODULE(process); + +COVERAGE_DEFINE(process_run); +COVERAGE_DEFINE(process_run_capture); +COVERAGE_DEFINE(process_sigchld); +COVERAGE_DEFINE(process_start); + struct process { struct list node; char *name; @@ -103,7 +108,7 @@ process_escape_args(char **argv) if (argp != argv) { ds_put_char(&ds, ' '); } - if (arg[strcspn(arg, " \t\r\n\v\\")]) { + if (arg[strcspn(arg, " \t\r\n\v\\\'\"")]) { ds_put_char(&ds, '"'); for (p = arg; *p; p++) { if (*p == '\\' || *p == '\"') { @@ -161,7 +166,7 @@ process_register(const char *name, pid_t pid) assert(sigchld_is_blocked()); - p = xcalloc(1, sizeof *p); + p = xzalloc(sizeof *p); p->pid = pid; slash = strrchr(name, '/'); p->name = xstrdup(slash ? slash + 1 : name); @@ -190,6 +195,7 @@ process_start(char **argv, struct process **pp) { sigset_t oldsigs; + int nullfd; pid_t pid; int error; @@ -200,18 +206,24 @@ process_start(char **argv, return error; } + if (n_null_fds) { + nullfd = get_null_fd(); + if (nullfd < 0) { + return -nullfd; + } + } else { + nullfd = -1; + } + block_sigchld(&oldsigs); - fatal_signal_block(); pid = fork(); if (pid < 0) { - fatal_signal_unblock(); unblock_sigchld(&oldsigs); VLOG_WARN("fork failed: %s", strerror(errno)); return errno; } else if (pid) { /* Running in parent process. */ *pp = process_register(argv[0], pid); - fatal_signal_unblock(); unblock_sigchld(&oldsigs); return 0; } else { @@ -220,19 +232,20 @@ process_start(char **argv, int fd; fatal_signal_fork(); - fatal_signal_unblock(); unblock_sigchld(&oldsigs); for (fd = 0; fd < fd_max; fd++) { if (is_member(fd, null_fds, n_null_fds)) { - /* We can't use get_null_fd() here because we might have - * already closed its fd. */ - int nullfd = open("/dev/null", O_RDWR); dup2(nullfd, fd); - close(nullfd); - } else if (fd >= 3 && !is_member(fd, keep_fds, n_keep_fds)) { + } else if (fd >= 3 && fd != nullfd + && !is_member(fd, keep_fds, n_keep_fds)) { close(fd); } } + if (nullfd >= 0 + && !is_member(nullfd, keep_fds, n_keep_fds) + && !is_member(nullfd, null_fds, n_null_fds)) { + close(nullfd); + } execvp(argv[0], argv); fprintf(stderr, "execvp(\"%s\") failed: %s\n", argv[0], strerror(errno)); @@ -289,7 +302,7 @@ process_exited(struct process *p) return true; } else { char buf[_POSIX_PIPE_BUF]; - read(fds[0], buf, sizeof buf); + ignore(read(fds[0], buf, sizeof buf)); return false; } } @@ -419,15 +432,13 @@ stream_open(struct stream *s) static void stream_read(struct stream *s) { - int error = 0; - if (s->fds[0] < 0) { return; } - error = 0; for (;;) { char buffer[512]; + int error; size_t n; error = read_fully(s->fds[0], buffer, sizeof buffer, &n); @@ -521,12 +532,10 @@ process_run_capture(char **argv, char **stdout_log, char **stderr_log, } block_sigchld(&oldsigs); - fatal_signal_block(); pid = fork(); if (pid < 0) { - int error = errno; + error = errno; - fatal_signal_unblock(); unblock_sigchld(&oldsigs); VLOG_WARN("fork failed: %s", strerror(error)); @@ -539,7 +548,6 @@ process_run_capture(char **argv, char **stdout_log, char **stderr_log, struct process *p; p = process_register(argv[0], pid); - fatal_signal_unblock(); unblock_sigchld(&oldsigs); close(s_stdout.fds[1]); @@ -575,7 +583,6 @@ process_run_capture(char **argv, char **stdout_log, char **stderr_log, int i; fatal_signal_fork(); - fatal_signal_unblock(); unblock_sigchld(&oldsigs); dup2(get_null_fd(), 0); @@ -600,7 +607,7 @@ sigchld_handler(int signr OVS_UNUSED) struct process *p; COVERAGE_INC(process_sigchld); - LIST_FOR_EACH (p, struct process, node, &all_processes) { + LIST_FOR_EACH (p, node, &all_processes) { if (!p->exited) { int retval, status; do { @@ -617,7 +624,7 @@ sigchld_handler(int signr OVS_UNUSED) } } } - write(fds[1], "", 1); + ignore(write(fds[1], "", 1)); } static bool