OSDN Git Service

* path.h (pathconv_arg): Define PC_NO_ACCESS_CHECK.
authorcgf <cgf>
Sat, 12 Mar 2005 02:32:58 +0000 (02:32 +0000)
committercgf <cgf>
Sat, 12 Mar 2005 02:32:58 +0000 (02:32 +0000)
(path_types): Define PATH_NO_ACCESS_CHECK == PC_NO_ACCESS_CHECK.
* path.cc (symlink_info::check_sysfile): Move to symlink_info class and
eliminate arguments that are part of class.  Use set_error.
(symlink_info::check_shortcut): Ditto.
(symlink_info::set_error): New function.
(path_conv::check): Pass PC_NO_ACCESS_CHECK to symlink_info::check.
(symlink_info::check): Preserve PC_NO_ACCESS_CHECK in pflags.  Use set_error.

winsup/cygwin/ChangeLog
winsup/cygwin/path.cc
winsup/cygwin/path.h

index c0ae04f..5916f0b 100644 (file)
@@ -1,3 +1,15 @@
+2005-03-11  Christopher Faylor  <cgf@timesys.com>
+
+       * path.h (pathconv_arg): Define PC_NO_ACCESS_CHECK.
+       (path_types): Define PATH_NO_ACCESS_CHECK == PC_NO_ACCESS_CHECK.
+       * path.cc (symlink_info::check_sysfile): Move to symlink_info class and
+       eliminate arguments that are part of class.  Use set_error.
+       (symlink_info::check_shortcut): Ditto.
+       (symlink_info::set_error): New function.
+       (path_conv::check): Pass PC_NO_ACCESS_CHECK to symlink_info::check.
+       (symlink_info::check): Preserve PC_NO_ACCESS_CHECK in pflags.  Use
+       set_error.
+
 2005-03-10  Corinna Vinschen  <corinna@vinschen.de>
 
        * path.cc (is_floppy): New function.
index 151c8ea..5276796 100644 (file)
@@ -99,6 +99,9 @@ struct symlink_info
   int set (char *path);
   bool parse_device (const char *);
   bool case_check (char *path);
+  int check_sysfile (const char *path, HANDLE h);
+  int check_shortcut (const char *path, HANDLE h);
+  void set_error (int);
 };
 
 int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
