summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan <stefan.thaeter@gmx.de>2009-01-14 20:39:20 +0100
committerLennart Poettering <lennart@poettering.net>2009-10-17 22:01:06 +0200
commit6f7abfd55907d5b8956b429139c8436d2c5fef6d (patch)
tree2ac73a8291678c69b5ea59eecdb468c1230a0525
parent8312ea47f754bc0962f4c92d8aa6a77c0d5c43a0 (diff)
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.
-rw-r--r--libdaemon/dfork.c6
1 files changed, 6 insertions, 0 deletions
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;