Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-03-31 21:38:00 +0400
committerChristopher Faylor <me@cgf.cx>2012-03-31 21:38:00 +0400
commit1c1294b4ce46055413bc7cea6450c96425b9c562 (patch)
treedd9c126fb8a2ef0246f611b4e7c391365a2defa7 /winsup/cygwin/fhandler_dev.cc
parent54440304b397a5d3f4b19415c09a5939a9074c37 (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.cc306
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);
}
-