* devices.in (dev_cygdrive_storage): Revert mapping to \Device\Null.

(dev_storage): Ditto for /dev.
	* devices.cc: Regenerate.
	* fhandler.cc (fhandler_base::open_null): New method to open a fake
	\Device\Null handler.
	(fhandler_base::open): Fix formatting.  Change O_ACCMODE test to a
	switch statement.  Simplify a test which still tested for a now unused
	create_disposition.
	* fhandler.h (fhandler_base::open_null): Declare.
	(fhandler_netdrive::close): Declare.
	* fhandler_dev.cc (fhandler_dev::open): Open fake \Device\Null handle
	by just calling new open_null method.
	* fhandler_disk_file.cc (fhandler_cygdrive::open): Ditto.
	* fhandler_netdrive.cc (fhandler_netdrive::open): Call open_null
	rather than setting nohandle.
	(fhandler_netdrive::close): New method.
	* fhandler_registry.cc (fetch_hkey): Fix token in RegOpenUserClassesRoot
	call.  Create valid key for HKEY_CURRENT_CONFIG by mapping to real key
	HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current.
	(fhandler_registry::open): Set nohandle only when using pseudo registry
	handle.
	* fhandler_virtual.cc (fhandler_virtual::opendir): Call open rather
	than just setting nohandle here.
	* fhandler_virtual::fstatvfs): Set ST_RDONLY fs flag.
	* globals.cc (ro_u_null): New readonly UNICODE_STRING for \Device\Null.
	* path.h (path_conv::set_path): Revert previous change caring for
	wide_path.
This commit is contained in:
Corinna Vinschen 2013-10-31 14:26:42 +00:00
parent a5f316d8cf
commit 5b312b4747
12 changed files with 138 additions and 79 deletions

View File

@ -1,3 +1,33 @@
2013-10-30 Corinna Vinschen <corinna@vinschen.de>
* devices.in (dev_cygdrive_storage): Revert mapping to \Device\Null.
(dev_storage): Ditto for /dev.
* devices.cc: Regenerate.
* fhandler.cc (fhandler_base::open_null): New method to open a fake
\Device\Null handler.
(fhandler_base::open): Fix formatting. Change O_ACCMODE test to a
switch statement. Simplify a test which still tested for a now unused
create_disposition.
* fhandler.h (fhandler_base::open_null): Declare.
(fhandler_netdrive::close): Declare.
* fhandler_dev.cc (fhandler_dev::open): Open fake \Device\Null handle
by just calling new open_null method.
* fhandler_disk_file.cc (fhandler_cygdrive::open): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::open): Call open_null
rather than setting nohandle.
(fhandler_netdrive::close): New method.
* fhandler_registry.cc (fetch_hkey): Fix token in RegOpenUserClassesRoot
call. Create valid key for HKEY_CURRENT_CONFIG by mapping to real key
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current.
(fhandler_registry::open): Set nohandle only when using pseudo registry
handle.
* fhandler_virtual.cc (fhandler_virtual::opendir): Call open rather
than just setting nohandle here.
* fhandler_virtual::fstatvfs): Set ST_RDONLY fs flag.
* globals.cc (ro_u_null): New readonly UNICODE_STRING for \Device\Null.
* path.h (path_conv::set_path): Revert previous change caring for
wide_path.
2013-10-30 Corinna Vinschen <corinna@vinschen.de> 2013-10-30 Corinna Vinschen <corinna@vinschen.de>
* devices.in (dev_cygdrive_storage): Map to \Device\Null. * devices.in (dev_cygdrive_storage): Map to \Device\Null.

View File

