summaryrefslogtreecommitdiff
path: root/src/inotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/inotify.c')
-rw-r--r--src/inotify.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/inotify.c b/src/inotify.c
index bba9ce19c22..7140568f1b6 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -26,6 +26,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include <errno.h>
+#include <fcntl.h>
+
#include <sys/inotify.h>
#include <sys/ioctl.h>
@@ -40,6 +42,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
# define IN_ONLYDIR 0
#endif
+#ifdef HAVE_ANDROID
+#include "android.h" /* For `android_is_special_directory'. */
+#endif /* HAVE_ANDROID */
+
/* File handle for inotify. */
static int inotifyfd = -1;
@@ -144,6 +150,11 @@ symbol_to_inotifymask (Lisp_Object symb)
else if (EQ (symb, Qonlydir))
return IN_ONLYDIR;
+ else if (EQ (symb, Qignored))
+ return IN_IGNORED;
+ else if (EQ (symb, Qunmount))
+ return IN_UNMOUNT;
+
else if (EQ (symb, Qt) || EQ (symb, Qall_events))
return IN_ALL_EVENTS;
else
@@ -419,12 +430,21 @@ IN_ONESHOT */)
int wd = -1;
uint32_t imask = aspect_to_inotifymask (aspect);
uint32_t mask = imask | IN_MASK_ADD | IN_EXCL_UNLINK;
+ char *name;
CHECK_STRING (filename);
if (inotifyfd < 0)
{
+#ifdef HAVE_INOTIFY_INIT1
inotifyfd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC);
+#else /* !HAVE_INOTIFY_INIT1 */
+ /* This is prey to race conditions with other threads calling
+ exec. */
+ inotifyfd = inotify_init ();
+ fcntl (inotifyfd, F_SETFL, O_NONBLOCK);
+ fcntl (inotifyfd, F_SETFD, O_CLOEXEC);
+#endif /* HAVE_INOTIFY_INIT1 */
if (inotifyfd < 0)
report_file_notify_error ("File watching is not available", Qnil);
watch_list = Qnil;
@@ -432,7 +452,19 @@ IN_ONESHOT */)
}
encoded_file_name = ENCODE_FILE (filename);
- wd = inotify_add_watch (inotifyfd, SSDATA (encoded_file_name), mask);
+ name = SSDATA (encoded_file_name);
+
+#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
+ /* If FILENAME actually lies in a special directory, return now
+ instead of letting inotify fail. These directories cannot
+ receive file notifications as they are read only. */
+
+ if (android_is_special_directory (name, "/assets")
+ || android_is_special_directory (name, "/content"))
+ return Qnil;
+#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
+
+ wd = inotify_add_watch (inotifyfd, name, mask);
if (wd < 0)
report_file_notify_error ("Could not add watch for file", filename);
@@ -495,12 +527,14 @@ it invalid. */)
#ifdef INOTIFY_DEBUG
DEFUN ("inotify-watch-list", Finotify_watch_list, Sinotify_watch_list, 0, 0, 0,
doc: /* Return a copy of the internal watch_list. */)
+ (void)
{
return Fcopy_sequence (watch_list);
}
DEFUN ("inotify-allocated-p", Finotify_allocated_p, Sinotify_allocated_p, 0, 0, 0,
doc: /* Return non-nil, if an inotify instance is allocated. */)
+ (void)
{
return inotifyfd < 0 ? Qnil : Qt;
}