/* Filesystem notifications support for GNU Emacs on the Microsoft Windows API.
- Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Copyright (C) 2012-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
DWORD notifications_size;
void *notifications_desc;
-static Lisp_Object Qfile_name, Qdirectory_name, Qattributes;
-static Lisp_Object Qlast_write_time, Qlast_access_time, Qcreation_time;
-static Lisp_Object Qsecurity_desc, Qsubtree, watch_list;
+static Lisp_Object watch_list;
/* Signal to the main thread that we have file notifications for it to
process. */
if (!notification_buffer_in_use)
{
if (info_size)
- memcpy (file_notifications, info, info_size);
- notifications_size = info_size;
+ memcpy (file_notifications, info,
+ min (info_size, sizeof (file_notifications)));
+ notifications_size = min (info_size, sizeof (file_notifications));
notifications_desc = desc;
/* If PostMessage fails, the message queue is full. If that
happens, the last thing they will worry about is file
/* The underlying features are available only since XP. */
if (os_subtype == OS_9X
- || (w32_major_version == 5 && w32_major_version < 1))
+ || (w32_major_version == 5 && w32_minor_version < 1))
{
errno = ENOSYS;
- report_file_error ("Watching filesystem events is not supported",
- Qnil);
+ report_file_notify_error ("Watching filesystem events is not supported",
+ Qnil);
}
/* filenotify.el always passes us a directory, either the parent
Vlocale_coding_system, 0);
else
lisp_errstr = build_string (errstr);
- report_file_error ("Cannot watch file",
- Fcons (lisp_errstr, Fcons (file, Qnil)));
+ report_file_notify_error ("Cannot watch file",
+ Fcons (lisp_errstr, Fcons (file, Qnil)));
}
else
- report_file_error ("Cannot watch file", Fcons (file, Qnil));
+ report_file_notify_error ("Cannot watch file", Fcons (file, Qnil));
}
/* Store watch object in watch list. */
- watch_descriptor = XIL ((EMACS_INT)dirwatch);
+ watch_descriptor = make_pointer_integer (dirwatch);
watch_object = Fcons (watch_descriptor, callback);
watch_list = Fcons (watch_object, watch_list);
if (!NILP (watch_object))
{
watch_list = Fdelete (watch_object, watch_list);
- dirwatch = (struct notification *)XLI (watch_descriptor);
+ dirwatch = (struct notification *)XINTPTR (watch_descriptor);
if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)))
status = remove_watch (dirwatch);
}
if (status == -1)
- report_file_error ("Invalid watch descriptor", Fcons (watch_descriptor,
- Qnil));
+ report_file_notify_error ("Invalid watch descriptor",
+ Fcons (watch_descriptor, Qnil));
return Qnil;
}
Lisp_Object
w32_get_watch_object (void *desc)
{
- Lisp_Object descriptor = XIL ((EMACS_INT)desc);
+ Lisp_Object descriptor = make_pointer_integer (desc);
/* This is called from the input queue handling code, inside a
critical section, so we cannot possibly QUIT if watch_list is not
return NILP (watch_list) ? Qnil : assoc_no_quit (descriptor, watch_list);
}
+DEFUN ("w32notify-valid-p", Fw32notify_valid_p, Sw32notify_valid_p, 1, 1, 0,
+ doc: /* "Check a watch specified by its WATCH-DESCRIPTOR for validity.
+
+WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'.
+
+A watch can become invalid if the directory it watches is deleted, or if
+the watcher thread exits abnormally for any other reason. Removing the
+watch by calling `w32notify-rm-watch' also makes it invalid. */)
+ (Lisp_Object watch_descriptor)
+{
+ Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list);
+
+ if (!NILP (watch_object))
+ {
+ struct notification *dirwatch =
+ (struct notification *)XINTPTR (watch_descriptor);
+ if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))
+ && dirwatch->dir != NULL)
+ return Qt;
+ }
+
+ return Qnil;
+}
+
void
globals_of_w32notify (void)
{
defsubr (&Sw32notify_add_watch);
defsubr (&Sw32notify_rm_watch);
+ defsubr (&Sw32notify_valid_p);
staticpro (&watch_list);