* 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.
This commit is contained in:
Christopher Faylor 2005-05-13 03:21:39 +00:00
parent cf55bf5ee8
commit 66582dd6e7
8 changed files with 72 additions and 26 deletions

View 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> 2005-05-11 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (do_global_dtors): Don't call dll_global_dtors here. * dcrt0.cc (do_global_dtors): Don't call dll_global_dtors here.

View File

@ -557,6 +557,8 @@ LoadDLLfuncEx (waveInStart, 4, winmm, 1)
LoadDLLfuncEx (waveInReset, 4, winmm, 1) LoadDLLfuncEx (waveInReset, 4, winmm, 1)
LoadDLLfuncEx (waveInClose, 4, winmm, 1) LoadDLLfuncEx (waveInClose, 4, winmm, 1)
LoadDLLfunc (WNetGetResourceInformationA, 16, mpr)
LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1) LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1) LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
} }

View File

@ -172,7 +172,7 @@ _cygtls::remove (DWORD wait)
if (locals.exitsock != INVALID_SOCKET) if (locals.exitsock != INVALID_SOCKET)
{ {
closesocket (locals.exitsock); closesocket (locals.exitsock);
locals.exitsock = NULL; locals.exitsock = (SOCKET) NULL;
} }
free_local (process_ident); free_local (process_ident);
free_local (ntoa_buf); free_local (ntoa_buf);

View File

@ -224,7 +224,7 @@ mkdir (const char *dir, mode_t mode)
SECURITY_ATTRIBUTES sa = sec_none_nih; SECURITY_ATTRIBUTES sa = sec_none_nih;
security_descriptor sd; 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) if (real_dir.error)
{ {
@ -263,15 +263,11 @@ extern "C" int
rmdir (const char *dir) rmdir (const char *dir)
{ {
int res = -1; 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) if (real_dir.error)
set_errno (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 ()) else if (!real_dir.exists ())
set_errno (ENOENT); set_errno (ENOENT);
else if (!real_dir.isdir ()) else if (!real_dir.isdir ())

View 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 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#include <windows.h>
#include "winsup.h" #include "winsup.h"
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
@ -19,12 +20,31 @@ details. */
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include <assert.h> #include <assert.h>
#include <shlwapi.h>
/* Returns 0 if path doesn't exist, >0 if path is a directory, /* 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. */ -1 if path is a file, -2 if it's a symlink. */
int int
fhandler_netdrive::exists () 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; return 1;
} }

View File

@ -17,19 +17,20 @@ extern "C" {
enum enum
{ {
MOUNT_SYMLINK = 0x001, /* "mount point" is a symlink */ MOUNT_SYMLINK = 0x0001, /* "mount point" is a symlink */
MOUNT_BINARY = 0x002, /* "binary" format read/writes */ MOUNT_BINARY = 0x0002, /* "binary" format read/writes */
MOUNT_SYSTEM = 0x008, /* mount point came from system table */ MOUNT_SYSTEM = 0x0008, /* mount point came from system table */
MOUNT_EXEC = 0x010, /* Any file in the mounted directory gets 'x' bit */ MOUNT_EXEC = 0x0010, /* Any file in the mounted directory gets 'x' bit */
MOUNT_CYGDRIVE = 0x020, /* mount point refers to cygdrive device mount */ MOUNT_CYGDRIVE = 0x0020, /* mount point refers to cygdrive device mount */
MOUNT_CYGWIN_EXEC = 0x040, /* file or directory is or contains a cygwin MOUNT_CYGWIN_EXEC = 0x0040, /* file or directory is or contains a cygwin
executable */ executable */
MOUNT_MIXED = 0x080, /* reads are text, writes are binary MOUNT_MIXED = 0x0080, /* reads are text, writes are binary
not yet implemented */ not yet implemented */
MOUNT_NOTEXEC = 0x100, /* don't check files for executable magic */ MOUNT_NOTEXEC = 0x0100, /* don't check files for executable magic */
MOUNT_DEVFS = 0x200, /* /device "filesystem" */ MOUNT_DEVFS = 0x0200, /* /device "filesystem" */
MOUNT_PROC = 0x400, /* /proc "filesystem" */ MOUNT_PROC = 0x0400, /* /proc "filesystem" */
MOUNT_ENC = 0x800 /* encode special characters */ MOUNT_ENC = 0x0800, /* encode special characters */
MOUNT_RO = 0x1000 /* read-only "filesystem" */
}; };
int mount (const char *, const char *, unsigned __flags); int mount (const char *, const char *, unsigned __flags);

View File

@ -675,6 +675,7 @@ path_conv::check (const char *src, unsigned opt,
fileattr = INVALID_FILE_ATTRIBUTES; fileattr = INVALID_FILE_ATTRIBUTES;
goto virtual_component_retry; goto virtual_component_retry;
} }
path_flags |= PATH_RO;
goto out; goto out;
} }
/* devn should not be a device. If it is, then stop parsing now. */ /* devn should not be a device. If it is, then stop parsing now. */
@ -881,15 +882,21 @@ virtual_component_retry:
out: out:
bool strip_tail = false; bool strip_tail = false;
/* If the user wants a directory, do not return a symlink */ /* If the user wants a directory, do not return a symlink */
if (!need_directory || error) 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 = dev.devn == FH_NETDRIVE ? ENOSHARE : ENOENT;
return;
}
else if (!need_directory || error)
/* nothing to do */; /* nothing to do */;
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY) else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
path_flags &= ~PATH_SYMLINK; path_flags &= ~PATH_SYMLINK;
else if (isvirtual_dev (dev.devn) && fileattr == INVALID_FILE_ATTRIBUTES)
{
error = ENOENT;
return;
}
else else
{ {
debug_printf ("%s is a non-directory", path); debug_printf ("%s is a non-directory", path);

View File

@ -39,7 +39,8 @@ enum pathconv_arg
PC_NULLEMPTY = 0x0020, PC_NULLEMPTY = 0x0020,
PC_CHECK_EA = 0x0040, PC_CHECK_EA = 0x0040,
PC_POSIX = 0x0080, PC_POSIX = 0x0080,
PC_NO_ACCESS_CHECK = 0x00800000 PC_NO_ACCESS_CHECK = 0x00800000,
PC_WRITABLE = 0x00400000
}; };
enum case_checking enum case_checking
@ -51,7 +52,7 @@ enum case_checking
#define PC_NONULLEMPTY -1 #define PC_NONULLEMPTY -1
#include <sys/mount.h> #include "sys/mount.h"
enum path_types enum path_types
{ {
@ -62,6 +63,7 @@ enum path_types
PATH_NOTEXEC = MOUNT_NOTEXEC, PATH_NOTEXEC = MOUNT_NOTEXEC,
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC, PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
PATH_ENC = MOUNT_ENC, PATH_ENC = MOUNT_ENC,
PATH_RO = MOUNT_RO,
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK, PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
PATH_LNK = 0x01000000, PATH_LNK = 0x01000000,
@ -149,6 +151,7 @@ class path_conv
int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();} int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
int issocket () const {return dev.devn == FH_UNIX;} int issocket () const {return dev.devn == FH_UNIX;}
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;} 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 exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);} bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);} int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}