@ -91,7 +91,7 @@ exists_pty (const device& dev)
} }
const device dev_cygdrive_storage = const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists}; {"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage = const device dev_fs_storage =
{"", {FH_FS}, "", exists}; {"", {FH_FS}, "", exists};
@ -141,7 +141,7 @@ const device dev_error_storage =
#define BRACK(x) {devn_int: x} #define BRACK(x) {devn_int: x}
const _RDATA device dev_storage[] = const _RDATA device dev_storage[] =
{ {
{"/dev", BRACK(FH_DEV), "\\Device\\Null", exists, S_IFDIR, false}, {"/dev", BRACK(FH_DEV), "", exists, S_IFDIR, false},
{"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\Device\\Null", exists_ntdev, S_IFCHR, true}, {"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/com1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1", exists_ntdev_silent, S_IFCHR, true}, {"/dev/com1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1", exists_ntdev_silent, S_IFCHR, true},
{"/dev/com2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2", exists_ntdev_silent, S_IFCHR, true}, {"/dev/com2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2", exists_ntdev_silent, S_IFCHR, true},

View File

@ -87,7 +87,7 @@ exists_pty (const device& dev)
} }
const device dev_cygdrive_storage = const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists}; {"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage = const device dev_fs_storage =
{"", {FH_FS}, "", exists}; {"", {FH_FS}, "", exists};
@ -140,7 +140,7 @@ const device dev_error_storage =
/* Internal devices below are prefixed with a ":". This moves them out of /* Internal devices below are prefixed with a ":". This moves them out of
the POSIX namespace. */ the POSIX namespace. */
%% %%
"/dev", BRACK(FH_DEV), "\\Device\\Null", exists, S_IFDIR "/dev", BRACK(FH_DEV), "", exists, S_IFDIR
"/dev/tty", BRACK(FH_TTY), "/dev/tty", exists, S_IFCHR "/dev/tty", BRACK(FH_TTY), "/dev/tty", exists, S_IFCHR
"/dev/pty%(0-63)d", BRACK(FHDEV(DEV_PTYS_MAJOR, {$1})), "/dev/pty{$1}", exists_pty, S_IFCHR, =ptys_dev "/dev/pty%(0-63)d", BRACK(FHDEV(DEV_PTYS_MAJOR, {$1})), "/dev/pty{$1}", exists_pty, S_IFCHR, =ptys_dev
":ptym%(0-63)d", BRACK(FHDEV(DEV_PTYM_MAJOR, {$1})), "/dev/ptym{$1}", exists_internal, S_IFCHR, =ptym_dev ":ptym%(0-63)d", BRACK(FHDEV(DEV_PTYM_MAJOR, {$1})), "/dev/ptym{$1}", exists_internal, S_IFCHR, =ptym_dev

View File

@ -507,6 +507,38 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
return res; return res;
} }
/* Open a fake handle to \\Device\\Null. This is a helper function for
fhandlers which just need some handle to keep track of BSD flock locks. */
int
fhandler_base::open_null (int flags)
{
int res = 0;
HANDLE fh;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
NTSTATUS status;
InitializeObjectAttributes (&attr, &ro_u_null, OBJ_CASE_INSENSITIVE |
((flags & O_CLOEXEC) ? 0 : OBJ_INHERIT),
NULL, NULL);
status = NtCreateFile (&fh, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}
set_io_handle (fh);
set_flags (flags, pc.binmode ());
res = 1;
set_open_status ();
done:
debug_printf ("%y = NtCreateFile (%p, ... %S ...)", status, fh, &ro_u_null);
syscall_printf ("%d = fhandler_base::open_null (%y)", res, flags);
return res;
}
/* Open system call handler function. */ /* Open system call handler function. */
int int
fhandler_base::open (int flags, mode_t mode) fhandler_base::open (int flags, mode_t mode)
@ -545,12 +577,18 @@ fhandler_base::open (int flags, mode_t mode)
access = READ_CONTROL | FILE_WRITE_ATTRIBUTES; access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
break; break;
default: default:
if ((flags & O_ACCMODE) == O_RDONLY) switch (flags & O_ACCMODE)
{
case O_RDONLY:
access = GENERIC_READ; access = GENERIC_READ;
else if ((flags & O_ACCMODE) == O_WRONLY) break;
case O_WRONLY:
access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES; access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
else break;
default:
access = GENERIC_READ | GENERIC_WRITE; access = GENERIC_READ | GENERIC_WRITE;
break;
}
if (flags & O_SYNC) if (flags & O_SYNC)
options |= FILE_WRITE_THROUGH; options |= FILE_WRITE_THROUGH;
if (flags & O_DIRECT) if (flags & O_DIRECT)
@ -596,7 +634,7 @@ fhandler_base::open (int flags, mode_t mode)
and/or FILE_ATTRIBUTE_SYSTEM attribute set, NtCreateFile fails with and/or FILE_ATTRIBUTE_SYSTEM attribute set, NtCreateFile fails with
STATUS_ACCESS_DENIED. Per MSDN you have to create the file with the STATUS_ACCESS_DENIED. Per MSDN you have to create the file with the
same attributes as already specified for the file. */ same attributes as already specified for the file. */
if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE) if (create_disposition == FILE_CREATE
&& has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) && has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
file_attributes |= pc.file_attributes (); file_attributes |= pc.file_attributes ();

