Revision 4d54ec78

b/iohandler.c
27 27
#include "qemu-char.h"
28 28
#include "qemu-queue.h"
29 29

  
30
#ifndef _WIN32
31
#include <sys/wait.h>
32
#endif
33

  
30 34
typedef struct IOHandlerRecord {
31 35
    int fd;
32 36
    IOCanReadHandler *fd_read_poll;
......
127 131
        }
128 132
    }
129 133
}
134

  
135
/* reaping of zombies.  right now we're not passing the status to
136
   anyone, but it would be possible to add a callback.  */
137
#ifndef _WIN32
138
typedef struct ChildProcessRecord {
139
    int pid;
140
    QLIST_ENTRY(ChildProcessRecord) next;
141
} ChildProcessRecord;
142

  
143
static QLIST_HEAD(, ChildProcessRecord) child_watches =
144
    QLIST_HEAD_INITIALIZER(child_watches);
145

  
146
static QEMUBH *sigchld_bh;
147

  
148
static void sigchld_handler(int signal)
149
{
150
    qemu_bh_schedule(sigchld_bh);
151
}
152

  
153
static void sigchld_bh_handler(void *opaque)
154
{
155
    ChildProcessRecord *rec, *next;
156

  
157
    QLIST_FOREACH_SAFE(rec, &child_watches, next, next) {
158
        if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) {
159
            QLIST_REMOVE(rec, next);
160
            qemu_free(rec);
161
        }
162
    }
163
}
164

  
165
static void qemu_init_child_watch(void)
166
{
167
    struct sigaction act;
168
    sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL);
169

  
170
    act.sa_handler = sigchld_handler;
171
    act.sa_flags = SA_NOCLDSTOP;
172
    sigaction(SIGCHLD, &act, NULL);
173
}
174

  
175
int qemu_add_child_watch(pid_t pid)
176
{
177
    ChildProcessRecord *rec;
178

  
179
    if (!sigchld_bh) {
180
        qemu_init_child_watch();
181
    }
182

  
183
    QLIST_FOREACH(rec, &child_watches, next) {
184
        if (rec->pid == pid) {
185
            return 1;
186
        }
187
    }
188
    rec = qemu_mallocz(sizeof(ChildProcessRecord));
189
    rec->pid = pid;
190
    QLIST_INSERT_HEAD(&child_watches, rec, next);
191
    return 0;
192
}
193
#endif
b/os-posix.c
67 67
    qemu_system_killed(info->si_signo, info->si_pid);
68 68
}
69 69

  
70
static void sigchld_handler(int signal)
71
{
72
    waitpid(-1, NULL, WNOHANG);
73
}
74

  
75 70
void os_setup_signal_handling(void)
76 71
{
77 72
    struct sigaction act;
......
82 77
    sigaction(SIGINT,  &act, NULL);
83 78
    sigaction(SIGHUP,  &act, NULL);
84 79
    sigaction(SIGTERM, &act, NULL);
85

  
86
    act.sa_handler = sigchld_handler;
87
    act.sa_flags = SA_NOCLDSTOP;
88
    sigaction(SIGCHLD, &act, NULL);
89 80
}
90 81

  
91 82
/* Find a likely location for support files using the location of the binary.
b/qemu-common.h
214 214
void qemu_set_cloexec(int fd);
215 215

  
216 216
#ifndef _WIN32
217
int qemu_add_child_watch(pid_t pid);
217 218
int qemu_eventfd(int pipefd[2]);
218 219
int qemu_pipe(int pipefd[2]);
219 220
#endif
b/slirp/misc.c
119 119
	char *bptr;
120 120
	const char *curarg;
121 121
	int c, i, ret;
122
	pid_t pid;
122 123

  
123 124
	DEBUG_CALL("fork_exec");
124 125
	DEBUG_ARG("so = %lx", (long)so);
......
142 143
		}
143 144
	}
144 145

  
145
	switch(fork()) {
146
	pid = fork();
147
	switch(pid) {
146 148
	 case -1:
147 149
		lprint("Error: fork failed: %s\n", strerror(errno));
148 150
		close(s);
......
206 208
		exit(1);
207 209

  
208 210
	 default:
211
		qemu_add_child_watch(pid);
209 212
		if (do_pty == 2) {
210 213
			close(s);
211 214
			so->s = master;

Also available in: Unified diff