From: Eli Zaretskii Date: Wed, 7 Sep 2022 12:18:54 +0000 (+0300) Subject: Don't follow symlinks in w32notify file watches X-Git-Tag: emacs-29.0.90~1856^2~680 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=579eefda36b9a8cd71c9aeff0f32e32d468727a3;p=emacs.git Don't follow symlinks in w32notify file watches * src/w32notify.c (add_watch): On filesystems that support symlinks, don't follow symlinks. (Bug#57536) * src/w32.c (symlinks_supported): New function. * src/w32.h (symlinks_supported): Add prototype. --- diff --git a/src/w32.c b/src/w32.c index 44c279602cf..9c7d536adad 100644 --- a/src/w32.c +++ b/src/w32.c @@ -6480,6 +6480,17 @@ chase_symlinks (const char *file) return target; } +/* Return non-zero if FILE's filesystem supports symlinks. */ +bool +symlinks_supported (const char *file) +{ + if (is_windows_9x () != TRUE + && get_volume_info (file, NULL) + && (volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0) + return true; + return false; +} + /* Posix ACL emulation. */ diff --git a/src/w32.h b/src/w32.h index dc91c595c43..b914aa9bafa 100644 --- a/src/w32.h +++ b/src/w32.h @@ -228,6 +228,8 @@ extern int sys_link (const char *, const char *); extern int openat (int, const char *, int, int); extern int fchmodat (int, char const *, mode_t, int); extern int lchmod (char const *, mode_t); +extern bool symlinks_supported (const char *); + /* Return total and free memory info. */ extern int w32_memory_info (unsigned long long *, unsigned long long *, diff --git a/src/w32notify.c b/src/w32notify.c index 72e634f77c7..6b5fce9f927 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -367,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]; @@ -383,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 @@ -400,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)