View File

@ -310,6 +310,7 @@ class fhandler_base
virtual bool need_fixup_before () const {return false;} virtual bool need_fixup_before () const {return false;}
int open_with_arch (int, mode_t = 0); int open_with_arch (int, mode_t = 0);
int open_null (int flags);
virtual int open (int, mode_t); virtual int open (int, mode_t);
virtual void open_setup (int flags); virtual void open_setup (int flags);
void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); } void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); }
@ -1962,6 +1963,7 @@ class fhandler_netdrive: public fhandler_virtual
void rewinddir (DIR *); void rewinddir (DIR *);
int closedir (DIR *); int closedir (DIR *);
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
int close ();
int __reg2 fstat (struct stat *buf); int __reg2 fstat (struct stat *buf);
fhandler_netdrive (void *) {} fhandler_netdrive (void *) {}

View File

@ -16,7 +16,6 @@ details. */
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "devices.h" #include "devices.h"
#include "tls_pbuf.h"
#define _COMPILING_NEWLIB #define _COMPILING_NEWLIB
#include <dirent.h> #include <dirent.h>
@ -54,16 +53,9 @@ fhandler_dev::open (int flags, mode_t mode)
int ret = fhandler_disk_file::open (flags & ~O_CREAT, mode); int ret = fhandler_disk_file::open (flags & ~O_CREAT, mode);
if (!ret) if (!ret)
{ {
/* Open a fake handle to \\Device\\Null */
ret = open_null (flags);
dir_exists = false; dir_exists = false;
/* Open a fake handle to \\Device\\Null, but revert to the old path
string afterwards, otherwise readdir will return with an EFAULT
when trying to fetch the inode number of ".." */
tmp_pathbuf tp;
char *orig_path = tp.c_get ();
stpcpy (orig_path, get_win32_name ());
pc.set_path (dev ().native);
ret = fhandler_base::open (flags, mode);
pc.set_path (orig_path);
} }
return ret; return ret;
} }

View File

@ -2384,16 +2384,8 @@ fhandler_cygdrive::open (int flags, mode_t mode)
set_errno (EISDIR); set_errno (EISDIR);
return 0; return 0;
} }
/* Open a fake handle to \\Device\\Null, but revert to the old path /* Open a fake handle to \\Device\\Null */
string afterwards, otherwise readdir will return with an EFAULT return open_null (flags);
when trying to fetch the inode number of ".." */
tmp_pathbuf tp;
char *orig_path = tp.c_get ();
stpcpy (orig_path, get_win32_name ());
pc.set_path (dev ().native);
int ret = fhandler_base::open (flags, mode);
pc.set_path (orig_path);
return ret;
} }
void void

View File

@ -295,30 +295,23 @@ fhandler_netdrive::closedir (DIR *dir)
int int
fhandler_netdrive::open (int flags, mode_t mode) fhandler_netdrive::open (int flags, mode_t mode)
{ {
int res = fhandler_virtual::open (flags, mode);
if (!res)
goto out;
nohandle (true);
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{ {
set_errno (EEXIST); set_errno (EEXIST);
res = 0; return 0;
goto out;
} }
else if (flags & O_WRONLY) if (flags & O_WRONLY)
{ {
set_errno (EISDIR); set_errno (EISDIR);
res = 0; return 0;
goto out; }
/* Open a fake handle to \\Device\\Null */
return open_null (flags);
} }
res = 1; int
set_flags ((flags & ~O_TEXT) | O_BINARY | O_DIROPEN); fhandler_netdrive::close ()
set_open_status (); {
out: /* Skip fhandler_virtual::close, which is a no-op. */
syscall_printf ("%d = fhandler_netdrive::open(%y, 0%o)", res, flags, mode); return fhandler_base::close ();
return res;
} }

