Revision 4d54ec78 iohandler.c

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

Also available in: Unified diff