diff options
author | Christopher Faylor <me@cgf.cx> | 2012-03-31 21:38:00 +0400 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2012-03-31 21:38:00 +0400 |
commit | 1c1294b4ce46055413bc7cea6450c96425b9c562 (patch) | |
tree | dd9c126fb8a2ef0246f611b4e7c391365a2defa7 /winsup/cygwin/fhandler_dev.cc | |
parent | 54440304b397a5d3f4b19415c09a5939a9074c37 (diff) |
(Interim checkin while we work on this)
* devices.cc: Regenerate.
* devices.h (device::noexpose): New field.
(device::dev_on_fs): Make a bit field.
(get_major): Use proper type for declaration.
(expose): New field.
(ext_dev_storage): Delete declaration.
(dev_storage_size): Ditto.
(dev_storage): New declaration.
(dev_storage_end): Ditto.
* devices.in: Mark /dev/ptym*, /dev/com*, /dev/pipe, /dev/fifo, and "/dev" as
"no expose".
* fhandler.h (fhandler_dev::lastrealpos): Delete declaration.
(fhandler_dev::devidx): Declare new field.
* fhandler_disk_file.cc: Move fhandler_dev functions into fhandler_dev.cc.
* fhandler_dev.cc: Add includes needed for functions moved from
fhandler_disk_file.cc.
(dev_storage_scan_start): Define place to start listing devices.
(dev_storage_size): Define size of array to scan.
(fhandler_dev::fhandler_dev): Move here from fhandler_disk_file.cc.
(fhandler_dev::opendir): Ditto.
(fhandler_dev::readdir): Just check devidx for non-NULL to determine when to go
to disk for /dev content. Use dev_storage rather than ext_dev_storage.
Iterate over dev_storage using devidx pointer. Use accessor functions rather
than raw references to the device struct. Only increment dir->__d_position
when we are actually going to be returning something. Add debug_printf for
exit.
(fhandler_dev::rewinddir): Set devidx as appropriate depending on whether
there's a /dev on disk or not.
* gendevices: Don't mark dev_storage static but do put it in the _RDATA
section.
* path.cc (path_conv::check): Use new "device::expose()" function to decide to
forbid programs from referencing internal device types.
Diffstat (limited to 'winsup/cygwin/fhandler_dev.cc')
-rw-r--r-- | winsup/cygwin/fhandler_dev.cc | 306 |
1 files changed, 178 insertions, 128 deletions
diff --git a/winsup/cygwin/fhandler_dev.cc b/winsup/cygwin/fhandler_dev.cc index 27b1ef321..713e8c0fb 100644 --- a/winsup/cygwin/fhandler_dev.cc +++ b/winsup/cygwin/fhandler_dev.cc @@ -14,12 +14,16 @@ details. */ #include "fhandler.h" #include "shared_info.h" #include "ntdll.h" +#include "dtable.h" +#include "cygheap.h" #include "devices.h" #define _COMPILING_NEWLIB #include <dirent.h> #define dev_prefix_len (sizeof ("/dev")) +#define dev_storage_scan_start (dev_storage + 1) +#define dev_storage_size (dev_storage_end - dev_storage_scan_start) static int device_cmp (const void *a, const void *b) @@ -28,13 +32,73 @@ device_cmp (const void *a, const void *b) ((const device *) b)->name + dev_prefix_len); } +fhandler_dev::fhandler_dev () : + fhandler_disk_file (), devidx (NULL), 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; + devidx = dev_storage_scan_start; + res = dir; + } + + syscall_printf ("%p = opendir (%s)", res, get_name ()); + return res; + +free_dirent: + free (dir->__d_dirent); +free_dir: + free (dir); + return res; +} + int fhandler_dev::readdir (DIR *dir, dirent *de) { int ret; device dev; - if (dir_exists && !lastrealpos) + if (!devidx) { while ((ret = fhandler_disk_file::readdir (dir, de)) == 0) { @@ -42,153 +106,139 @@ fhandler_dev::readdir (DIR *dir, dirent *de) /dev already, for instance by using the old script from Igor Peshansky. */ dev.name = de->d_name; - if (!bsearch (&dev, ext_dev_storage, dev_storage_size, sizeof dev, - device_cmp)) + if (!bsearch (&dev, dev_storage_scan_start, dev_storage_size, sizeof dev, + device_cmp)) break; } if (ret == ENMFILE) - lastrealpos = dir->__d_position; + devidx = dev_storage_scan_start; + else + goto out; } - if (!dir_exists || lastrealpos) + + /* Now start processing our internal dev table. */ + ret = ENMFILE; + while (devidx < dev_storage_end) { - ret = ENMFILE; - for (size_t idx = dir->__d_position - lastrealpos + 1; - idx < dev_storage_size; - ++idx) + const device& thisdev = *devidx++; + if (!thisdev.expose ()) + continue; + int devn = *const_cast<device *> (&thisdev); + /* Exclude devices which are only available for internal purposes + and devices which are not really existing at this time. */ + switch (thisdev.get_major ()) { - ++dir->__d_position; - /* Exclude devices which are only available for internal purposes - and devices which are not really existing at this time. */ - switch (ext_dev_storage[idx].d.major) + case DEV_PTYS_MAJOR: + /* Show only existing slave ptys. */ + if (cygwin_shared->tty.connect (thisdev.get_minor ()) == -1) + continue; + break; + case DEV_CONS_MAJOR: + /* Show only the one console which is our controlling tty + right now. */ + if (!iscons_dev (myself->ctty) + || myself->ctty != devn) + continue; + break; + case DEV_TTY_MAJOR: + /* Show con{in,out,sole} only if we're running in a console. */ + switch (devn) { - case DEV_VIRTFS_MAJOR: - /* Drop /dev/fifo and /dev/pipe since they are internal only. */ - switch (ext_dev_storage[idx].d.devn) - { - case FH_FIFO: - case FH_PIPE: - continue; - } - break; - case DEV_PTYM_MAJOR: - /* Only /dev/ptmx is user-visible. */ - if (strcmp (ext_dev_storage[idx].name + dev_prefix_len, "ptmx")) + case FH_CONIN: + case FH_CONOUT: + case FH_CONSOLE: + if (!iscons_dev (myself->ctty)) continue; - break; - case DEV_PTYS_MAJOR: - /* Show only existing slave ptys. */ - if (cygwin_shared->tty.connect (ext_dev_storage[idx].d.minor) - == -1) - continue; - break; - case DEV_CONS_MAJOR: - /* Show only the one console which is our controlling tty - right now. */ - if (!iscons_dev (myself->ctty) - || myself->ctty != ext_dev_storage[idx].d.devn_int) - continue; - break; - case DEV_TTY_MAJOR: - /* Show con{in,out,sole} only if we're running in a console. */ - switch (ext_dev_storage[idx].d.devn) - { - case FH_CONIN: - case FH_CONOUT: - case FH_CONSOLE: - if (!iscons_dev (myself->ctty)) - continue; - } - break; - case DEV_SERIAL_MAJOR: - /* Ignore comX devices, only print ttySx. */ - if (ext_dev_storage[idx].name[dev_prefix_len] == 'c') - continue; - /*FALLTHRU*/ - case DEV_FLOPPY_MAJOR: - case DEV_TAPE_MAJOR: - case DEV_CDROM_MAJOR: - case DEV_SD_MAJOR: - case DEV_SD1_MAJOR: - case DEV_SD2_MAJOR: - case DEV_SD3_MAJOR: - case DEV_SD4_MAJOR: - case DEV_SD5_MAJOR: - case DEV_SD6_MAJOR: - case DEV_SD7_MAJOR: - /* Check existence of POSIX devices backed by real NT devices. */ + } + break; + case DEV_SERIAL_MAJOR: + case DEV_FLOPPY_MAJOR: + case DEV_TAPE_MAJOR: + case DEV_CDROM_MAJOR: + case DEV_SD_MAJOR: + case DEV_SD1_MAJOR: + case DEV_SD2_MAJOR: + case DEV_SD3_MAJOR: + case DEV_SD4_MAJOR: + case DEV_SD5_MAJOR: + case DEV_SD6_MAJOR: + case DEV_SD7_MAJOR: + /* Check existence of POSIX devices backed by real NT devices. */ + { + WCHAR wpath[MAX_PATH]; + UNICODE_STRING upath; + OBJECT_ATTRIBUTES attr; + HANDLE h; + NTSTATUS status; + + sys_mbstowcs (wpath, MAX_PATH, thisdev.native); + RtlInitUnicodeString (&upath, wpath); + InitializeObjectAttributes (&attr, &upath, + OBJ_CASE_INSENSITIVE, NULL, NULL); + /* Except for the serial IO devices, the native paths are + direct device paths, not symlinks, so every status code + except for "NOT_FOUND" means the device exists. */ + status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, + &attr); + switch (status) { - WCHAR wpath[MAX_PATH]; - UNICODE_STRING upath; - OBJECT_ATTRIBUTES attr; - HANDLE h; - NTSTATUS status; - - sys_mbstowcs (wpath, MAX_PATH, ext_dev_storage[idx].native); - RtlInitUnicodeString (&upath, wpath); - InitializeObjectAttributes (&attr, &upath, - OBJ_CASE_INSENSITIVE, NULL, NULL); - /* Except for the serial IO devices, the native paths are - direct device paths, not symlinks, so every status code - except for "NOT_FOUND" means the device exists. */ - status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, - &attr); - switch (status) - { - case STATUS_OBJECT_NAME_NOT_FOUND: - case STATUS_OBJECT_PATH_NOT_FOUND: - continue; - case STATUS_SUCCESS: - NtClose (h); - break; - default: - break; - } + case STATUS_OBJECT_NAME_NOT_FOUND: + case STATUS_OBJECT_PATH_NOT_FOUND: + continue; + case STATUS_SUCCESS: + NtClose (h); + break; + default: + break; } - break; - } - strcpy (de->d_name, ext_dev_storage[idx].name + dev_prefix_len); - de->d_ino = hash_path_name (0, ext_dev_storage[idx].native); - switch (ext_dev_storage[idx].d.major) + } + break; + } + ++dir->__d_position; + strcpy (de->d_name, thisdev.name + dev_prefix_len); + de->d_ino = hash_path_name (0, thisdev.native); + switch (thisdev.get_major ()) + { + case DEV_FLOPPY_MAJOR: + case DEV_TAPE_MAJOR: + case DEV_CDROM_MAJOR: + case DEV_SD_MAJOR: + case DEV_SD1_MAJOR: + case DEV_SD2_MAJOR: + case DEV_SD3_MAJOR: + case DEV_SD4_MAJOR: + case DEV_SD5_MAJOR: + case DEV_SD6_MAJOR: + case DEV_SD7_MAJOR: + de->d_type = DT_BLK; + break; + case DEV_TTY_MAJOR: + switch (devn) { - case DEV_FLOPPY_MAJOR: - case DEV_TAPE_MAJOR: - case DEV_CDROM_MAJOR: - case DEV_SD_MAJOR: - case DEV_SD1_MAJOR: - case DEV_SD2_MAJOR: - case DEV_SD3_MAJOR: - case DEV_SD4_MAJOR: - case DEV_SD5_MAJOR: - case DEV_SD6_MAJOR: - case DEV_SD7_MAJOR: - de->d_type = DT_BLK; - break; - case DEV_TTY_MAJOR: - switch (ext_dev_storage[idx].d.devn) - { - case FH_CONIN: - case FH_CONOUT: - case FH_CONSOLE: - dev.parse (myself->ctty); - de->d_ino = hash_path_name (0, dev.native); - break; - } - /*FALLTHRU*/ - default: - de->d_type = DT_CHR; + case FH_CONIN: + case FH_CONOUT: + case FH_CONSOLE: + dev.parse (myself->ctty); + de->d_ino = hash_path_name (0, dev.native); break; } - ret = 0; - break; + /*FALLTHRU*/ + default: + de->d_type = DT_CHR; + break; } + ret = 0; + break; } + +out: + debug_printf ("returning %d", ret); return ret; } void fhandler_dev::rewinddir (DIR *dir) { - lastrealpos = 0; + devidx = dir_exists ? NULL : dev_storage_scan_start; fhandler_disk_file::rewinddir (dir); } - |