X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=iohandler.c;h=2b824218e501b475a72af361eff9cc435e0ea107;hb=68e3508eafd111c050e0a6f4dc8588dbe75d0e1c;hp=2e30fe3bcb7384bb13ce466939f7777d481defb1;hpb=0298141998ea3e19fd86b5a7122aab2fd1ebad51;p=qemu.git diff --git a/iohandler.c b/iohandler.c index 2e30fe3bc..2b824218e 100644 --- a/iohandler.c +++ b/iohandler.c @@ -27,6 +27,10 @@ #include "qemu-char.h" #include "qemu-queue.h" +#ifndef _WIN32 +#include +#endif + typedef struct IOHandlerRecord { int fd; IOCanReadHandler *fd_read_poll; @@ -127,3 +131,63 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int re } } } + +/* reaping of zombies. right now we're not passing the status to + anyone, but it would be possible to add a callback. */ +#ifndef _WIN32 +typedef struct ChildProcessRecord { + int pid; + QLIST_ENTRY(ChildProcessRecord) next; +} ChildProcessRecord; + +static QLIST_HEAD(, ChildProcessRecord) child_watches = + QLIST_HEAD_INITIALIZER(child_watches); + +static QEMUBH *sigchld_bh; + +static void sigchld_handler(int signal) +{ + qemu_bh_schedule(sigchld_bh); +} + +static void sigchld_bh_handler(void *opaque) +{ + ChildProcessRecord *rec, *next; + + QLIST_FOREACH_SAFE(rec, &child_watches, next, next) { + if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) { + QLIST_REMOVE(rec, next); + qemu_free(rec); + } + } +} + +static void qemu_init_child_watch(void) +{ + struct sigaction act; + sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL); + + act.sa_handler = sigchld_handler; + act.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &act, NULL); +} + +int qemu_add_child_watch(pid_t pid) +{ + ChildProcessRecord *rec; + + if (!sigchld_bh) { + qemu_init_child_watch(); + } + + QLIST_FOREACH(rec, &child_watches, next) { + if (rec->pid == pid) { + return 1; + } + } + rec = qemu_mallocz(sizeof(ChildProcessRecord)); + rec->pid = pid; + QLIST_INSERT_HEAD(&child_watches, rec, next); + return 0; +} +#endif