diff options
Diffstat (limited to 'src/w32notify.c')
-rw-r--r-- | src/w32notify.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/src/w32notify.c b/src/w32notify.c index 4e0e5804a55..6b5fce9f927 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -1,5 +1,8 @@ /* Filesystem notifications support for GNU Emacs on the Microsoft Windows API. - Copyright (C) 2012-2017 Free Software Foundation, Inc. + +Copyright (C) 2012-2022 Free Software Foundation, Inc. + +Author: Eli Zaretskii <eliz@gnu.org> This file is part of GNU Emacs. @@ -16,9 +19,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ -/* Written by Eli Zaretskii <eliz@gnu.org>. - - Design overview: +/* Design overview: For each watch request, we launch a separate worker thread. The worker thread runs the watch_worker function, which issues an @@ -39,8 +40,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ and returns. That causes the WaitForSingleObjectEx function call inside watch_worker to return, but the thread won't terminate until the event telling to do so will be signaled. The completion - routine issued another call to ReadDirectoryChangesW as quickly as - possible. (Except when it does not, see below.) + routine then issues another call to ReadDirectoryChangesW as quickly + as possible. (Except when it does not, see below.) In a GUI session, the WM_EMACS_FILENOTIFY message posted to the message queue gets dispatched to the main Emacs window procedure, @@ -366,6 +367,12 @@ add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags) if (!file) return NULL; + /* Do not follow symlinks, so that the caller could watch symlink + files. */ + DWORD crflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED; + if (symlinks_supported (parent_dir)) + crflags |= FILE_FLAG_OPEN_REPARSE_POINT; + if (w32_unicode_filenames) { wchar_t dir_w[MAX_PATH], file_w[MAX_PATH]; @@ -382,8 +389,7 @@ add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags) processes from deleting files inside parent_dir. */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + NULL, OPEN_EXISTING, crflags, NULL); } else @@ -399,8 +405,7 @@ add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags) hdir = CreateFileA (dir_a, FILE_LIST_DIRECTORY, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + NULL, OPEN_EXISTING, crflags, NULL); } if (hdir == INVALID_HANDLE_VALUE) @@ -518,16 +523,16 @@ watched for some reason, this function signals a `file-error' error. FILTER is a list of conditions for reporting an event. It can include the following symbols: - 'file-name' -- report file creation, deletion, or renaming - 'directory-name' -- report directory creation, deletion, or renaming - 'attributes' -- report changes in attributes - 'size' -- report changes in file-size - 'last-write-time' -- report changes in last-write time - 'last-access-time' -- report changes in last-access time - 'creation-time' -- report changes in creation time - 'security-desc' -- report changes in security descriptor + `file-name' -- report file creation, deletion, or renaming + `directory-name' -- report directory creation, deletion, or renaming + `attributes' -- report changes in attributes + `size' -- report changes in file-size + `last-write-time' -- report changes in last-write time + `last-access-time' -- report changes in last-access time + `creation-time' -- report changes in creation time + `security-desc' -- report changes in security descriptor -If FILE is a directory, and FILTER includes 'subtree', then all the +If FILE is a directory, and FILTER includes `subtree', then all the subdirectories will also be watched and changes in them reported. When any event happens that satisfies the conditions specified by @@ -540,11 +545,11 @@ DESCRIPTOR is the same object as the one returned by this function. ACTION is the description of the event. It could be any one of the following: - 'added' -- FILE was added - 'removed' -- FILE was deleted - 'modified' -- FILE's contents or its attributes were modified - 'renamed-from' -- a file was renamed whose old name was FILE - 'renamed-to' -- a file was renamed and its new name is FILE + `added' -- FILE was added + `removed' -- FILE was deleted + `modified' -- FILE's contents or its attributes were modified + `renamed-from' -- a file was renamed whose old name was FILE + `renamed-to' -- a file was renamed and its new name is FILE FILE is the name of the file whose event is being reported. @@ -565,7 +570,7 @@ generate notifications correctly, though. */) CHECK_LIST (filter); /* The underlying features are available only since XP. */ - if (os_subtype == OS_9X + if (os_subtype == OS_SUBTYPE_9X || (w32_major_version == 5 && w32_minor_version < 1)) { errno = ENOSYS; @@ -621,7 +626,7 @@ generate notifications correctly, though. */) report_file_notify_error ("Cannot watch file", Fcons (file, Qnil)); } /* Store watch object in watch list. */ - watch_descriptor = make_pointer_integer (dirwatch); + watch_descriptor = make_mint_ptr (dirwatch); watch_object = Fcons (watch_descriptor, callback); watch_list = Fcons (watch_object, watch_list); @@ -646,7 +651,7 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. */) if (!NILP (watch_object)) { watch_list = Fdelete (watch_object, watch_list); - dirwatch = (struct notification *)XINTPTR (watch_descriptor); + dirwatch = (struct notification *)xmint_pointer (watch_descriptor); if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))) status = remove_watch (dirwatch); } @@ -661,7 +666,7 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. */) Lisp_Object w32_get_watch_object (void *desc) { - Lisp_Object descriptor = make_pointer_integer (desc); + Lisp_Object descriptor = make_mint_ptr (desc); /* This is called from the input queue handling code, inside a critical section, so we cannot possibly quit if watch_list is not @@ -684,7 +689,7 @@ watch by calling `w32notify-rm-watch' also makes it invalid. */) if (!NILP (watch_object)) { struct notification *dirwatch = - (struct notification *)XINTPTR (watch_descriptor); + (struct notification *)xmint_pointer (watch_descriptor); if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)) && dirwatch->dir != NULL) return Qt; |