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

(dev_storage): Map /dev and /dev/windows to \Device\Null.
	* devices.cc: Regenerate.
	* dir.cc (opendir): Create unique id.  Explain why.
	* fhandler.h (fhandler_dev::get_dev): Implement inline.
	(fhandler_cygdrive::close): Drop declaration.
	(fhandler_cygdrive::get_dev): Implement inline.
	(fhandler_windows::get_hwnd): Ditto.
	(fhandler_windows::set_close_on_exec): Drop declaration.
	(fhandler_windows::fixup_after_fork): Ditto.
	* fhandler_dev.cc (fhandler_dev::open): Call fhandler_disk_file::open
	without O_CREAT flag.  Explain why.  Create \Device\Null handle if
	/dev/ doesn't actually exist.
	(fhandler_dev::close): Drop nohandle case.
	(fhandler_dev::fstatvfs): Drop nohandle check.  Test for fs_got_fs
	instead.  Set ST_RDONLY fs flag for simulated /dev.
	(fhandler_dev::opendir): If /dev doesn't exist, call open() to create
	fake \Device\Null handle.  Don't set nohandle.  Set dir_exists
	correctly.
	(fhandler_dev::rewinddir): Call fhandler_disk_file::rewinddir only if
	/dev is a real directory.
	* fhandler_disk_file.cc (fhandler_disk_file::opendir): If called for
	the cygdrive dir, call open() to create fake \Device\Null handle.
	Only attach __DIR_mounts buffer to dir if not called for cygdrive dir.
	Don't set nohandle.
	(fhandler_cygdrive::open): Create \Device\Null handle.
	(fhandler_cygdrive::close): Remove.
	(fhandler_cygdrive::fstatvfs): Set ST_RDONLY fs flag.
	* fhandler_windows.cc (fhandler_windows::open): Create \Device\Null
	handle.
	(fhandler_windows::read): Don't add io_handle to WFMO handle array.
	Change subsequent test for return value accordingly.  Fix test for
	"message arrived".
	(fhandler_windows::set_close_on_exec): Remove.
	(fhandler_windows::fixup_after_fork): Remove.
	* path.h (path_conv::set_path): Make sure wide_path is NULL when
	setting a new path.
	* select.cc (peek_windows): Use correct hWnd value, not io_handle.
	(fhandler_windows::select_read): Don't use io_handle as wait object.
	(fhandler_windows::select_write): Ditto.
	(fhandler_windows::select_except): Ditto.
This commit is contained in:
Corinna Vinschen 2013-10-30 09:44:47 +00:00
parent 0160e166ee
commit 751bbaf96a
10 changed files with 141 additions and 102 deletions

View File

@ -1,3 +1,47 @@
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.
* dir.cc (opendir): Create unique id. Explain why.
* fhandler.h (fhandler_dev::get_dev): Implement inline.
(fhandler_cygdrive::close): Drop declaration.
(fhandler_cygdrive::get_dev): Implement inline.
(fhandler_windows::get_hwnd): Ditto.
(fhandler_windows::set_close_on_exec): Drop declaration.
(fhandler_windows::fixup_after_fork): Ditto.
* fhandler_dev.cc (fhandler_dev::open): Call fhandler_disk_file::open
without O_CREAT flag. Explain why. Create \Device\Null handle if
/dev/ doesn't actually exist.
(fhandler_dev::close): Drop nohandle case.
(fhandler_dev::fstatvfs): Drop nohandle check. Test for fs_got_fs
instead. Set ST_RDONLY fs flag for simulated /dev.
(fhandler_dev::opendir): If /dev doesn't exist, call open() to create
fake \Device\Null handle. Don't set nohandle. Set dir_exists
correctly.
(fhandler_dev::rewinddir): Call fhandler_disk_file::rewinddir only if
/dev is a real directory.
* fhandler_disk_file.cc (fhandler_disk_file::opendir): If called for
the cygdrive dir, call open() to create fake \Device\Null handle.
Only attach __DIR_mounts buffer to dir if not called for cygdrive dir.
Don't set nohandle.
(fhandler_cygdrive::open): Create \Device\Null handle.
(fhandler_cygdrive::close): Remove.
(fhandler_cygdrive::fstatvfs): Set ST_RDONLY fs flag.
* fhandler_windows.cc (fhandler_windows::open): Create \Device\Null
handle.
(fhandler_windows::read): Don't add io_handle to WFMO handle array.
Change subsequent test for return value accordingly. Fix test for
"message arrived".
(fhandler_windows::set_close_on_exec): Remove.
(fhandler_windows::fixup_after_fork): Remove.
* path.h (path_conv::set_path): Make sure wide_path is NULL when
setting a new path.
* select.cc (peek_windows): Use correct hWnd value, not io_handle.
(fhandler_windows::select_read): Don't use io_handle as wait object.
(fhandler_windows::select_write): Ditto.
(fhandler_windows::select_except): Ditto.
2013-10-27 Corinna Vinschen <corinna@vinschen.de>
* exception.h: Fold in content of include/exceptions.h.

