+ }
+}
+
+
+static struct screenhack_job *
+find_job (pid_t pid)
+{
+ struct screenhack_job *job;
+ for (job = jobs; job; job = job->next)
+ if (job->pid == pid)
+ return job;
+ return 0;
+}
+
+static void await_dying_children (saver_info *si);
+#ifndef VMS
+static void describe_dead_child (saver_info *, pid_t, int wait_status);
+#endif
+
+
+/* Semaphore to temporarily turn the SIGCHLD handler into a no-op.
+ Don't alter this directly -- use block_sigchld() / unblock_sigchld().
+ */
+static int block_sigchld_handler = 0;
+
+
+static void
+block_sigchld (void)
+{
+#ifdef HAVE_SIGACTION
+ sigset_t child_set;
+ sigemptyset (&child_set);
+ sigaddset (&child_set, SIGCHLD);
+ sigprocmask (SIG_BLOCK, &child_set, 0);
+#endif /* HAVE_SIGACTION */
+
+ block_sigchld_handler++;
+}
+
+static void
+unblock_sigchld (void)
+{
+#ifdef HAVE_SIGACTION
+ sigset_t child_set;
+ sigemptyset(&child_set);
+ sigaddset(&child_set, SIGCHLD);
+ sigprocmask(SIG_UNBLOCK, &child_set, 0);
+#endif /* HAVE_SIGACTION */
+
+ block_sigchld_handler--;
+}
+
+static int
+kill_job (saver_info *si, pid_t pid, int signal)
+{
+ saver_preferences *p = &si->prefs;
+ struct screenhack_job *job;
+ int status = -1;
+
+ clean_job_list();
+
+ if (block_sigchld_handler)
+ /* This function should not be called from the signal handler. */
+ abort();
+
+ block_sigchld(); /* we control the horizontal... */
+
+ job = find_job (pid);
+ if (!job ||
+ !job->pid ||
+ job->status == job_killed)
+ {
+ if (p->verbose_p)
+ fprintf (stderr, "%s: no child %ld to signal!\n",
+ blurb(), (long) pid);
+ goto DONE;
+ }
+
+ switch (signal) {
+ case SIGTERM: job->status = job_killed; break;
+#ifdef SIGSTOP
+ /* #### there must be a way to do this on VMS... */
+ case SIGSTOP: job->status = job_stopped; break;
+ case SIGCONT: job->status = job_running; break;
+#endif /* SIGSTOP */
+ default: abort();
+ }
+
+#ifdef SIGSTOP
+ if (p->verbose_p)
+ fprintf (stderr, "%s: %s pid %lu.\n", blurb(),
+ (signal == SIGTERM ? "killing" :
+ signal == SIGSTOP ? "suspending" :
+ signal == SIGCONT ? "resuming" : "signalling"),
+ (unsigned long) job->pid);
+#else /* !SIGSTOP */
+ if (p->verbose_p)
+ fprintf (stderr, "%s: %s pid %lu.\n", blurb(), "killing",
+ (unsigned long) job->pid);
+#endif /* !SIGSTOP */
+
+ status = kill (job->pid, signal);
+
+ if (p->verbose_p && status < 0)
+ {
+ if (errno == ESRCH)
+ fprintf (stderr, "%s: child process %lu (%s) was already dead.\n",
+ blurb(), job->pid, job->name);
+ else