Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-10-31 18:26:42 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-10-31 18:26:42 +0400
commit5b312b4747cc4acda39c187369c02fcea456513b (patch)
tree56d9e0bec1c4b808933153d0a38903805bb0cc88
parenta5f316d8cfbd9f2abf018e3fe766a88820492ac1 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog30
-rw-r--r--winsup/cygwin/devices.cc4
-rw-r--r--winsup/cygwin/devices.in4
-rw-r--r--winsup/cygwin/fhandler.cc98
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fhandler_dev.cc12
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc12
-rw-r--r--winsup/cygwin/fhandler_netdrive.cc29
-rw-r--r--winsup/cygwin/fhandler_registry.cc16
-rw-r--r--winsup/cygwin/fhandler_virtual.cc8
-rw-r--r--winsup/cygwin/globals.cc1
-rw-r--r--winsup/cygwin/path.h1
12 files changed, 138 insertions, 79 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7ea534b23..e1c6fb7cb 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,35 @@
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>
+
* devices.in (dev_cygdrive_storage): Map to \Device\Null.
(dev_storage): Map /dev and /dev/windows to \Device\Null.
* devices.cc: Regenerate.
diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc
index cd49d4959..8aba6d840 100644
--- a/winsup/cygwin/devices.cc
+++ b/winsup/cygwin/devices.cc
@@ -91,7 +91,7 @@ exists_pty (const device& dev)
}
const device dev_cygdrive_storage =
- {"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
+ {"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
@@ -141,7 +141,7 @@ const device dev_error_storage =
#define BRACK(x) {devn_int: x}
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/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},
diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in
index 520191eb7..c43f11c0f 100644
--- a/winsup/cygwin/devices.in
+++ b/winsup/cygwin/devices.in
@@ -87,7 +87,7 @@ exists_pty (const device& dev)
}
const device dev_cygdrive_storage =
- {"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
+ {"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
@@ -140,7 +140,7 @@ const device dev_error_storage =
/* Internal devices below are prefixed with a ":". This moves them out of
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/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
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 39dcbd057..c64fc33b1 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -507,6 +507,38 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
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. */
int
fhandler_base::open (int flags, mode_t mode)
@@ -529,38 +561,44 @@ fhandler_base::open (int flags, mode_t mode)
options = FILE_OPEN_FOR_BACKUP_INTENT;
switch (query_open ())
{
- case query_read_control:
- access = READ_CONTROL;
- break;
- case query_read_attributes:
- access = READ_CONTROL | FILE_READ_ATTRIBUTES;
- break;
- case query_write_control:
- access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
- break;
- case query_write_dac:
- access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
- break;
- case query_write_attributes:
- access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
- break;
- default:
- if ((flags & O_ACCMODE) == O_RDONLY)
+ case query_read_control:
+ access = READ_CONTROL;
+ break;
+ case query_read_attributes:
+ access = READ_CONTROL | FILE_READ_ATTRIBUTES;
+ break;
+ case query_write_control:
+ access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
+ break;
+ case query_write_dac:
+ access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
+ break;
+ case query_write_attributes:
+ access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
+ break;
+ default:
+ switch (flags & O_ACCMODE)
+ {
+ case O_RDONLY:
access = GENERIC_READ;
- else if ((flags & O_ACCMODE) == O_WRONLY)
+ break;
+ case O_WRONLY:
access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
- else
+ break;
+ default:
access = GENERIC_READ | GENERIC_WRITE;
- if (flags & O_SYNC)
- options |= FILE_WRITE_THROUGH;
- if (flags & O_DIRECT)
- options |= FILE_NO_INTERMEDIATE_BUFFERING;
- if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
- {
- options |= FILE_SYNCHRONOUS_IO_NONALERT;
- access |= SYNCHRONIZE;
- }
- break;
+ break;
+ }
+ if (flags & O_SYNC)
+ options |= FILE_WRITE_THROUGH;
+ if (flags & O_DIRECT)
+ options |= FILE_NO_INTERMEDIATE_BUFFERING;
+ if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
+ {
+ options |= FILE_SYNCHRONOUS_IO_NONALERT;
+ access |= SYNCHRONIZE;
+ }
+ break;
}
/* Don't use the FILE_OVERWRITE{_IF} flags here. See below for an
@@ -596,7 +634,7 @@ fhandler_base::open (int flags, mode_t mode)
and/or FILE_ATTRIBUTE_SYSTEM attribute set, NtCreateFile fails with
STATUS_ACCESS_DENIED. Per MSDN you have to create the file with the
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))
file_attributes |= pc.file_attributes ();
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index d2f9758d8..d63e7448f 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -310,6 +310,7 @@ class fhandler_base
virtual bool need_fixup_before () const {return false;}
int open_with_arch (int, mode_t = 0);
+ int open_null (int flags);
virtual int open (int, mode_t);
virtual void open_setup (int flags);
void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); }
@@ -1962,6 +1963,7 @@ class fhandler_netdrive: public fhandler_virtual
void rewinddir (DIR *);
int closedir (DIR *);
int open (int flags, mode_t mode = 0);
+ int close ();
int __reg2 fstat (struct stat *buf);
fhandler_netdrive (void *) {}
diff --git a/winsup/cygwin/fhandler_dev.cc b/winsup/cygwin/fhandler_dev.cc
index 668d0b480..4f92a1db8 100644
--- a/winsup/cygwin/fhandler_dev.cc
+++ b/winsup/cygwin/fhandler_dev.cc
@@ -16,7 +16,6 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "devices.h"
-#include "tls_pbuf.h"
#define _COMPILING_NEWLIB
#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);
if (!ret)
{
+ /* Open a fake handle to \\Device\\Null */
+ ret = open_null (flags);
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;
}
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 9ee487dc1..ebdc806e2 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -2384,16 +2384,8 @@ fhandler_cygdrive::open (int flags, mode_t mode)
set_errno (EISDIR);
return 0;
}
- /* 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);
- int ret = fhandler_base::open (flags, mode);
- pc.set_path (orig_path);
- return ret;
+ /* Open a fake handle to \\Device\\Null */
+ return open_null (flags);
}
void
diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc
index af9abcada..909e02354 100644
--- a/winsup/cygwin/fhandler_netdrive.cc
+++ b/winsup/cygwin/fhandler_netdrive.cc
@@ -295,30 +295,23 @@ fhandler_netdrive::closedir (DIR *dir)
int
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))
{
set_errno (EEXIST);
- res = 0;
- goto out;
+ return 0;
}
- else if (flags & O_WRONLY)
+ if (flags & O_WRONLY)
{
set_errno (EISDIR);
- res = 0;
- goto out;
+ return 0;
}
-
- res = 1;
- set_flags ((flags & ~O_TEXT) | O_BINARY | O_DIROPEN);
- set_open_status ();
-out:
- syscall_printf ("%d = fhandler_netdrive::open(%y, 0%o)", res, flags, mode);
- return res;
+ /* Open a fake handle to \\Device\\Null */
+ return open_null (flags);
}
+int
+fhandler_netdrive::close ()
+{
+ /* Skip fhandler_virtual::close, which is a no-op. */
+ return fhandler_base::close ();
+}
diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc
index 10370550a..d4b6706c7 100644
--- a/winsup/cygwin/fhandler_registry.cc
+++ b/winsup/cygwin/fhandler_registry.cc
@@ -87,7 +87,7 @@ fetch_hkey (int idx) /* idx *must* be valid */
if (registry_keys[idx] == HKEY_CLASSES_ROOT)
{
if (RegOpenUserClassesRoot (cygheap->user.issetuid ()
- ? cygheap->user.imp_token () : hProcImpToken,
+ ? cygheap->user.imp_token () : hProcToken,
0, KEY_READ, &key) == ERROR_SUCCESS)
return key;
}
@@ -96,6 +96,17 @@ fetch_hkey (int idx) /* idx *must* be valid */
if (RegOpenCurrentUser (KEY_READ, &key) == ERROR_SUCCESS)
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];
}
@@ -820,7 +831,8 @@ fhandler_registry::open (int flags, mode_t mode)
set_io_handle (fetch_hkey (i));
/* Marking as nohandle allows to call dup on pseudo registry
handles. */
- nohandle (true);
+ if (get_handle () >= HKEY_CLASSES_ROOT)
+ nohandle (true);
flags |= O_DIROPEN;
goto success;
}
diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc
index 07b8e4b0b..2d56d7413 100644
--- a/winsup/cygwin/fhandler_virtual.cc
+++ b/winsup/cygwin/fhandler_virtual.cc
@@ -1,7 +1,7 @@
/* fhandler_virtual.cc: base fhandler class for virtual filesystems
- Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Red Hat, Inc.
+ Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
+ 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -84,10 +84,9 @@ fhandler_virtual::opendir (int fd)
else
{
cygheap_fdnew cfd;
- if (cfd >= 0)
+ if (cfd >= 0 && open (O_RDONLY, 0))
{
cfd = this;
- cfd->nohandle (true);
dir->__d_fd = cfd;
dir->__fh = this;
res = dir;
@@ -273,6 +272,7 @@ fhandler_virtual::fstatvfs (struct statvfs *sfs)
set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
+ sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX;
return 0;
}
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index fa32749ba..531703a7a 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -146,6 +146,7 @@ extern "C" {
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_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
+ extern UNICODE_STRING _RDATA ro_u_null = _ROU (L"\\Device\\Null");
#undef _ROU
/* Cygwin properties are meant to be readonly data placed in the DLL, but
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 5c329e33f..d6c386075 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -380,7 +380,6 @@ class path_conv
cfree (modifiable_path ());
char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7);
strcpy (new_path, p);
- cfree_and_null (wide_path);
return path = new_path;
}
bool is_binary ();