~ubuntu-branches/ubuntu/dapper/gnome-screensaver/dapper

« back to all changes in this revision

Viewing changes to src/subprocs.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2005-10-10 00:18:18 UTC
  • Revision ID: james.westby@ubuntu.com-20051010001818-3mujs05r8rht7xi1
Tags: upstream-0.0.15
ImportĀ upstreamĀ versionĀ 0.0.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * subprocs.c --- choosing, spawning, and killing screenhacks.
 
4
 *
 
5
 * xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski <jwz@jwz.org>
 
6
 * Modified:     Copyright (c) 2004 William Jon McCann <mccann@jhu.edu>
 
7
 *
 
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 
 
14
 * implied warranty.
 
15
 */
 
16
 
 
17
#include "config.h"
 
18
 
 
19
#include <stdlib.h>
 
20
#include <ctype.h>
 
21
#include <stdio.h>
 
22
#include <string.h>
 
23
 
 
24
#ifndef ESRCH
 
25
# include <errno.h>
 
26
#endif
 
27
 
 
28
#include <sys/time.h>           /* sys/resource.h needs this for timeval */
 
29
# include <sys/wait.h>          /* for waitpid() and associated macros */
 
30
 
 
31
#ifdef VMS
 
32
# include <processes.h>
 
33
# include <unixio.h>            /* for close */
 
34
# include <unixlib.h>           /* for getpid */
 
35
# define pid_t int
 
36
# define fork  vfork
 
37
#endif /* VMS */
 
38
 
 
39
#include <signal.h>             /* for the signal names */
 
40
 
 
41
#include <glib.h>
 
42
#include "subprocs.h"
 
43
 
 
44
#if !defined(SIGCHLD) && defined(SIGCLD)
 
45
# define SIGCHLD SIGCLD
 
46
#endif
 
47
 
 
48
/* Semaphore to temporarily turn the SIGCHLD handler into a no-op.
 
49
   Don't alter this directly -- use block_sigchld() / unblock_sigchld().
 
50
*/
 
51
static int block_sigchld_handler = 0;
 
52
 
 
53
 
 
54
#ifdef HAVE_SIGACTION
 
55
sigset_t
 
56
#else  /* !HAVE_SIGACTION */
 
57
int
 
58
#endif /* !HAVE_SIGACTION */
 
59
block_sigchld (void)
 
60
{
 
61
#ifdef HAVE_SIGACTION
 
62
        sigset_t child_set;
 
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 */
 
68
 
 
69
        block_sigchld_handler++;
 
70
 
 
71
#ifdef HAVE_SIGACTION
 
72
        return child_set;
 
73
#else  /* !HAVE_SIGACTION */
 
74
        return 0;
 
75
#endif /* !HAVE_SIGACTION */
 
76
}
 
77
 
 
78
void
 
79
unblock_sigchld (void)
 
80
{
 
81
#ifdef HAVE_SIGACTION
 
82
        sigset_t child_set;
 
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 */
 
88
 
 
89
        block_sigchld_handler--;
 
90
}
 
91
 
 
92
int
 
93
signal_pid (int    pid,
 
94
            int    signal)
 
95
{
 
96
        int status = -1;
 
97
        gboolean verbose = TRUE;
 
98
 
 
99
        if (block_sigchld_handler)
 
100
                /* This function should not be called from the signal handler. */
 
101
                abort();
 
102
 
 
103
        block_sigchld ();                      /* we control the horizontal... */
 
104
 
 
105
        status = kill (pid, signal);
 
106
 
 
107
        if (verbose && status < 0) {
 
108
                if (errno == ESRCH)
 
109
                        g_message ("Child process %lu was already dead.",
 
110
                                   (unsigned long) pid);
 
111
                else {
 
112
                        char buf [1024];
 
113
                        snprintf (buf, sizeof (buf), "Couldn't kill child process %lu",
 
114
                                 (unsigned long) pid);
 
115
                        perror (buf);
 
116
                }
 
117
        }
 
118
 
 
119
        unblock_sigchld ();
 
120
 
 
121
        if (block_sigchld_handler < 0)
 
122
                abort ();
 
123
 
 
124
        return status;
 
125
}
 
126
 
 
127
#ifndef VMS
 
128
 
 
129
void
 
130
await_dying_children (int      pid,
 
131
                      gboolean debug)
 
132
{
 
133
        while (1) {
 
134
                int wait_status = 0;
 
135
                pid_t kid;
 
136
 
 
137
                errno = 0;
 
138
                kid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED);
 
139
 
 
140
                if (debug) {
 
141
                        if (kid < 0 && errno)
 
142
                                g_message ("waitpid(%d) ==> %ld (%d)", pid, (long) kid, errno);
 
143
                        else if (kid != 0) 
 
144
                                g_message ("waitpid(%d) ==> %ld", pid, (long) kid);
 
145
                }
 
146
 
 
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)
 
151
                        break;
 
152
        }
 
153
}
 
154
 
 
155
 
 
156
#else  /* VMS */
 
157
static void await_dying_children (saver_info *si) { return; }
 
158
#endif /* VMS */
 
159