From 6f7abfd55907d5b8956b429139c8436d2c5fef6d Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 14 Jan 2009 20:39:20 +0100 Subject: dfork: daemon_retval_done() might close socket already closed in daemon_close_allv() No Avahi daemon is running. If I start it at command-line with etc/init.d/avahi-daemon start or simply with avahi-daemon -D then the avahi-daemon eats all CPU-time. Stracing the process shows, that it loops endlessly in gettimeofday({1231956423, 692711}, NULL) = 0 gettimeofday({1231956423, 692735}, NULL) = 0 poll([{fd=5, events=POLLIN}, {fd=15, events=POLLIN}, \ {fd=14, events=POLLIN}, {fd=13, events=POLLIN}, \ {fd=12, events=POLLIN}, {fd=11, events=POLLIN}, \ {fd=10, events=POLLIN}, {fd=8, events=POLLIN}], 8, 62150) = 1 \ ([{fd=5, revents=POLLNVAL}]) The fd=5 is a BADFD. I found out that the fd was closed by daemon_retval_send() from libdaemon. (But: I think avahi-daemon should handle the POLLERR nevertheless.) Looking in libdaemon I found, that the library had already closed the fd=5 in daemon_close_all(), and closed it "again" as _daemon_retval_pipe[0] in daemon_retval_send() -> daemon_retval_done(), but in the meantime, this is an fd from the application, not from the library. I think, after closing _daemon_retval_pipe[0] in daemon_close_allv() the fd must be marked as closed. I have attached a patch. For me it works fine. --- libdaemon/dfork.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libdaemon/dfork.c b/libdaemon/dfork.c index 5f163fd..e705155 100644 --- a/libdaemon/dfork.c +++ b/libdaemon/dfork.c @@ -541,6 +541,9 @@ int daemon_close_allv(const int except_fds[]) { return -1; } + + if (fd == _daemon_retval_pipe[0]) + _daemon_retval_pipe[0] = -1; /* mark as closed */ } closedir(d); @@ -572,6 +575,9 @@ int daemon_close_allv(const int except_fds[]) { if (close(fd) < 0 && errno != EBADF) return -1; + + if (fd == _daemon_retval_pipe[0]) + _daemon_retval_pipe[0] = -1; /* mark as closed */ } return 0; -- cgit