emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master fce2b2d: Fix completion on directory names on MS-DO


From: Eli Zaretskii
Subject: [Emacs-diffs] master fce2b2d: Fix completion on directory names on MS-DOS/MS-Windows
Date: Sat, 12 Aug 2017 07:45:27 -0400 (EDT)

branch: master
commit fce2b2d2b40a1c0505d1ad623baef76f726c436a
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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.
---
 src/msdos.c | 17 +++++++++++++++--
 src/w32.c   | 19 +++++++++++++++++--
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/msdos.c b/src/msdos.c
index 87b6f84..5b02575 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -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);
 }
 
diff --git a/src/w32.c b/src/w32.c
index bdeaed0..c5b51bb 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]