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.
This commit is contained in:
Eli Zaretskii 2017-08-12 14:44:20 +03:00
parent ec5cfaa456
commit fce2b2d2b4
2 changed files with 32 additions and 4 deletions

View file

@ -3950,10 +3950,23 @@ faccessat (int dirfd, const char * path, int mode, int flags)
&& !(IS_DIRECTORY_SEP (path[0])
|| IS_DEVICE_SEP (path[1])))
{
errno = EBADF;
return -1;
char lastc = dir_pathname[strlen (dir_pathname) - 1];
if (strlen (dir_pathname) + strlen (path) + IS_DIRECTORY_SEP (lastc)
>= MAXPATHLEN)
{
errno = ENAMETOOLONG;
return -1;
}
sprintf (fullname, "%s%s%s",
dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", path);
path = fullname;
}
if ((mode & F_OK) != 0 && IS_DIRECTORY_SEP (path[strlen (path) - 1]))
mode |= D_OK;
return access (path, mode);
}

View file

@ -3887,15 +3887,30 @@ int
faccessat (int dirfd, const char * path, int mode, int flags)
{
DWORD attributes;
char fullname[MAX_UTF8_PATH];
/* Rely on a hack: an open directory is modeled as file descriptor 0,
and its actual file name is stored in dir_pathname by opendir.
This is good enough for the current usage in Emacs, but is fragile. */
if (dirfd != AT_FDCWD
&& !(IS_DIRECTORY_SEP (path[0])
|| IS_DEVICE_SEP (path[1])))
{
errno = EBADF;
return -1;
char lastc = dir_pathname[strlen (dir_pathname) - 1];
if (_snprintf (fullname, sizeof fullname, "%s%s%s",
dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", path)
< 0)
{
errno = ENAMETOOLONG;
return -1;
}
path = fullname;
}
if (IS_DIRECTORY_SEP (path[strlen (path) - 1]) && (mode & F_OK) != 0)
mode |= D_OK;
/* MSVCRT implementation of 'access' doesn't recognize D_OK, and its
newer versions blow up when passed D_OK. */
path = map_w32_filename (path, NULL);