View File

@ -87,7 +87,7 @@ fetch_hkey (int idx) /* idx *must* be valid */
if (registry_keys[idx] == HKEY_CLASSES_ROOT) if (registry_keys[idx] == HKEY_CLASSES_ROOT)
{ {
if (RegOpenUserClassesRoot (cygheap->user.issetuid () if (RegOpenUserClassesRoot (cygheap->user.issetuid ()
? cygheap->user.imp_token () : hProcImpToken, ? cygheap->user.imp_token () : hProcToken,
0, KEY_READ, &key) == ERROR_SUCCESS) 0, KEY_READ, &key) == ERROR_SUCCESS)
return key; return key;
} }
@ -96,6 +96,17 @@ fetch_hkey (int idx) /* idx *must* be valid */
if (RegOpenCurrentUser (KEY_READ, &key) == ERROR_SUCCESS) if (RegOpenCurrentUser (KEY_READ, &key) == ERROR_SUCCESS)
return key; return key;
} }
else if (registry_keys[idx] == HKEY_CURRENT_CONFIG)
{
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Hardware Profiles\\Current",
0, KEY_READ, &key) == ERROR_SUCCESS)
return key;
}
/* Unfortunately there's no way to generate a valid OS registry key for
the other root keys. HKEY_USERS and HKEY_LOCAL_MACHINE are file
handles internally, HKEY_PERFORMANCE_DATA is just a bad hack and
no registry key at all. */
return registry_keys[idx]; return registry_keys[idx];
} }
@ -820,6 +831,7 @@ fhandler_registry::open (int flags, mode_t mode)
set_io_handle (fetch_hkey (i)); set_io_handle (fetch_hkey (i));
/* Marking as nohandle allows to call dup on pseudo registry /* Marking as nohandle allows to call dup on pseudo registry
handles. */ handles. */
if (get_handle () >= HKEY_CLASSES_ROOT)
nohandle (true); nohandle (true);
flags |= O_DIROPEN; flags |= O_DIROPEN;
goto success; goto success;

View File

@ -1,7 +1,7 @@
/* fhandler_virtual.cc: base fhandler class for virtual filesystems /* fhandler_virtual.cc: base fhandler class for virtual filesystems
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
Red Hat, Inc. 2013 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -84,10 +84,9 @@ fhandler_virtual::opendir (int fd)
else else
{ {
cygheap_fdnew cfd; cygheap_fdnew cfd;
if (cfd >= 0) if (cfd >= 0 && open (O_RDONLY, 0))
{ {
cfd = this; cfd = this;
cfd->nohandle (true);
dir->__d_fd = cfd; dir->__d_fd = cfd;
dir->__fh = this; dir->__fh = this;
res = dir; res = dir;
@ -273,6 +272,7 @@ fhandler_virtual::fstatvfs (struct statvfs *sfs)
set to something useful. Just as on Linux. */ set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs)); memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096; sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX; sfs->f_namemax = NAME_MAX;
return 0; return 0;
} }

View File

@ -146,6 +146,7 @@ extern "C" {
extern UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{"); extern UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\"); extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT"); extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
extern UNICODE_STRING _RDATA ro_u_null = _ROU (L"\\Device\\Null");
#undef _ROU #undef _ROU
/* Cygwin properties are meant to be readonly data placed in the DLL, but /* Cygwin properties are meant to be readonly data placed in the DLL, but

View File

@ -380,7 +380,6 @@ class path_conv
cfree (modifiable_path ()); cfree (modifiable_path ());
char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7); char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7);
strcpy (new_path, p); strcpy (new_path, p);
cfree_and_null (wide_path);
return path = new_path; return path = new_path;
} }
bool is_binary (); bool is_binary ();