OSDN Git Service

* cygtls.cc (_cygtls::remove): Eliminate compiler warning.
authorcgf <cgf>
Fri, 13 May 2005 03:21:37 +0000 (03:21 +0000)
committercgf <cgf>
Fri, 13 May 2005 03:21:37 +0000 (03:21 +0000)
* dir.cc (mkdir): Check path for writability.
(rmdir): Ditto.  Remove check for special directories.
* path.cc (path_conv::check): Set PATH_RO for virtual devices.  Set error if
read-only and asked for writability.
* path.h (pathconv_arg): Add PC_WRITABLE.
(path_types): Add PATH_RO.
(path_conv::isro): Add (currently unused) check for read-only filesystem.
Return "ENOSHARE" when we know a share doesn't exist.
* include/sys/mount.h: Add MOUNT_RO flag.
* autoload.cc (WNetGetResourceInformationA): Import.
* fhandler_netdrive.cc (fhandler_netdrive::exists): Detect actual existence of
remote system rather than always assuming that it exists.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/cygtls.cc
winsup/cygwin/dir.cc
winsup/cygwin/fhandler_netdrive.cc
winsup/cygwin/include/sys/mount.h
winsup/cygwin/path.cc
winsup/cygwin/path.h

index 6419c90..ed9d167 100644 (file)
@@ -1,3 +1,20 @@
+2005-05-12  Christopher Faylor  <cgf@timesys.com>
+
+       * cygtls.cc (_cygtls::remove): Eliminate compiler warning.
+
+       * dir.cc (mkdir): Check path for writability.
+       (rmdir): Ditto.  Remove check for special directories.
+       * path.cc (path_conv::check): Set PATH_RO for virtual devices.  Set
+       error if read-only and asked for writability.
+       * path.h (pathconv_arg): Add PC_WRITABLE.
+       (path_types): Add PATH_RO.
+       (path_conv::isro): Add (currently unused) check for read-only
+       filesystem.  Return "ENOSHARE" when we know a share doesn't exist.
+       * include/sys/mount.h: Add MOUNT_RO flag.
+       * autoload.cc (WNetGetResourceInformationA): Import.
+       * fhandler_netdrive.cc (fhandler_netdrive::exists): Detect actual
+       existence of remote system rather than always assuming that it exists.
+
 2005-05-11  Christopher Faylor  <cgf@timesys.com>
 
        * dcrt0.cc (do_global_dtors): Don't call dll_global_dtors here.
index f264b86..d295940 100644 (file)
@@ -557,6 +557,8 @@ LoadDLLfuncEx (waveInStart, 4, winmm, 1)
 LoadDLLfuncEx (waveInReset, 4, winmm, 1)
 LoadDLLfuncEx (waveInClose, 4, winmm, 1)
 
+LoadDLLfunc (WNetGetResourceInformationA, 16, mpr)
+
 LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
 LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
 }
index 4e09ae9..58e82d2 100644 (file)
@@ -172,7 +172,7 @@ _cygtls::remove (DWORD wait)
       if (locals.exitsock != INVALID_SOCKET)
        {
          closesocket (locals.exitsock);
-         locals.exitsock = NULL;
+         locals.exitsock = (SOCKET) NULL;
        }
       free_local (process_ident);
       free_local (ntoa_buf);
index 5aabcd3..cb49d3a 100644 (file)
@@ -224,7 +224,7 @@ mkdir (const char *dir, mode_t mode)
   SECURITY_ATTRIBUTES sa = sec_none_nih;
   security_descriptor sd;
 
-  path_conv real_dir (dir, PC_SYM_NOFOLLOW);
+  path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_WRITABLE);
 
   if (real_dir.error)
     {
@@ -263,15 +263,11 @@ extern "C" int
 rmdir (const char *dir)
 {
   int res = -1;
-  DWORD devn;
 
-  path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_FULL);
+  path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_FULL | PC_WRITABLE);
 
   if (real_dir.error)
     set_errno (real_dir.error);
-  else if ((devn = real_dir.get_devn ()) == FH_PROC || devn == FH_REGISTRY
-          || devn == FH_PROCESS)
-    set_errno (EROFS);
   else if (!real_dir.exists ())
     set_errno (ENOENT);
   else if  (!real_dir.isdir ())
index 82a4a49..0567a2f 100644 (file)
@@ -8,6 +8,7 @@ This software is a copyrighted work licensed under the terms of the
 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
+#include <windows.h>
 #include "winsup.h"
 #include <unistd.h>
 #include <stdlib.h>
@@ -19,12 +20,31 @@ details. */
 #include "dtable.h"
 #include "cygheap.h"
 #include <assert.h>
+#include <shlwapi.h>
 
 /* Returns 0 if path doesn't exist, >0 if path is a directory,
    -1 if path is a file, -2 if it's a symlink.  */
 int
 fhandler_netdrive::exists ()
 {
+  char *to;
+  const char *from;
+  char namebuf[strlen (get_name ()) + 1];
+  for (to = namebuf, from = get_name (); *from; to++, from++)
+    *to = (*from == '/') ? '\\' : *from;
+  *to = '\0';
+
+  NETRESOURCE nr = {0};
+  nr.dwScope = RESOURCE_GLOBALNET;
+  nr.dwType = RESOURCETYPE_DISK;
+  nr.lpLocalName = NULL;
+  nr.lpRemoteName = namebuf;
+  LPTSTR sys = NULL;
+  char buf[8192];
+  DWORD n = sizeof (buf);
+  DWORD rc = WNetGetResourceInformation (&nr, &buf, &n, &sys);
+  if (rc != ERROR_MORE_DATA && rc != NO_ERROR)
+    return 0;
   return 1;
 }
 
