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. */