View File

@ -91,7 +91,7 @@ exists_pty (const device& dev)
}
const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "/cygdrive", exists};
{"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", 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), "/dev", exists, S_IFDIR, false},
{"/dev", BRACK(FH_DEV), "\\Device\\Null", 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},
@ -2714,7 +2714,7 @@ const _RDATA device dev_storage[] =
{"/dev/ttyS62", BRACK(FHDEV(DEV_SERIAL_MAJOR, 62)), "\\??\\COM63", exists_ntdev, S_IFCHR, true},
{"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64", exists_ntdev, S_IFCHR, true},
{"/dev/urandom", BRACK(FH_URANDOM), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows", exists, S_IFCHR, true},
{"/dev/windows", BRACK(FH_WINDOWS), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/zero", BRACK(FH_ZERO), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{":fifo", BRACK(FH_FIFO), "/dev/fifo", exists_internal, S_IFCHR, false},
{":pipe", BRACK(FH_PIPE), "/dev/pipe", exists_internal, S_IFCHR, false},

View File

@ -87,7 +87,7 @@ exists_pty (const device& dev)
}
const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "/cygdrive", exists};
{"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
@ -140,14 +140,14 @@ const device dev_error_storage =
/* Internal devices below are prefixed with a ":". This moves them out of
the POSIX namespace. */
%%
"/dev", BRACK(FH_DEV), "/dev", exists, S_IFDIR
"/dev", BRACK(FH_DEV), "\\Device\\Null", 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
"/dev/cons%(0-63)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", exists_console, S_IFCHR, =cons_dev
"/dev/console", BRACK(FH_CONSOLE), "/dev/console", exists_console, S_IFCHR, =console_dev
"/dev/ptmx", BRACK(FH_PTMX), "/dev/ptmx", exists, S_IFCHR
"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows", exists, S_IFCHR
"/dev/windows", BRACK(FH_WINDOWS), "\\Device\\Null", exists_ntdev, S_IFCHR
"/dev/dsp", BRACK(FH_OSS_DSP), "\\Device\\Null", exists_ntdev, S_IFCHR
"/dev/conin", BRACK(FH_CONIN), "/dev/conin", exists_console, S_IFCHR
"/dev/conout", BRACK(FH_CONOUT), "/dev/conout", exists_console, S_IFCHR

View File

@ -1,7 +1,7 @@
/* dir.cc: Posix directory-related routines
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -68,6 +68,9 @@ opendir (const char *name)
if (!res && fh)
delete fh;
/* Applications calling flock(2) on dirfd(fd) need this... */
if (!fh->nohandle ())
fh->set_unique_id ();
return res;
}

View File