@@ -544,6 +547,7 @@ path_conv::check (const char *src, unsigned opt,
     error = 0;
   else if ((error = check_null_empty_str (src)))
     return;
+  unsigned pflags_or = (opt & PC_NO_ACCESS_CHECK);
   /* This loop handles symlink expansion.  */
   for (;;)
     {
@@ -603,6 +607,8 @@ path_conv::check (const char *src, unsigned opt,
          if (error)
            return;
 
+         sym.pflags |= pflags_or;
+
          if (dev.major == DEV_CYGDRIVE_MAJOR)
            {
              if (!component)
@@ -767,7 +773,7 @@ is_virtual_symlink:
                  else
                    break;
                }
-             else if (sym.error != ENOENT && sym.error != ENOSHARE) /* E. g. EACCES */
+             else if (sym.error != ENOENT && sym.error != ENOSHARE)
                {
                  error = sym.error;
                  goto out;
@@ -2776,9 +2782,8 @@ cmp_shortcut_header (win_shortcut_hdr *file_header)
       && file_header->run == SW_NORMAL;
 }
 
-static int
-check_shortcut (const char *path, DWORD fileattr, HANDLE h,
-               char *contents, int *error, unsigned *pflags)
+int
+symlink_info::check_shortcut (const char *path, HANDLE h)
 {
   win_shortcut_hdr *file_header;
   char *buf, *cp;
@@ -2795,7 +2800,7 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h,
   buf = (char *) alloca (size);
   if (!ReadFile (h, buf, size, &got, 0))
     {
-      *error = EIO;
+      set_error (EIO);
       goto close_it;
     }
   file_header = (win_shortcut_hdr *) buf;
@@ -2810,13 +2815,13 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h,
   contents[len] = '\0';
   res = len;
   if (res) /* It's a symlink.  */
-    *pflags = PATH_SYMLINK | PATH_LNK;
+    pflags = PATH_SYMLINK | PATH_LNK;
   goto close_it;
 
 file_not_symlink:
   /* Not a symlink, see if executable.  */
-  if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars ((const char *) &file_header, got))
-    *pflags |= PATH_EXEC;
+  if (!(pflags & PATH_ALL_EXEC) && has_exec_chars ((const char *) &file_header, got))
+    pflags |= PATH_EXEC;
 
 close_it:
   CloseHandle (h);
@@ -2824,9 +2829,8 @@ close_it:
 }
 
 
-static int
-check_sysfile (const char *path, DWORD fileattr, HANDLE h,
-              char *contents, int *error, unsigned *pflags)
+int
+symlink_info::check_sysfile (const char *path, HANDLE h)
 {
   char cookie_buf[sizeof (SYMLINK_COOKIE) - 1];
   DWORD got;
@@ -2835,19 +2839,19 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
   if (!ReadFile (h, cookie_buf, sizeof (cookie_buf), &got, 0))
     {
       debug_printf ("ReadFile1 failed");
-      *error = EIO;
+      set_error (EIO);
     }
   else if (got == sizeof (cookie_buf)
           && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0)
     {
       /* It's a symlink.  */
-      *pflags = PATH_SYMLINK;
+      pflags = PATH_SYMLINK;
 
       res = ReadFile (h, contents, CYG_MAX_PATH + 1, &got, 0);
       if (!res)
        {
          debug_printf ("ReadFile2 failed");
-         *error = EIO;
+         set_error (EIO);
        }
       else
        {
@@ -2866,19 +2870,19 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
     }
   else if (got == sizeof (cookie_buf)
           && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0)
-    *pflags |= PATH_SOCKET;
+    pflags |= PATH_SOCKET;
   else
     {
       /* Not a symlink, see if executable.  */
-      if (*pflags & PATH_ALL_EXEC)
+      if (pflags & PATH_ALL_EXEC)
        /* Nothing to do */;
       else if (has_exec_chars (cookie_buf, got))
-       *pflags |= PATH_EXEC;
+       pflags |= PATH_EXEC;
       else
-       *pflags |= PATH_NOTEXEC;
+       pflags |= PATH_NOTEXEC;
       }
   syscall_printf ("%d = symlink.check_sysfile (%s, %s) (%p)",
-                 res, path, contents, *pflags);
+                 res, path, contents, pflags);
 
   CloseHandle (h);
   return res;
@@ -3001,6 +3005,14 @@ suffix_scan::next ()
     }
 }
 
+void
+symlink_info::set_error (int in_errno)
+{
+  if ((pflags & PATH_NO_ACCESS_CHECK) && in_errno != ENAMETOOLONG)
+    return;
+  error = in_errno;
+}
+
 bool
 symlink_info::parse_device (const char *contents)
 {
@@ -3075,6 +3087,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
   minor = 0;
 
   pflags &= ~(PATH_SYMLINK | PATH_LNK);
+  unsigned pflags_or = pflags & PATH_NO_ACCESS_CHECK;
 
   case_clash = false;
 
@@ -3088,7 +3101,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
             matter, so we just return 0.  For example, getting the
             attributes of \\HOST will typically fail.  */
          debug_printf ("GetFileAttributes (%s) failed", suffix.path);
-         error = geterrno_from_win_error (GetLastError (), EACCES);
+         set_error (geterrno_from_win_error (GetLastError (), EACCES));
          continue;
        }
 
@@ -3122,7 +3135,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
       if (sym_check > 0 && opt & PC_CHECK_EA &&
          (res = get_symlink_ea (suffix.path, contents, sizeof (contents))) > 0)
        {
-         pflags = PATH_SYMLINK;
+         pflags = PATH_SYMLINK | pflags_or;
          if (sym_check == 1)
            pflags |= PATH_LNK;
          debug_printf ("Got symlink from EA: %s", contents);
@@ -3142,7 +3155,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
       switch (sym_check)
        {
        case 1:
-         res = check_shortcut (suffix.path, fileattr, h, contents, &error, &pflags);
+         res = check_shortcut (suffix.path, h);
          if (!res)
            /* check more below */;
          else if (contents[0] == ':' && contents[1] == '\\' && parse_device (contents))
@@ -3157,7 +3170,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
          fileattr = INVALID_FILE_ATTRIBUTES;
          continue;             /* in case we're going to tack *another* .lnk on this filename. */
        case 2:
-         res = check_sysfile (suffix.path, fileattr, h, contents, &error, &pflags);
+         res = check_sysfile (suffix.path, h);
          if (!res)
            goto file_not_symlink;
          break;
@@ -3453,7 +3466,7 @@ fchdir (int fd)
 extern "C" int
 cygwin_conv_to_win32_path (const char *path, char *win32_path)
 {
-  path_conv p (path, PC_SYM_FOLLOW);
+  path_conv p (path, PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK);
   if (p.error)
     {
       win32_path[0] = '\0';
@@ -3468,7 +3481,7 @@ cygwin_conv_to_win32_path (const char *path, char *win32_path)
 extern "C" int
 cygwin_conv_to_full_win32_path (const char *path, char *win32_path)
 {
-  path_conv p (path, PC_SYM_FOLLOW | PC_FULL);
+  path_conv p (path, PC_SYM_FOLLOW | PC_FULL | PC_NO_ACCESS_CHECK);
   if (p.error)
     {
       win32_path[0] = '\0';
index 171f510..e0a565f 100644 (file)
@@ -38,7 +38,8 @@ enum pathconv_arg
   PC_FULL              = 0x0010,
   PC_NULLEMPTY         = 0x0020,
   PC_CHECK_EA          = 0x0040,
-  PC_POSIX             = 0x0080
+  PC_POSIX             = 0x0080,
+  PC_NO_ACCESS_CHECK   = 0x00800000
 };
 
 enum case_checking
@@ -54,18 +55,19 @@ enum case_checking
 
 enum path_types
 {
-  PATH_NOTHING = 0,
-  PATH_SYMLINK = MOUNT_SYMLINK,
-  PATH_BINARY = MOUNT_BINARY,
-  PATH_EXEC = MOUNT_EXEC,
-  PATH_NOTEXEC = MOUNT_NOTEXEC,
-  PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
-  PATH_ENC = MOUNT_ENC,
-  PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
-  PATH_LNK =         0x01000000,
-  PATH_TEXT =        0x02000000,
-  PATH_HAS_SYMLINKS = 0x10000000,
-  PATH_SOCKET =       0x40000000
+  PATH_NOTHING         = 0,
+  PATH_SYMLINK         = MOUNT_SYMLINK,
+  PATH_BINARY          = MOUNT_BINARY,
+  PATH_EXEC            = MOUNT_EXEC,
+  PATH_NOTEXEC         = MOUNT_NOTEXEC,
+  PATH_CYGWIN_EXEC     = MOUNT_CYGWIN_EXEC,
+  PATH_ENC             = MOUNT_ENC,
+  PATH_ALL_EXEC                = (PATH_CYGWIN_EXEC | PATH_EXEC),
+  PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
+  PATH_LNK             = 0x01000000,
+  PATH_TEXT            = 0x02000000,
+  PATH_HAS_SYMLINKS    = 0x10000000,
+  PATH_SOCKET          = 0x40000000
 };
 
 class symlink_info;