summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes4
-rw-r--r--ev.c24
2 files changed, 26 insertions, 2 deletions
diff --git a/Changes b/Changes
index 5c50a48..2e90c5a 100644
--- a/Changes
+++ b/Changes
@@ -1,11 +1,15 @@
Revision history for libev, a high-performance and full-featured event loop.
- backport inotify code to C89.
+ - inotify file descriptors were not properly recreated after a fork,
+ and could leak into child processes.
- implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration
symbols to make it easier for apps to do their own fd management.
- support EV_IDLE_ENABLE being disabled in ev++.h
(patch by Didier Spezia).
- point out the unspecified signal mask in the documentation.
+ - take advantage of inotify_init1, if available, to set cloexec/nonblock
+ on fd creation, to avoid races.
- changed minimum glibc requirement from glibc 2.9 to 2.7, for
signalfd.
diff --git a/ev.c b/ev.c
index 2403b32..ddfbe8b 100644
--- a/ev.c
+++ b/ev.c
@@ -2999,6 +2999,17 @@ check_2625 (EV_P)
fs_2625 = 1;
}
+inline_size int
+infy_newfd (void)
+{
+#if defined (IN_CLOEXEC) && defined (IN_NONBLOCK)
+ int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK);
+ if (fd >= 0)
+ return fd;
+#endif
+ return inotify_init ();
+}
+
inline_size void
infy_init (EV_P)
{
@@ -3009,10 +3020,11 @@ infy_init (EV_P)
check_2625 (EV_A);
- fs_fd = inotify_init ();
+ fs_fd = infy_newfd ();
if (fs_fd >= 0)
{
+ fd_intern (fs_fd);
ev_io_init (&fs_w, infy_cb, fs_fd, EV_READ);
ev_set_priority (&fs_w, EV_MAXPRI);
ev_io_start (EV_A_ &fs_w);
@@ -3027,8 +3039,16 @@ infy_fork (EV_P)
if (fs_fd < 0)
return;
+ ev_io_stop (EV_A_ &fs_w);
close (fs_fd);
- fs_fd = inotify_init ();
+ fs_fd = infy_newfd ();
+
+ if (fs_fd >= 0)
+ {
+ fd_intern (fs_fd);
+ ev_io_set (&fs_w, fs_fd, EV_READ);
+ ev_io_start (EV_A_ &fs_w);
+ }
for (slot = 0; slot < EV_INOTIFY_HASHSIZE; ++slot)
{