aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2022-09-07 15:18:54 +0300
committerEli Zaretskii2022-09-07 15:18:54 +0300
commit579eefda36b9a8cd71c9aeff0f32e32d468727a3 (patch)
tree7b5cdc52f3f8858691ec05925351c8302caeae27 /src
parentc6c9dfc8670f5698634a8d5853853056ff928974 (diff)
downloademacs-579eefda36b9a8cd71c9aeff0f32e32d468727a3.tar.gz
emacs-579eefda36b9a8cd71c9aeff0f32e32d468727a3.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/w32.c11
-rw-r--r--src/w32.h2
-rw-r--r--src/w32notify.c12
3 files changed, 21 insertions, 4 deletions
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)
6480 return target; 6480 return target;
6481} 6481}
6482 6482
6483/* Return non-zero if FILE's filesystem supports symlinks. */
6484bool
6485symlinks_supported (const char *file)
6486{
6487 if (is_windows_9x () != TRUE
6488 && get_volume_info (file, NULL)
6489 && (volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0)
6490 return true;
6491 return false;
6492}
6493
6483 6494
6484/* Posix ACL emulation. */ 6495/* Posix ACL emulation. */
6485 6496
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 *);
228extern int openat (int, const char *, int, int); 228extern int openat (int, const char *, int, int);
229extern int fchmodat (int, char const *, mode_t, int); 229extern int fchmodat (int, char const *, mode_t, int);
230extern int lchmod (char const *, mode_t); 230extern int lchmod (char const *, mode_t);
231extern bool symlinks_supported (const char *);
232
231 233
232/* Return total and free memory info. */ 234/* Return total and free memory info. */
233extern int w32_memory_info (unsigned long long *, unsigned long long *, 235extern 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)
367 if (!file) 367 if (!file)
368 return NULL; 368 return NULL;
369 369
370 /* Do not follow symlinks, so that the caller could watch symlink
371 files. */
372 DWORD crflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
373 if (symlinks_supported (parent_dir))
374 crflags |= FILE_FLAG_OPEN_REPARSE_POINT;
375
370 if (w32_unicode_filenames) 376 if (w32_unicode_filenames)
371 { 377 {
372 wchar_t dir_w[MAX_PATH], file_w[MAX_PATH]; 378 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)
383 processes from deleting files inside 389 processes from deleting files inside
384 parent_dir. */ 390 parent_dir. */
385 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 391 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
386 NULL, OPEN_EXISTING, 392 NULL, OPEN_EXISTING, crflags,
387 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
388 NULL); 393 NULL);
389 } 394 }
390 else 395 else
@@ -400,8 +405,7 @@ add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags)
400 hdir = CreateFileA (dir_a, 405 hdir = CreateFileA (dir_a,
401 FILE_LIST_DIRECTORY, 406 FILE_LIST_DIRECTORY,
402 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 407 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
403 NULL, OPEN_EXISTING, 408 NULL, OPEN_EXISTING, crflags,
404 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
405 NULL); 409 NULL);
406 } 410 }
407 if (hdir == INVALID_HANDLE_VALUE) 411 if (hdir == INVALID_HANDLE_VALUE)