aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2017-08-12 14:44:20 +0300
committerEli Zaretskii2017-08-12 14:44:20 +0300
commitfce2b2d2b40a1c0505d1ad623baef76f726c436a (patch)
treeb47d40c2cc59399db224828d8682c30cabdb1f87
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.
-rw-r--r--src/msdos.c17
-rw-r--r--src/w32.c19
2 files changed, 32 insertions, 4 deletions
diff --git a/src/msdos.c b/src/msdos.c
index 87b6f84148c..5b025753d98 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -3950,10 +3950,23 @@ faccessat (int dirfd, const char * path, int mode, int flags)
3950 && !(IS_DIRECTORY_SEP (path[0]) 3950 && !(IS_DIRECTORY_SEP (path[0])
3951 || IS_DEVICE_SEP (path[1]))) 3951 || IS_DEVICE_SEP (path[1])))
3952 { 3952 {
3953 errno = EBADF; 3953 char lastc = dir_pathname[strlen (dir_pathname) - 1];
3954 return -1; 3954
3955 if (strlen (dir_pathname) + strlen (path) + IS_DIRECTORY_SEP (lastc)
3956 >= MAXPATHLEN)
3957 {
3958 errno = ENAMETOOLONG;
3959 return -1;
3960 }
3961
3962 sprintf (fullname, "%s%s%s",
3963 dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", path);
3964 path = fullname;
3955 } 3965 }
3956 3966
3967 if ((mode & F_OK) != 0 && IS_DIRECTORY_SEP (path[strlen (path) - 1]))
3968 mode |= D_OK;
3969
3957 return access (path, mode); 3970 return access (path, mode);
3958} 3971}
3959 3972
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);