1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2 * Permission is hereby granted, free of charge, to any person obtaining a copy
3 * of this software and associated documentation files (the "Software"), to
4 * deal in the Software without restriction, including without limitation the
5 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6 * sell copies of the Software, and to permit persons to whom the Software is
7 * furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
19 */
20
21#include "uv.h"
22#include "internal.h"
23
24#include <assert.h>
25#include <stdlib.h>
26#include <string.h>
27#include <errno.h>
28
29#include <sys/sysctl.h>
30#include <sys/types.h>
31#include <sys/event.h>
32#include <sys/time.h>
33#include <unistd.h>
34#include <fcntl.h>
35#include <time.h>
36
37/*
38 * Required on
39 * - Until at least FreeBSD 11.0
40 * - Older versions of Mac OS X
41 *
42 * http://www.boost.org/doc/libs/1_61_0/boost/asio/detail/kqueue_reactor.hpp
43 */
44#ifndef EV_OOBAND
45#define EV_OOBAND  EV_FLAG1
46#endif
47
48static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
49
50
51int uv__kqueue_init(uv_loop_t* loop) {
52  loop->backend_fd = kqueue();
53  if (loop->backend_fd == -1)
54    return UV__ERR(errno);
55
56  uv__cloexec(loop->backend_fd, 1);
57
58  return 0;
59}
60
61
62#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
63static int uv__has_forked_with_cfrunloop;
64#endif
65
66int uv__io_fork(uv_loop_t* loop) {
67  int err;
68  loop->backend_fd = -1;
69  err = uv__kqueue_init(loop);
70  if (err)
71    return err;
72
73#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
74  if (loop->cf_state != NULL) {
75    /* We cannot start another CFRunloop and/or thread in the child
76       process; CF aborts if you try or if you try to touch the thread
77       at all to kill it. So the best we can do is ignore it from now
78       on. This means we can't watch directories in the same way
79       anymore (like other BSDs). It also means we cannot properly
80       clean up the allocated resources; calling
81       uv__fsevents_loop_delete from uv_loop_close will crash the
82       process. So we sidestep the issue by pretending like we never
83       started it in the first place.
84    */
85    uv__store_relaxed(&uv__has_forked_with_cfrunloop, 1);
86    uv__free(loop->cf_state);
87    loop->cf_state = NULL;
88  }
89#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
90  return err;
91}
92
93
94int uv__io_check_fd(uv_loop_t* loop, int fd) {
95  struct kevent ev;
96  int rc;
97
98  rc = 0;
99  EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
100  if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
101    rc = UV__ERR(errno);
102
103  EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
104  if (rc == 0)
105    if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
106      abort();
107
108  return rc;
109}
110
111
112void uv__io_poll(uv_loop_t* loop, int timeout) {
113  struct kevent events[1024];
114  struct kevent* ev;
115  struct timespec spec;
116  unsigned int nevents;
117  unsigned int revents;
118  QUEUE* q;
119  uv__io_t* w;
120  uv_process_t* process;
121  sigset_t* pset;
122  sigset_t set;
123  uint64_t base;
124  uint64_t diff;
125  int have_signals;
126  int filter;
127  int fflags;
128  int count;
129  int nfds;
130  int fd;
131  int op;
132  int i;
133  int user_timeout;
134  int reset_timeout;
135
136  if (loop->nfds == 0) {
137    assert(QUEUE_EMPTY(&loop->watcher_queue));
138    return;
139  }
140
141  nevents = 0;
142
143  while (!QUEUE_EMPTY(&loop->watcher_queue)) {
144    q = QUEUE_HEAD(&loop->watcher_queue);
145    QUEUE_REMOVE(q);
146    QUEUE_INIT(q);
147
148    w = QUEUE_DATA(q, uv__io_t, watcher_queue);
149    assert(w->pevents != 0);
150    assert(w->fd >= 0);
151    assert(w->fd < (int) loop->nwatchers);
152
153    if ((w->events & POLLIN) == 0 && (w->pevents & POLLIN) != 0) {
154      filter = EVFILT_READ;
155      fflags = 0;
156      op = EV_ADD;
157
158      if (w->cb == uv__fs_event) {
159        filter = EVFILT_VNODE;
160        fflags = NOTE_ATTRIB | NOTE_WRITE  | NOTE_RENAME
161               | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
162        op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */
163      }
164
165      EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0);
166
167      if (++nevents == ARRAY_SIZE(events)) {
168        if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
169          abort();
170        nevents = 0;
171      }
172    }
173
174    if ((w->events & POLLOUT) == 0 && (w->pevents & POLLOUT) != 0) {
175      EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
176
177      if (++nevents == ARRAY_SIZE(events)) {
178        if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
179          abort();
180        nevents = 0;
181      }
182    }
183
184   if ((w->events & UV__POLLPRI) == 0 && (w->pevents & UV__POLLPRI) != 0) {
185      EV_SET(events + nevents, w->fd, EV_OOBAND, EV_ADD, 0, 0, 0);
186
187      if (++nevents == ARRAY_SIZE(events)) {
188        if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
189          abort();
190        nevents = 0;
191      }
192    }
193
194    w->events = w->pevents;
195  }
196
197  pset = NULL;
198  if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
199    pset = &set;
200    sigemptyset(pset);
201    sigaddset(pset, SIGPROF);
202  }
203
204  assert(timeout >= -1);
205  base = loop->time;
206  count = 48; /* Benchmarks suggest this gives the best throughput. */
207
208  if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
209    reset_timeout = 1;
210    user_timeout = timeout;
211    timeout = 0;
212  } else {
213    reset_timeout = 0;
214  }
215
216  for (;; nevents = 0) {
217    /* Only need to set the provider_entry_time if timeout != 0. The function
218     * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
219     */
220    if (timeout != 0)
221      uv__metrics_set_provider_entry_time(loop);
222
223    if (timeout != -1) {
224      spec.tv_sec = timeout / 1000;
225      spec.tv_nsec = (timeout % 1000) * 1000000;
226    }
227
228    if (pset != NULL)
229      pthread_sigmask(SIG_BLOCK, pset, NULL);
230
231    nfds = kevent(loop->backend_fd,
232                  events,
233                  nevents,
234                  events,
235                  ARRAY_SIZE(events),
236                  timeout == -1 ? NULL : &spec);
237
238    if (pset != NULL)
239      pthread_sigmask(SIG_UNBLOCK, pset, NULL);
240
241    /* Update loop->time unconditionally. It's tempting to skip the update when
242     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
243     * operating system didn't reschedule our process while in the syscall.
244     */
245    SAVE_ERRNO(uv__update_time(loop));
246
247    if (nfds == 0) {
248      if (reset_timeout != 0) {
249        timeout = user_timeout;
250        reset_timeout = 0;
251        if (timeout == -1)
252          continue;
253        if (timeout > 0)
254          goto update_timeout;
255      }
256
257      assert(timeout != -1);
258      return;
259    }
260
261    if (nfds == -1) {
262      if (errno != EINTR)
263        abort();
264
265      if (reset_timeout != 0) {
266        timeout = user_timeout;
267        reset_timeout = 0;
268      }
269
270      if (timeout == 0)
271        return;
272
273      if (timeout == -1)
274        continue;
275
276      /* Interrupted by a signal. Update timeout and poll again. */
277      goto update_timeout;
278    }
279
280    have_signals = 0;
281    nevents = 0;
282
283    assert(loop->watchers != NULL);
284    loop->watchers[loop->nwatchers] = (void*) events;
285    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
286    for (i = 0; i < nfds; i++) {
287      ev = events + i;
288      fd = ev->ident;
289
290      /* Handle kevent NOTE_EXIT results */
291      if (ev->filter == EVFILT_PROC) {
292        QUEUE_FOREACH(q, &loop->process_handles) {
293          process = QUEUE_DATA(q, uv_process_t, queue);
294          if (process->pid == fd) {
295            process->flags |= UV_HANDLE_REAP;
296            loop->flags |= UV_LOOP_REAP_CHILDREN;
297            break;
298          }
299        }
300        nevents++;
301        continue;
302      }
303
304      /* Skip invalidated events, see uv__platform_invalidate_fd */
305      if (fd == -1)
306        continue;
307      w = loop->watchers[fd];
308
309      if (w == NULL) {
310        /* File descriptor that we've stopped watching, disarm it.
311         * TODO: batch up. */
312        struct kevent events[1];
313
314        EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
315        if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
316          if (errno != EBADF && errno != ENOENT)
317            abort();
318
319        continue;
320      }
321
322      if (ev->filter == EVFILT_VNODE) {
323        assert(w->events == POLLIN);
324        assert(w->pevents == POLLIN);
325        uv__metrics_update_idle_time(loop);
326        w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
327        nevents++;
328        continue;
329      }
330
331      revents = 0;
332
333      if (ev->filter == EVFILT_READ) {
334        if (w->pevents & POLLIN) {
335          revents |= POLLIN;
336          w->rcount = ev->data;
337        } else {
338          /* TODO batch up */
339          struct kevent events[1];
340          EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
341          if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
342            if (errno != ENOENT)
343              abort();
344        }
345        if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP))
346          revents |= UV__POLLRDHUP;
347      }
348
349      if (ev->filter == EV_OOBAND) {
350        if (w->pevents & UV__POLLPRI) {
351          revents |= UV__POLLPRI;
352          w->rcount = ev->data;
353        } else {
354          /* TODO batch up */
355          struct kevent events[1];
356          EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
357          if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
358            if (errno != ENOENT)
359              abort();
360        }
361      }
362
363      if (ev->filter == EVFILT_WRITE) {
364        if (w->pevents & POLLOUT) {
365          revents |= POLLOUT;
366          w->wcount = ev->data;
367        } else {
368          /* TODO batch up */
369          struct kevent events[1];
370          EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
371          if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
372            if (errno != ENOENT)
373              abort();
374        }
375      }
376
377      if (ev->flags & EV_ERROR)
378        revents |= POLLERR;
379
380      if (revents == 0)
381        continue;
382
383      /* Run signal watchers last.  This also affects child process watchers
384       * because those are implemented in terms of signal watchers.
385       */
386      if (w == &loop->signal_io_watcher) {
387        have_signals = 1;
388      } else {
389        uv__metrics_update_idle_time(loop);
390        w->cb(loop, w, revents);
391      }
392
393      nevents++;
394    }
395
396    if (loop->flags & UV_LOOP_REAP_CHILDREN) {
397      loop->flags &= ~UV_LOOP_REAP_CHILDREN;
398      uv__wait_children(loop);
399    }
400
401    if (reset_timeout != 0) {
402      timeout = user_timeout;
403      reset_timeout = 0;
404    }
405
406    if (have_signals != 0) {
407      uv__metrics_update_idle_time(loop);
408      loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
409    }
410
411    loop->watchers[loop->nwatchers] = NULL;
412    loop->watchers[loop->nwatchers + 1] = NULL;
413
414    if (have_signals != 0)
415      return;  /* Event loop should cycle now so don't poll again. */
416
417    if (nevents != 0) {
418      if (nfds == ARRAY_SIZE(events) && --count != 0) {
419        /* Poll for more events but don't block this time. */
420        timeout = 0;
421        continue;
422      }
423      return;
424    }
425
426    if (timeout == 0)
427      return;
428
429    if (timeout == -1)
430      continue;
431
432update_timeout:
433    assert(timeout > 0);
434
435    diff = loop->time - base;
436    if (diff >= (uint64_t) timeout)
437      return;
438
439    timeout -= diff;
440  }
441}
442
443
444void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
445  struct kevent* events;
446  uintptr_t i;
447  uintptr_t nfds;
448
449  assert(loop->watchers != NULL);
450  assert(fd >= 0);
451
452  events = (struct kevent*) loop->watchers[loop->nwatchers];
453  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
454  if (events == NULL)
455    return;
456
457  /* Invalidate events with same file descriptor */
458  for (i = 0; i < nfds; i++)
459    if ((int) events[i].ident == fd && events[i].filter != EVFILT_PROC)
460      events[i].ident = -1;
461}
462
463
464static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
465  uv_fs_event_t* handle;
466  struct kevent ev;
467  int events;
468  const char* path;
469#if defined(F_GETPATH)
470  /* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */
471  char pathbuf[MAXPATHLEN];
472#endif
473
474  handle = container_of(w, uv_fs_event_t, event_watcher);
475
476  if (fflags & (NOTE_ATTRIB | NOTE_EXTEND))
477    events = UV_CHANGE;
478  else
479    events = UV_RENAME;
480
481  path = NULL;
482#if defined(F_GETPATH)
483  /* Also works when the file has been unlinked from the file system. Passing
484   * in the path when the file has been deleted is arguably a little strange
485   * but it's consistent with what the inotify backend does.
486   */
487  if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0)
488    path = uv__basename_r(pathbuf);
489#endif
490  handle->cb(handle, path, events, 0);
491
492  if (handle->event_watcher.fd == -1)
493    return;
494
495  /* Watcher operates in one-shot mode, re-arm it. */
496  fflags = NOTE_ATTRIB | NOTE_WRITE  | NOTE_RENAME
497         | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
498
499  EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0);
500
501  if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
502    abort();
503}
504
505
506int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
507  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
508  return 0;
509}
510
511
512int uv_fs_event_start(uv_fs_event_t* handle,
513                      uv_fs_event_cb cb,
514                      const char* path,
515                      unsigned int flags) {
516  int fd;
517#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
518  struct stat statbuf;
519#endif
520
521  if (uv__is_active(handle))
522    return UV_EINVAL;
523
524  handle->cb = cb;
525  handle->path = uv__strdup(path);
526  if (handle->path == NULL)
527    return UV_ENOMEM;
528
529  /* TODO open asynchronously - but how do we report back errors? */
530  fd = open(handle->path, O_RDONLY);
531  if (fd == -1) {
532    uv__free(handle->path);
533    handle->path = NULL;
534    return UV__ERR(errno);
535  }
536
537#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
538  /* Nullify field to perform checks later */
539  handle->cf_cb = NULL;
540  handle->realpath = NULL;
541  handle->realpath_len = 0;
542  handle->cf_flags = flags;
543
544  if (fstat(fd, &statbuf))
545    goto fallback;
546  /* FSEvents works only with directories */
547  if (!(statbuf.st_mode & S_IFDIR))
548    goto fallback;
549
550  if (0 == uv__load_relaxed(&uv__has_forked_with_cfrunloop)) {
551    int r;
552    /* The fallback fd is no longer needed */
553    uv__close_nocheckstdio(fd);
554    handle->event_watcher.fd = -1;
555    r = uv__fsevents_init(handle);
556    if (r == 0) {
557      uv__handle_start(handle);
558    } else {
559      uv__free(handle->path);
560      handle->path = NULL;
561    }
562    return r;
563  }
564fallback:
565#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
566
567  uv__handle_start(handle);
568  uv__io_init(&handle->event_watcher, uv__fs_event, fd);
569  uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
570
571  return 0;
572}
573
574
575int uv_fs_event_stop(uv_fs_event_t* handle) {
576  int r;
577  r = 0;
578
579  if (!uv__is_active(handle))
580    return 0;
581
582  uv__handle_stop(handle);
583
584#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
585  if (0 == uv__load_relaxed(&uv__has_forked_with_cfrunloop))
586    if (handle->cf_cb != NULL)
587      r = uv__fsevents_close(handle);
588#endif
589
590  if (handle->event_watcher.fd != -1) {
591    uv__io_close(handle->loop, &handle->event_watcher);
592    uv__close(handle->event_watcher.fd);
593    handle->event_watcher.fd = -1;
594  }
595
596  uv__free(handle->path);
597  handle->path = NULL;
598
599  return r;
600}
601
602
603void uv__fs_event_close(uv_fs_event_t* handle) {
604  uv_fs_event_stop(handle);
605}
606