I've found and fixed another bug related to signal handling - sigcx's non-GTK library doesn't handle select() bailing due to EINTR, and generates spurious file events as a result. This is patch-6 in my arch branch, the following diff as attached, and I've updated the pretend-NMU to -2.4 which contains it.
Fix interruption of select() by a signal causing spurrious file events. The select() loop wasn't being restarted on EINTR, wrap it in such a loop. Previously, it'd cause a fall-through into attempting to read fd sets that hadn't been initialized, and would generate spurrious file events as a result. - Steven Brown <[EMAIL PROTECTED]> --- orig/sigcx/dispatch.cc +++ mod/sigcx/dispatch.cc @@ -357,31 +357,36 @@ fd_set wr = wr_fds_; fd_set ex = ex_fds_; - if (tm_events_.size() == 0) + // Loop on select, restarting if we were interrupted by a signal. + int result; + do { - UnGuard unguard (mutex_); - int result = select(FD_SETSIZE, &rd, &wr, &ex, 0); - assert(result != -1 || errno == EINTR); - } - else - { - now.get_current_time(); - timeout = tm_events_.begin()->first.expiration - now; + if (tm_events_.size() == 0) + { + UnGuard unguard (mutex_); + result = select(FD_SETSIZE, &rd, &wr, &ex, 0); + assert(result != -1 || errno == EINTR); + } + else + { + now.get_current_time(); + timeout = tm_events_.begin()->first.expiration - now; - UnGuard unguard(mutex_); - - if (timeout < TimeVal(0)) - timeout = TimeVal(0); - - struct timeval tv; - tv.tv_sec = timeout.tv_sec; - tv.tv_usec = timeout.tv_usec; - - int result = select(FD_SETSIZE, &rd, &wr, &ex, &tv); - assert(result != -1 || errno == EINTR); - } + UnGuard unguard(mutex_); + + if (timeout < TimeVal(0)) + timeout = TimeVal(0); + + struct timeval tv; + tv.tv_sec = timeout.tv_sec; + tv.tv_usec = timeout.tv_usec; + + result = select(FD_SETSIZE, &rd, &wr, &ex, &tv); + assert(result != -1 || errno == EINTR); + } + } while(result == -1 && errno == EINTR); - // check after select, we might have caught a signal + // check if we've been asked to exit. If so, exit early. if (do_exit_) break;