+ return 0;
+}
+
+/* Creates and returns a new struct process with the specified 'name' and
+ * 'pid'. */
+static struct process *
+process_register(const char *name, pid_t pid)
+{
+ struct process *p;
+ const char *slash;
+
+ p = xzalloc(sizeof *p);
+ p->pid = pid;
+ slash = strrchr(name, '/');
+ p->name = xstrdup(slash ? slash + 1 : name);
+ p->exited = false;
+
+ list_push_back(&all_processes, &p->node);
+
+ 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.
+ *
+ * Returns 0 if successful, otherwise a positive errno value indicating the
+ * error. If successful, '*pp' is assigned a new struct process that may be
+ * used to query the process's status. On failure, '*pp' is set to NULL. */
+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);
+ if (error) {
+ return error;
+ }
+