diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2012-03-29 22:02:54 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2012-03-29 22:02:54 +0400 |
commit | 9ca7bca3c381d4affa78b450bd7284da9a68ec9b (patch) | |
tree | b411492e1997760f201f1bac335296211e5ddec3 /winsup/cygwin/fhandler_disk_file.cc | |
parent | d46ed263afc680ce6a7f84114a3014b84e447987 (diff) |
* Makefile.in (DLL_OFILES): Add fhandler_dev.o.
* devices.h (DEV_DEV_MAJOR): Define.
(FH_DEV): Redefine in terms of DEV_DEV_MAJOR.
(ext_dev_storage): Declare.
(dev_storage_size): Declare.
(dev_dev_storage): Declare.
(dev_dev): Define.
(isdev_dev): Define.
* devices.in (dev_dev_storage): Activate.
(ext_dev_storage): Define as externally available pointer to
dev_storage.
(dev_storage_size): Define to contain number of dev_storage elements.
* dir.cc (rmdir): Handle /dev as always not empty.
* dtable.cc (fh_alloc): Handle DEV_DEV_MAJOR.
* fhandler.h (fhandler_dev): New class, derived from fhandler_disk_file.
(fhandler_union): Add fhandler_dev member.
* fhandler_disk_file.cc (class __DIR_mounts): Handle /dev directory
to make sure it always exists.
* fhandler_dev.cc: New file implementing /dev.
* globals.cc (ro_u_dev): New R/O unicode string.
* path.cc (path_conv::check): Handle FH_DEV device.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 1fe12b0a2..3f54ebefa 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -26,6 +26,7 @@ details. */ #include "pwdgrp.h" #include <winioctl.h> #include <lm.h> +#include "devices.h" #define _COMPILING_NEWLIB #include <dirent.h> @@ -36,11 +37,12 @@ class __DIR_mounts const char *parent_dir; int parent_dir_len; UNICODE_STRING mounts[MAX_MOUNTS]; - bool found[MAX_MOUNTS + 2]; + bool found[MAX_MOUNTS + 3]; UNICODE_STRING cygdrive; #define __DIR_PROC (MAX_MOUNTS) #define __DIR_CYGDRIVE (MAX_MOUNTS+1) +#define __DIR_DEV (MAX_MOUNTS+2) __ino64_t eval_ino (int idx) { @@ -84,6 +86,11 @@ public: found[__DIR_PROC] = true; return 2; } + if (RtlEqualUnicodeString (fname, &ro_u_dev, FALSE)) + { + found[__DIR_DEV] = true; + return 2; + } if (fname->Length / sizeof (WCHAR) == mount_table->cygdrive_len - 2 && RtlEqualUnicodeString (fname, &cygdrive, FALSE)) { @@ -121,6 +128,13 @@ public: *retname = ro_u_proc; return 2; } + if (!found[__DIR_DEV]) + { + found[__DIR_DEV] = true; + if (retname) + *retname = ro_u_dev; + return 2; + } if (!found[__DIR_CYGDRIVE]) { found[__DIR_CYGDRIVE] = true; @@ -2351,6 +2365,66 @@ fhandler_disk_file::closedir (DIR *dir) return res; } +fhandler_dev::fhandler_dev () : + fhandler_disk_file (), lastrealpos (0), dir_exists (true) +{ +} + +DIR * +fhandler_dev::opendir (int fd) +{ + DIR *dir; + DIR *res = NULL; + + dir = fhandler_disk_file::opendir (fd); + if (dir) + return dir; + if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL) + set_errno (ENOMEM); + else if ((dir->__d_dirent = + (struct dirent *) malloc (sizeof (struct dirent))) == NULL) + { + set_errno (ENOMEM); + goto free_dir; + } + else + { + cygheap_fdnew cfd; + if (cfd < 0 && fd < 0) + goto free_dirent; + + dir->__d_dirname = NULL; + dir->__d_dirent->__d_version = __DIRENT_VERSION; + dir->__d_cookie = __DIRENT_COOKIE; + dir->__handle = INVALID_HANDLE_VALUE; + dir->__d_position = 0; + dir->__flags = 0; + dir->__d_internal = 0; + + if (fd >= 0) + dir->__d_fd = fd; + else + { + cfd = this; + dir->__d_fd = cfd; + cfd->nohandle (true); + } + set_close_on_exec (true); + dir->__fh = this; + dir_exists = false; + res = dir; + } + + syscall_printf ("%p = opendir (%s)", res, get_name ()); + return res; + +free_dirent: + free (dir->__d_dirent); +free_dir: + free (dir); + return res; +} + fhandler_cygdrive::fhandler_cygdrive () : fhandler_disk_file (), ndrives (0), pdrive (NULL) { |