summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_dev.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-10-30 09:44:47 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-10-30 09:44:47 +0000
commit751bbaf96ae7ee249d7f5cb243b1239779ca0530 (patch)
treea7c6fbb535a816767ae9a7231458d3688bea8b17 /winsup/cygwin/fhandler_dev.cc
parent0160e166ee3c6a87c9e95c2d75ee2d2a0c4c2a29 (diff)
downloadcygnal-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.cc71
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);
}