index 5915ddc..d9d138a 100644 (file)
@@ -17,19 +17,20 @@ extern "C" {
 
 enum
 {
-  MOUNT_SYMLINK =      0x001,  /* "mount point" is a symlink */
-  MOUNT_BINARY =       0x002,  /* "binary" format read/writes */
-  MOUNT_SYSTEM =       0x008,  /* mount point came from system table */
-  MOUNT_EXEC   =       0x010,  /* Any file in the mounted directory gets 'x' bit */
-  MOUNT_CYGDRIVE   =   0x020,  /* mount point refers to cygdrive device mount */
-  MOUNT_CYGWIN_EXEC =  0x040,  /* file or directory is or contains a cygwin
+  MOUNT_SYMLINK =      0x0001, /* "mount point" is a symlink */
+  MOUNT_BINARY =       0x0002, /* "binary" format read/writes */
+  MOUNT_SYSTEM =       0x0008, /* mount point came from system table */
+  MOUNT_EXEC   =       0x0010, /* Any file in the mounted directory gets 'x' bit */
+  MOUNT_CYGDRIVE   =   0x0020, /* mount point refers to cygdrive device mount */
+  MOUNT_CYGWIN_EXEC =  0x0040, /* file or directory is or contains a cygwin
                                   executable */
-  MOUNT_MIXED  =       0x080,  /* reads are text, writes are binary
+  MOUNT_MIXED  =       0x0080, /* reads are text, writes are binary
                                   not yet implemented */
-  MOUNT_NOTEXEC =      0x100,  /* don't check files for executable magic */
-  MOUNT_DEVFS =                0x200,  /* /device "filesystem" */
-  MOUNT_PROC =         0x400,  /* /proc "filesystem" */
-  MOUNT_ENC =          0x800   /* encode special characters */
+  MOUNT_NOTEXEC =      0x0100, /* don't check files for executable magic */
+  MOUNT_DEVFS =                0x0200, /* /device "filesystem" */
+  MOUNT_PROC =         0x0400, /* /proc "filesystem" */
+  MOUNT_ENC =          0x0800, /* encode special characters */
+  MOUNT_RO =           0x1000  /* read-only "filesystem" */
 };
 
 int mount (const char *, const char *, unsigned __flags);
index 52a04fc..09382da 100644 (file)
@@ -675,6 +675,7 @@ path_conv::check (const char *src, unsigned opt,
                      fileattr = INVALID_FILE_ATTRIBUTES;
                    goto virtual_component_retry;
                }
+             path_flags |= PATH_RO;
              goto out;
            }
          /* devn should not be a device.  If it is, then stop parsing now. */
@@ -881,15 +882,21 @@ virtual_component_retry:
 out:
   bool strip_tail = false;
   /* If the user wants a directory, do not return a symlink */
-  if (!need_directory || error)
-    /* nothing to do */;
-  else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
-    path_flags &= ~PATH_SYMLINK;
+  if ((opt & PC_WRITABLE) && (path_flags & PATH_RO))
+    {
+      debug_printf ("%s is on a read-only filesystem", path);
+      error = EROFS;
+      return;
+    }
   else if (isvirtual_dev (dev.devn) && fileattr == INVALID_FILE_ATTRIBUTES)
     {
-      error = ENOENT;
+      error = dev.devn == FH_NETDRIVE ? ENOSHARE : ENOENT;
       return;
     }
+  else if (!need_directory || error)
+    /* nothing to do */;
+  else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
+    path_flags &= ~PATH_SYMLINK;
   else
     {
       debug_printf ("%s is a non-directory", path);
index f21c4b9..1c63103 100644 (file)
@@ -39,7 +39,8 @@ enum pathconv_arg
   PC_NULLEMPTY         = 0x0020,
   PC_CHECK_EA          = 0x0040,
   PC_POSIX             = 0x0080,
-  PC_NO_ACCESS_CHECK   = 0x00800000
+  PC_NO_ACCESS_CHECK   = 0x00800000,
+  PC_WRITABLE          = 0x00400000
 };
 
 enum case_checking
@@ -51,7 +52,7 @@ enum case_checking
 
 #define PC_NONULLEMPTY -1
 
-#include <sys/mount.h>
+#include "sys/mount.h"
 
 enum path_types
 {
@@ -62,6 +63,7 @@ enum path_types
   PATH_NOTEXEC         = MOUNT_NOTEXEC,
   PATH_CYGWIN_EXEC     = MOUNT_CYGWIN_EXEC,
   PATH_ENC             = MOUNT_ENC,
+  PATH_RO              = MOUNT_RO,
   PATH_ALL_EXEC                = (PATH_CYGWIN_EXEC | PATH_EXEC),
   PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
   PATH_LNK             = 0x01000000,
@@ -149,6 +151,7 @@ class path_conv
   int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
   int issocket () const {return dev.devn == FH_UNIX;}
   int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
+  bool isro () const {return !!(path_flags & PATH_RO);}
   bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
   bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
   int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}