X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fprocess.c;h=313f11fa9d97aca99b790e8a5fac8dc02fe7296e;hb=65a0903b26bdff3e42dc0fa78ef5b73a48448e80;hp=520502a855db00392e550e8b97b291175b8411aa;hpb=57d90319a6deeb59e23227878a39f92470ac3e2b;p=sliver-openvswitch.git diff --git a/lib/process.c b/lib/process.c index 520502a85..313f11fa9 100644 --- a/lib/process.c +++ b/lib/process.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include "dynamic-string.h" #include "fatal-signal.h" #include "list.h" +#include "ovs-thread.h" #include "poll-loop.h" #include "signals.h" #include "socket-util.h" @@ -36,7 +38,6 @@ VLOG_DEFINE_THIS_MODULE(process); -COVERAGE_DEFINE(process_sigchld); COVERAGE_DEFINE(process_start); struct process { @@ -60,15 +61,19 @@ static void sigchld_handler(int signr OVS_UNUSED); /* Initializes the process subsystem (if it is not already initialized). Calls * exit() if initialization fails. * + * This function may not be called after creating any additional threads. + * * Calling this function is optional; it will be called automatically by * process_start() if necessary. Calling it explicitly allows the client to * prevent the process from exiting at an unexpected time. */ void process_init(void) { +#ifndef _WIN32 static bool inited; struct sigaction sa; + assert_single_threaded(); if (inited) { return; } @@ -83,6 +88,7 @@ process_init(void) sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; xsigaction(SIGCHLD, &sa, NULL); +#endif } char * @@ -160,10 +166,55 @@ process_register(const char *name, pid_t pid) return p; } +#ifndef _WIN32 +static bool +rlim_is_finite(rlim_t limit) +{ + if (limit == RLIM_INFINITY) { + return false; + } + +#ifdef RLIM_SAVED_CUR /* FreeBSD 8.0 lacks RLIM_SAVED_CUR. */ + if (limit == RLIM_SAVED_CUR) { + return false; + } +#endif + +#ifdef RLIM_SAVED_MAX /* FreeBSD 8.0 lacks RLIM_SAVED_MAX. */ + if (limit == RLIM_SAVED_MAX) { + return false; + } +#endif + + return true; +} + +/* Returns the maximum valid FD value, plus 1. */ +static int +get_max_fds(void) +{ + static int max_fds; + + if (!max_fds) { + struct rlimit r; + if (!getrlimit(RLIMIT_NOFILE, &r) && rlim_is_finite(r.rlim_cur)) { + max_fds = r.rlim_cur; + } else { + VLOG_WARN("failed to obtain fd limit, defaulting to 1024"); + max_fds = 1024; + } + } + + return max_fds; +} +#endif /* _WIN32 */ + /* Starts a subprocess with the arguments in the null-terminated argv[] array. * argv[0] is used as the name of the process. Searches the PATH environment * variable to find the program to execute. * + * This function may not be called after creating any additional threads. + * * All file descriptors are closed before executing the subprocess, except for * fds 0, 1, and 2. * @@ -173,9 +224,12 @@ process_register(const char *name, pid_t pid) int process_start(char **argv, struct process **pp) { +#ifndef _WIN32 pid_t pid; int error; + assert_single_threaded(); + *pp = NULL; COVERAGE_INC(process_start); error = process_prestart(argv); @@ -185,7 +239,7 @@ process_start(char **argv, struct process **pp) pid = fork(); if (pid < 0) { - VLOG_WARN("fork failed: %s", strerror(errno)); + VLOG_WARN("fork failed: %s", ovs_strerror(errno)); return errno; } else if (pid) { /* Running in parent process. */ @@ -202,9 +256,13 @@ process_start(char **argv, struct process **pp) } execvp(argv[0], argv); fprintf(stderr, "execvp(\"%s\") failed: %s\n", - argv[0], strerror(errno)); + argv[0], ovs_strerror(errno)); _exit(1); } +#else + *pp = NULL; + return ENOSYS; +#endif } /* Destroys process 'p'. */ @@ -223,9 +281,13 @@ process_destroy(struct process *p) int process_kill(const struct process *p, int signr) { +#ifndef _WIN32 return (p->exited ? ESRCH : !kill(p->pid, signr) ? 0 : errno); +#else + return ENOSYS; +#endif } /* Returns the pid of process 'p'. */ @@ -268,6 +330,7 @@ char * process_status_msg(int status) { struct ds ds = DS_EMPTY_INITIALIZER; +#ifndef _WIN32 if (WIFEXITED(status)) { ds_put_format(&ds, "exit status %d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { @@ -286,6 +349,9 @@ process_status_msg(int status) if (WCOREDUMP(status)) { ds_put_cstr(&ds, ", core dumped"); } +#else + ds_put_cstr(&ds, "function not supported."); +#endif return ds_cstr(&ds); } @@ -293,6 +359,7 @@ process_status_msg(int status) void process_run(void) { +#ifndef _WIN32 char buf[_POSIX_PIPE_BUF]; if (!list_is_empty(&all_processes) && read(fds[0], buf, sizeof buf) > 0) { @@ -308,13 +375,14 @@ process_run(void) p->exited = true; p->status = status; } else if (retval < 0) { - VLOG_WARN("waitpid: %s", strerror(errno)); + VLOG_WARN("waitpid: %s", ovs_strerror(errno)); p->exited = true; p->status = -1; } } } } +#endif } @@ -323,11 +391,15 @@ process_run(void) void process_wait(struct process *p) { +#ifndef _WIN32 if (p->exited) { poll_immediate_wake(); } else { poll_fd_wait(fds[0], POLLIN); } +#else + OVS_NOT_REACHED(); +#endif } char *