diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-10-30 09:44:47 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-10-30 09:44:47 +0000 |
commit | 751bbaf96ae7ee249d7f5cb243b1239779ca0530 (patch) | |
tree | a7c6fbb535a816767ae9a7231458d3688bea8b17 /winsup/cygwin/fhandler_dev.cc | |
parent | 0160e166ee3c6a87c9e95c2d75ee2d2a0c4c2a29 (diff) | |
download | cygnal-751bbaf96ae7ee249d7f5cb243b1239779ca0530.tar.gz cygnal-751bbaf96ae7ee249d7f5cb243b1239779ca0530.tar.bz2 cygnal-751bbaf96ae7ee249d7f5cb243b1239779ca0530.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_dev.cc')
-rw-r--r-- | winsup/cygwin/fhandler_dev.cc | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/winsup/cygwin/fhandler_dev.cc b/winsup/cygwin/fhandler_dev.cc index 48ac0b70f..668d0b480 100644 --- a/winsup/cygwin/fhandler_dev.cc +++ b/winsup/cygwin/fhandler_dev.cc @@ -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); } |