@ -1045,6 +1045,8 @@ public:
void rewinddir (DIR *);
fhandler_dev (void *) {}
dev_t get_dev () { return dir_exists ? pc.fs_serial_number ()
: get_device (); }
void copyto (fhandler_base *x)
{
@ -1075,7 +1077,6 @@ class fhandler_cygdrive: public fhandler_disk_file
public:
fhandler_cygdrive ();
int open (int flags, mode_t mode);
int close ();
DIR __reg2 *opendir (int fd);
int __reg3 readdir (DIR *, dirent *);
void rewinddir (DIR *);
@ -1084,6 +1085,7 @@ class fhandler_cygdrive: public fhandler_disk_file
int __reg2 fstatvfs (struct statvfs *buf);
fhandler_cygdrive (void *) {}
dev_t get_dev () { return get_device (); }
void copyto (fhandler_base *x)
{
@ -1726,6 +1728,7 @@ class fhandler_windows: public fhandler_base
public:
fhandler_windows ();
int is_windows () { return 1; }
HWND get_hwnd () { return hWnd_; }
int open (int flags, mode_t mode = 0);
ssize_t __stdcall write (const void *ptr, size_t len);
void __reg3 read (void *ptr, size_t& len);
@ -1733,8 +1736,6 @@ class fhandler_windows: public fhandler_base
off_t lseek (off_t, int) { return 0; }
int close () { return 0; }
void set_close_on_exec (bool val);
void fixup_after_fork (HANDLE parent);
select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *);

View File

@ -16,6 +16,7 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "devices.h"
#include "tls_pbuf.h"
#define _COMPILING_NEWLIB
#include <dirent.h>
@ -49,21 +50,27 @@ fhandler_dev::open (int flags, mode_t mode)
set_errno (EISDIR);
return 0;
}
int ret = fhandler_disk_file::open (flags, mode);
/* Filter O_CREAT flag to avoid creating a file called /dev accidentally. */
int ret = fhandler_disk_file::open (flags & ~O_CREAT, mode);
if (!ret)
{
flags |= O_DIROPEN;
set_flags (flags);
nohandle (true);
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 1;
return ret;
}
int
fhandler_dev::close ()
{
if (nohandle ())
return 0;
return fhandler_disk_file::close ();
}
@ -87,25 +94,24 @@ fhandler_dev::fstatvfs (struct statvfs *sfs)
int ret = -1, opened = 0;
HANDLE fh = get_handle ();
if (!fh && !nohandle ())
if (!fh)
{
if (!open (O_RDONLY, 0))
return -1;
opened = 1;
}
if (!nohandle ())
if (pc.fs_got_fs ())
ret = fhandler_disk_file::fstatvfs (sfs);
else
{
ret = fhandler_disk_file::fstatvfs (sfs);
goto out;
/* Virtual file system. Just return an empty buffer with a few values
set to something useful similar to Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX;
ret = 0;
}
/* Virtual file system. Just return an empty buffer with a few values
set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_namemax = NAME_MAX;
ret = 0;
out:
if (opened)
close ();
return ret;
@ -114,13 +120,10 @@ out:
DIR *
fhandler_dev::opendir (int fd)
{
DIR *dir;
DIR *res = NULL;
dir = fhandler_disk_file::opendir (fd);
DIR *dir = fhandler_disk_file::opendir (fd);
if (dir)
return dir;
if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
dir_exists = true;
else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
set_errno (ENOMEM);
else if ((dir->__d_dirent =
(struct dirent *) malloc (sizeof (struct dirent))) == NULL)
@ -144,26 +147,28 @@ fhandler_dev::opendir (int fd)
if (fd >= 0)
dir->__d_fd = fd;
else if (!open (O_RDONLY, 0))
goto free_dirent;
else
{
cfd = this;
dir->__d_fd = cfd;
cfd->nohandle (true);
}
set_close_on_exec (true);
dir->__fh = this;
devidx = dev_storage_scan_start;
res = dir;
dir_exists = false;
}
syscall_printf ("%p = opendir (%s)", res, get_name ());
return res;
devidx = dir_exists ? NULL : dev_storage_scan_start;
syscall_printf ("%p = opendir (%s)", dir, get_name ());
return dir;
free_dirent:
free (dir->__d_dirent);
free_dir:
free (dir);
return res;
return NULL;
}
int
@ -226,5 +231,7 @@ void
fhandler_dev::rewinddir (DIR *dir)
{
devidx = dir_exists ? NULL : dev_storage_scan_start;
fhandler_disk_file::rewinddir (dir);
dir->__d_position = 0;
if (dir_exists)
fhandler_disk_file::rewinddir (dir);
}

View File

@ -1833,11 +1833,17 @@ fhandler_disk_file::opendir (int fd)
dir->__d_position = 0;
dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0')
? dirent_isroot : 0;
dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ());
d_cachepos (dir) = 0;
dir->__d_internal = 0;
if (!pc.iscygdrive ())
if (pc.iscygdrive ())
{
if (fd < 0 && !open (O_RDONLY, 0))
goto free_mounts;
}
else
{
dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ());
d_cachepos (dir) = 0;
if (fd < 0)
{
/* opendir() case. Initialize with given directory name and
@ -1918,8 +1924,6 @@ fhandler_disk_file::opendir (int fd)
time on exit. Nasty, nasty... */
cfd = this;
dir->__d_fd = cfd;
if (pc.iscygdrive ())
cfd->nohandle (true);
}
set_close_on_exec (true);
dir->__fh = this;
@ -2380,16 +2384,16 @@ fhandler_cygdrive::open (int flags, mode_t mode)
set_errno (EISDIR);
return 0;
}
flags |= O_DIROPEN;
set_flags (flags);
nohandle (true);
return 1;
}
int
fhandler_cygdrive::close ()
{
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;
}
void
@ -2416,6 +2420,7 @@ fhandler_cygdrive::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;
}

