diff options
author | Stefan <stefan.thaeter@gmx.de> | 2009-01-14 20:39:20 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2009-10-17 22:01:06 +0200 |
commit | 6f7abfd55907d5b8956b429139c8436d2c5fef6d (patch) | |
tree | 2ac73a8291678c69b5ea59eecdb468c1230a0525 /libdaemon/dfork.c | |
parent | 8312ea47f754bc0962f4c92d8aa6a77c0d5c43a0 (diff) | |
download | platform_external_libdaemon-6f7abfd55907d5b8956b429139c8436d2c5fef6d.tar.gz platform_external_libdaemon-6f7abfd55907d5b8956b429139c8436d2c5fef6d.tar.bz2 platform_external_libdaemon-6f7abfd55907d5b8956b429139c8436d2c5fef6d.zip |
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.
Diffstat (limited to 'libdaemon/dfork.c')
-rw-r--r-- | libdaemon/dfork.c | 6 |
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; |