aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/autoload.cc2
-rw-r--r--winsup/cygwin/cygtls.cc2
-rw-r--r--winsup/cygwin/dir.cc8
-rw-r--r--winsup/cygwin/fhandler_netdrive.cc20
-rw-r--r--winsup/cygwin/include/sys/mount.h23
-rw-r--r--winsup/cygwin/path.cc17
-rw-r--r--winsup/cygwin/path.h7
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);}