View File

@ -1,7 +1,7 @@
/* fhandler_windows.cc: code to access windows message queues.
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012
Red Hat, Inc.
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012,
2013 Red Hat, Inc.
Written by Sergey S. Okhapkin (sos@prospect.com.ru).
Feedback and testing by Andy Piper (andyp@parallax.co.uk).
@ -54,12 +54,9 @@ fhandler_windows::fhandler_windows ()
}
int
fhandler_windows::open (int flags, mode_t)
fhandler_windows::open (int flags, mode_t mode)
{
set_flags ((flags & ~O_TEXT) | O_BINARY);
close_on_exec (true);
set_open_status ();
return 1;
return fhandler_base::open ((flags & ~O_TEXT) | O_BINARY, mode);
}
ssize_t __stdcall
@ -96,10 +93,10 @@ fhandler_windows::read (void *buf, size_t& len)
return;
}
HANDLE w4[3] = { get_handle (), };
set_signal_arrived here (w4[1]);
DWORD cnt = 2;
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
HANDLE w4[2];
set_signal_arrived here (w4[0]);
DWORD cnt = 1;
if ((w4[1] = pthread::get_cancel_event ()) != NULL)
++cnt;
for (;;)
{
@ -109,6 +106,19 @@ fhandler_windows::read (void *buf, size_t& len)
MWMO_INPUTAVAILABLE))
{
case WAIT_OBJECT_0:
if (_my_tls.call_signal_handler ())
continue;
len = (size_t) -1;
set_errno (EINTR);
break;
case WAIT_OBJECT_0 + 1:
if (cnt > 1) /* WAIT_OBJECT_0 + 1 is the cancel event object. */
{
pthread::static_cancel_self ();
break;
}
/*FALLTHRU*/
case WAIT_OBJECT_0 + 2:
if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
{
len = (size_t) -1;
@ -119,15 +129,6 @@ fhandler_windows::read (void *buf, size_t& len)
else
len = sizeof (MSG);
break;
case WAIT_OBJECT_0 + 1:
if (_my_tls.call_signal_handler ())
continue;
len = (size_t) -1;
set_errno (EINTR);
break;
case WAIT_OBJECT_0 + 2:
pthread::static_cancel_self ();
break;
case WAIT_TIMEOUT:
len = (size_t) -1;
set_errno (EAGAIN);
@ -163,25 +164,3 @@ fhandler_windows::ioctl (unsigned int cmd, void *val)
}
return 0;
}
void
fhandler_windows::set_close_on_exec (bool val)
{
if (get_handle ())
fhandler_base::set_close_on_exec (val);
else
fhandler_base::close_on_exec (val);
void *h = hWnd_;
if (h)
set_no_inheritance (h, val);
}
void
fhandler_windows::fixup_after_fork (HANDLE parent)
{
if (get_handle ())
fhandler_base::fixup_after_fork (parent);
void *h = hWnd_;
if (h)
fork_fixup (parent, h, "hWnd_");
}

View File

@ -380,6 +380,7 @@ 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 ();

View File

@ -1542,6 +1542,8 @@ peek_windows (select_record *me, bool)
MSG m;
HANDLE h;
set_handle_or_return_if_not_open (h, me);
/* We need the hWnd value, not the io_handle. */
h = ((fhandler_windows *) me->fh)->get_hwnd ();
if (me->read_selected && me->read_ready)
return 1;
@ -1576,7 +1578,6 @@ fhandler_windows::select_read (select_stuff *ss)
s->peek = peek_windows;
s->read_selected = true;
s->read_ready = false;
s->h = get_handle ();
s->windows_handle = true;
return s;
}
@ -1591,7 +1592,6 @@ fhandler_windows::select_write (select_stuff *ss)
s->verify = verify_ok;
}
s->peek = peek_windows;
s->h = get_handle ();
s->write_selected = true;
s->write_ready = true;
s->windows_handle = true;
@ -1608,7 +1608,6 @@ fhandler_windows::select_except (select_stuff *ss)
s->verify = verify_ok;
}
s->peek = peek_windows;
s->h = get_handle ();
s->except_selected = true;
s->except_ready = false;
s->windows_handle = true;