aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32.c
diff options
context:
space:
mode:
authorEli Zaretskii2017-08-12 14:44:20 +0300
committerEli Zaretskii2017-08-12 14:44:20 +0300
commitfce2b2d2b40a1c0505d1ad623baef76f726c436a (patch)
treeb47d40c2cc59399db224828d8682c30cabdb1f87 /src/w32.c
parentec5cfaa4568327b5b0b299be2664f7fdae123292 (diff)
downloademacs-fce2b2d2b40a1c0505d1ad623baef76f726c436a.tar.gz
emacs-fce2b2d2b40a1c0505d1ad623baef76f726c436a.zip
Fix completion on directory names on MS-DOS/MS-Windows
* src/msdos.c (faccessat): * src/w32.c (faccessat): Support relative file names, and add D_OK to 'mode' if the argument is a directory. This unbreaks file-name completion when the completion result is a directory.
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/w32.c b/src/w32.c
index bdeaed0675b..c5b51bb6b0e 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -3887,15 +3887,30 @@ int
3887faccessat (int dirfd, const char * path, int mode, int flags) 3887faccessat (int dirfd, const char * path, int mode, int flags)
3888{ 3888{
3889 DWORD attributes; 3889 DWORD attributes;
3890 char fullname[MAX_UTF8_PATH];
3890 3891
3892 /* Rely on a hack: an open directory is modeled as file descriptor 0,
3893 and its actual file name is stored in dir_pathname by opendir.
3894 This is good enough for the current usage in Emacs, but is fragile. */
3891 if (dirfd != AT_FDCWD 3895 if (dirfd != AT_FDCWD
3892 && !(IS_DIRECTORY_SEP (path[0]) 3896 && !(IS_DIRECTORY_SEP (path[0])
3893 || IS_DEVICE_SEP (path[1]))) 3897 || IS_DEVICE_SEP (path[1])))
3894 { 3898 {
3895 errno = EBADF; 3899 char lastc = dir_pathname[strlen (dir_pathname) - 1];
3896 return -1; 3900
3901 if (_snprintf (fullname, sizeof fullname, "%s%s%s",
3902 dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", path)
3903 < 0)
3904 {
3905 errno = ENAMETOOLONG;
3906 return -1;
3907 }
3908 path = fullname;
3897 } 3909 }
3898 3910
3911 if (IS_DIRECTORY_SEP (path[strlen (path) - 1]) && (mode & F_OK) != 0)
3912 mode |= D_OK;
3913
3899 /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its 3914 /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its
3900 newer versions blow up when passed D_OK. */ 3915 newer versions blow up when passed D_OK. */
3901 path = map_w32_filename (path, NULL); 3916 path = map_w32_filename (path, NULL);