diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 17 | ||||
-rw-r--r-- | winsup/cygwin/autoload.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/dir.cc | 8 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_netdrive.cc | 20 | ||||
-rw-r--r-- | winsup/cygwin/include/sys/mount.h | 23 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 17 | ||||
-rw-r--r-- | winsup/cygwin/path.h | 7 |
8 files changed, 71 insertions, 25 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6419c90..ed9d167 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index f264b86..d295940 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -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) } diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 4e09ae9..58e82d2 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -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); diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 5aabcd3..cb49d3a 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -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 ()) diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc index 82a4a49..0567a2f 100644 --- a/winsup/cygwin/fhandler_netdrive.cc +++ b/winsup/cygwin/fhandler_netdrive.cc @@ -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; } diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h index 5915ddc..d9d138a 100644 --- a/winsup/cygwin/include/sys/mount.h +++ b/winsup/cygwin/include/sys/mount.h @@ -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); diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 52a04fc..09382da 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -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); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index f21c4b9..1c63103 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -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);} |