1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* subprocs.c --- choosing, spawning, and killing screenhacks.
5
* xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski <jwz@jwz.org>
6
* Modified: Copyright (c) 2004 William Jon McCann <mccann@jhu.edu>
8
* Permission to use, copy, modify, distribute, and sell this software and its
9
* documentation for any purpose is hereby granted without fee, provided that
10
* the above copyright notice appear in all copies and that both that
11
* copyright notice and this permission notice appear in supporting
12
* documentation. No representations are made about the suitability of this
13
* software for any purpose. It is provided "as is" without express or
28
#include <sys/time.h> /* sys/resource.h needs this for timeval */
29
# include <sys/wait.h> /* for waitpid() and associated macros */
32
# include <processes.h>
33
# include <unixio.h> /* for close */
34
# include <unixlib.h> /* for getpid */
39
#include <signal.h> /* for the signal names */
44
#if !defined(SIGCHLD) && defined(SIGCLD)
45
# define SIGCHLD SIGCLD
48
/* Semaphore to temporarily turn the SIGCHLD handler into a no-op.
49
Don't alter this directly -- use block_sigchld() / unblock_sigchld().
51
static int block_sigchld_handler = 0;
56
#else /* !HAVE_SIGACTION */
58
#endif /* !HAVE_SIGACTION */
63
sigemptyset (&child_set);
64
sigaddset (&child_set, SIGCHLD);
65
sigaddset (&child_set, SIGPIPE);
66
sigprocmask (SIG_BLOCK, &child_set, 0);
67
#endif /* HAVE_SIGACTION */
69
block_sigchld_handler++;
73
#else /* !HAVE_SIGACTION */
75
#endif /* !HAVE_SIGACTION */
79
unblock_sigchld (void)
83
sigemptyset (&child_set);
84
sigaddset (&child_set, SIGCHLD);
85
sigaddset (&child_set, SIGPIPE);
86
sigprocmask (SIG_UNBLOCK, &child_set, 0);
87
#endif /* HAVE_SIGACTION */
89
block_sigchld_handler--;
97
gboolean verbose = TRUE;
99
if (block_sigchld_handler)
100
/* This function should not be called from the signal handler. */
103
block_sigchld (); /* we control the horizontal... */
105
status = kill (pid, signal);
107
if (verbose && status < 0) {
109
g_message ("Child process %lu was already dead.",
110
(unsigned long) pid);
113
snprintf (buf, sizeof (buf), "Couldn't kill child process %lu",
114
(unsigned long) pid);
121
if (block_sigchld_handler < 0)
130
await_dying_children (int pid,
138
kid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED);
141
if (kid < 0 && errno)
142
g_message ("waitpid(%d) ==> %ld (%d)", pid, (long) kid, errno);
144
g_message ("waitpid(%d) ==> %ld", pid, (long) kid);
147
/* 0 means no more children to reap.
148
-1 means error -- except "interrupted system call" isn't a "real"
149
error, so if we get that, we should just try again. */
150
if (kid < 0 && errno != EINTR)
157
static void await_dying_children (saver_info *si) { return; }