-#if defined(SYSV) || defined(SVR4) || defined(__hpux)
- {
- int old_nice = nice (0);
- int n = nice_inferior - old_nice;
- errno = 0;
- if (nice (n) == -1 && errno != 0)
- {
- sprintf (buf, "%s: %snice(%d) failed", progname,
- (verbose_p ? "## " : ""), n);
- perror (buf);
- }
- }
-#else /* !SYSV */
-#ifdef PRIO_PROCESS
- if (setpriority (PRIO_PROCESS, getpid(), nice_inferior) != 0)
+ if (p->verbose_p)
+ fprintf (stderr, "%s: spawning \"%s\" in pid %lu%s.\n",
+ blurb(), command, (unsigned long) getpid (),
+ (hairy_p ? " (via shell)" : ""));
+
+ if (hairy_p)
+ /* If it contains any shell metacharacters, do it the hard way,
+ and fork a shell to parse the arguments for us. */
+ exec_complex_command (p->shell, command);
+ else
+ /* Otherwise, we can just exec the program directly. */
+ exec_simple_command (command);
+
+#else /* VMS */
+ if (p->verbose_p)
+ fprintf (stderr, "%s: spawning \"%s\" in pid %lu.\n",
+ blurb(), command, getpid());
+ exec_vms_command (command);
+#endif /* VMS */
+
+ abort(); /* that shouldn't have returned. */
+}
+
+
+\f
+/* Management of child processes, and de-zombification.
+ */
+
+enum job_status {
+ job_running, /* the process is still alive */
+ job_stopped, /* we have sent it a STOP signal */
+ job_killed, /* we have sent it a TERM signal */
+ job_dead /* we have wait()ed for it, and it's dead -- this state only
+ occurs so that we can avoid calling free() from a signal
+ handler. Shortly after going into this state, the list
+ element will be removed. */
+};
+
+struct screenhack_job {
+ char *name;
+ pid_t pid;
+ enum job_status status;
+ struct screenhack_job *next;
+};
+
+static struct screenhack_job *jobs = 0;
+
+/* for debugging -- nothing calls this, but it's useful to invoke from gdb. */
+void
+show_job_list (void)
+{
+ struct screenhack_job *job;
+ fprintf(stderr, "%s: job list:\n", blurb());
+ for (job = jobs; job; job = job->next)
+ fprintf (stderr, " %5ld: (%s) %s\n",
+ (long) job->pid,
+ (job->status == job_running ? "running" :
+ job->status == job_stopped ? "stopped" :
+ job->status == job_killed ? " killed" :
+ job->status == job_dead ? " dead" : " ???"),
+ job->name);
+ fprintf (stderr, "\n");
+}
+
+
+static void clean_job_list (void);
+
+static struct screenhack_job *
+make_job (pid_t pid, const char *cmd)
+{
+ struct screenhack_job *job = (struct screenhack_job *) malloc (sizeof(*job));
+
+ static char name [1024];
+ const char *in = cmd;
+ char *out = name;
+
+ clean_job_list();
+
+ while (isspace(*in)) in++; /* skip whitespace */
+ while (!isspace(*in) && *in != ':')
+ *out++ = *in++; /* snarf first token */
+ while (isspace(*in)) in++; /* skip whitespace */
+ if (*in == ':') /* token was a visual name; skip it. */