X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a8dd976aa5299060ee3670f8d693887960aa6ad8..63efcc268635dea78c6bd80749eae4ee2c72d717:/src/kqueue.c diff --git a/src/kqueue.c b/src/kqueue.c index e0ee5fb9d7..f45bd0c4c2 100644 --- a/src/kqueue.c +++ b/src/kqueue.c @@ -1,12 +1,13 @@ /* Filesystem notifications support with kqueue API. - Copyright (C) 2015 Free Software Foundation, Inc. + +Copyright (C) 2015-2016 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,6 +29,10 @@ along with GNU Emacs. If not, see . */ #include "keyboard.h" #include "process.h" +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif /* HAVE_SYS_RESOURCE_H */ + /* File handle for kqueue. */ static int kqueuefd = -1; @@ -66,9 +71,8 @@ kqueue_directory_listing (Lisp_Object directory_files) /* Generate a file notification event. */ static void -kqueue_generate_event -(Lisp_Object watch_object, Lisp_Object actions, - Lisp_Object file, Lisp_Object file1) +kqueue_generate_event (Lisp_Object watch_object, Lisp_Object actions, + Lisp_Object file, Lisp_Object file1) { Lisp_Object flags, action, entry; struct input_event event; @@ -108,8 +112,7 @@ kqueue_generate_event replaced by the new directory listing at the end of this function. */ static void -kqueue_compare_dir_list -(Lisp_Object watch_object) +kqueue_compare_dir_list (Lisp_Object watch_object) { Lisp_Object dir, pending_dl, deleted_dl; Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl; @@ -367,9 +370,12 @@ only when the upper directory of the renamed file is watched. */) (Lisp_Object file, Lisp_Object flags, Lisp_Object callback) { Lisp_Object watch_object, dir_list; - int fd, oflags; + int maxfd, fd, oflags; u_short fflags = 0; struct kevent kev; +#ifdef HAVE_GETRLIMIT + struct rlimit rlim; +#endif /* HAVE_GETRLIMIT */ /* Check parameters. */ CHECK_STRING (file); @@ -382,6 +388,21 @@ only when the upper directory of the renamed file is watched. */) if (! FUNCTIONP (callback)) wrong_type_argument (Qinvalid_function, callback); + /* Check available file descriptors. */ +#ifdef HAVE_GETRLIMIT + if (! getrlimit (RLIMIT_NOFILE, &rlim)) + maxfd = rlim.rlim_cur; + else +#endif /* HAVE_GETRLIMIT */ + maxfd = 256; + + /* We assume 50 file descriptors are sufficient for the rest of Emacs. */ + if ((maxfd - 50) < XINT (Flength (watch_list))) + xsignal2 + (Qfile_notify_error, + build_string ("File watching not possible, no file descriptor left"), + Flength (watch_list)); + if (kqueuefd < 0) { /* Create kqueue descriptor. */