--- rxvt-unicode/src/iom.C 2005/11/29 19:22:48 1.30 +++ rxvt-unicode/src/iom.C 2006/01/19 11:56:00 1.34 @@ -1,6 +1,6 @@ /* iom.C -- generic I/O multiplexer - Copyright (C) 2003, 2004 Marc Lehmann + Copyright (C) 2003-2006 Marc Lehmann This file is part of GVPE. @@ -24,18 +24,20 @@ #include #include #include +#include +#include #include -#include - #if 1 // older unices need these includes for select (2) # include -# include # include #endif -// for IOM_SIG +#if IOM_CHILD +# include +#endif + #if IOM_SIG # include # include @@ -72,28 +74,63 @@ }; static vector sw; #endif +#if IOM_CHILD +static io_manager_vec pw; +#endif // this is a dummy time watcher to ensure that the first // time watcher is _always_ valid, this gets rid of a lot // of null-pointer-checks // (must come _before_ iom is being defined) static struct tw0 : time_watcher +{ + void cb (time_watcher &w) { - void cb (time_watcher &w) - { - // should never get called - // reached end-of-time, or tstamp has a bogus definition, - // or compiler initialisation order broken, or something else :) - abort (); - } + // should never get called + // reached end-of-time, or tstamp has a bogus definition, + // or compiler initialisation order broken, or something else :) + abort (); + } - tw0 () - : time_watcher (this, &tw0::cb) - { } - } tw0; + tw0 () + : time_watcher (this, &tw0::cb) + { } +} tw0; tstamp NOW; +#if IOM_CHILD +// sig_watcher for child signal(s) +static struct sw0 : sig_watcher +{ + void cb (sig_watcher &w) + { + // SIGCHLD, call corresponding watchera + pid_t pid; + int status; + + while ((pid = waitpid (-1, &status, WNOHANG)) > 0) + for (int i = pw.size (); i--; ) + { + child_watcher *w = pw[i]; + + if (!w) + pw.erase_unordered (i); + else if (w->pid == pid) + { + w->stop (); + w->call (*w, status); + } + } + + } + + sw0 () + : sig_watcher (this, &sw0::cb) + { } +} sw0; +#endif + #if IOM_TIME tstamp io_manager::now () { @@ -115,6 +152,8 @@ static struct init { init () { + iom_valid = true; + #if IOM_SIG sigemptyset (&sigs); @@ -128,7 +167,9 @@ fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); fcntl (sigpipe[1], F_SETFD, FD_CLOEXEC); #endif - iom_valid = true; +#if IOM_CHILD + sw0.start (SIGCHLD); +#endif #if IOM_TIME io_manager::set_now (); @@ -137,6 +178,11 @@ #endif } + ~init () + { + iom_valid = false; + } + static void required (); } init; @@ -216,6 +262,8 @@ void io_manager::reg (sig_watcher &w) { + init::required (); + assert (0 < w.signum); sw.reserve (w.signum); @@ -250,7 +298,7 @@ void io_manager::unreg (sig_watcher &w) { - if (!w.active) + if (!w.active || !iom_valid) return; assert (0 < w.signum && w.signum <= sw.size ()); @@ -266,6 +314,11 @@ } #endif +#if IOM_CHILD +void io_manager::reg (child_watcher &w) { io_manager::reg (w, pw); } +void io_manager::unreg (child_watcher &w) { io_manager::unreg (w, pw); } +#endif + void io_manager::loop () { init::required ();