From a918afd7033d33525ed4eb4c42ba974a8d766d65 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 30 Mar 2012 09:26:45 +0000 Subject: [PATCH] * devices.h (DEV_TTY_MAJOR): Define, use throughout where appropriate. (DEV_VIRTFS_MAJOR): Ditto. * fhandler_dev.cc (fhandler_dev::readdir): Add comments. Tweak tests for invisible devices. Don't print comX devices, only ttySX. Drop requirement to call stat64. --- winsup/cygwin/ChangeLog | 8 ++++ winsup/cygwin/devices.h | 42 +++++++++--------- winsup/cygwin/fhandler_dev.cc | 83 ++++++++++++++++++++++++++++------- 3 files changed, 96 insertions(+), 37 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index cbefec3f1..1c632eb58 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2012-03-30 Corinna Vinschen + + * devices.h (DEV_TTY_MAJOR): Define, use throughout where appropriate. + (DEV_VIRTFS_MAJOR): Ditto. + * fhandler_dev.cc (fhandler_dev::readdir): Add comments. Tweak tests + for invisible devices. Don't print comX devices, only ttySX. Drop + requirement to call stat64. + 2012-03-29 Corinna Vinschen * Makefile.in (DLL_OFILES): Add fhandler_dev.o. diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h index ff93da919..5b452ba1b 100644 --- a/winsup/cygwin/devices.h +++ b/winsup/cygwin/devices.h @@ -23,11 +23,12 @@ typedef __dev32_t _dev_t; #define MAX_CONSOLES 63 enum fh_devices { - FH_TTY = FHDEV (5, 0), - FH_CONSOLE = FHDEV (5, 1), - FH_PTMX = FHDEV (5, 2), - FH_CONIN = FHDEV (5, 255), - FH_CONOUT = FHDEV (5, 254), + DEV_TTY_MAJOR = 5, + FH_TTY = FHDEV (DEV_TTY_MAJOR, 0), + FH_CONSOLE = FHDEV (DEV_TTY_MAJOR, 1), + FH_PTMX = FHDEV (DEV_TTY_MAJOR, 2), + FH_CONIN = FHDEV (DEV_TTY_MAJOR, 255), + FH_CONOUT = FHDEV (DEV_TTY_MAJOR, 254), DEV_CONS_MAJOR = 3, FH_CONS = FHDEV (DEV_CONS_MAJOR, 0), @@ -50,24 +51,25 @@ enum fh_devices /* begin /proc directories */ - FH_PROC_MIN_MINOR = FHDEV (0, 200), - FH_PROCSYSVIPC = FHDEV (0, 249), - FH_PROCSYS = FHDEV (0, 250), - FH_PROCESSFD = FHDEV (0, 251), - FH_PROCNET = FHDEV (0, 252), - FH_REGISTRY= FHDEV (0, 253), - FH_PROCESS = FHDEV (0, 254), - FH_PROC = FHDEV (0, 255), - FH_PROC_MAX_MINOR = FHDEV (0, 255), + DEV_VIRTFS_MAJOR = 0, + FH_PROC_MIN_MINOR = FHDEV (DEV_VIRTFS_MAJOR, 200), + FH_PROCSYSVIPC = FHDEV (DEV_VIRTFS_MAJOR, 249), + FH_PROCSYS = FHDEV (DEV_VIRTFS_MAJOR, 250), + FH_PROCESSFD = FHDEV (DEV_VIRTFS_MAJOR, 251), + FH_PROCNET = FHDEV (DEV_VIRTFS_MAJOR, 252), + FH_REGISTRY= FHDEV (DEV_VIRTFS_MAJOR, 253), + FH_PROCESS = FHDEV (DEV_VIRTFS_MAJOR, 254), + FH_PROC = FHDEV (DEV_VIRTFS_MAJOR, 255), + FH_PROC_MAX_MINOR = FHDEV (DEV_VIRTFS_MAJOR, 255), /* end /proc directories */ - FH_PIPE = FHDEV (0, 199), - FH_PIPER = FHDEV (0, 198), - FH_PIPEW = FHDEV (0, 197), - FH_FIFO = FHDEV (0, 196), - FH_FS = FHDEV (0, 195), /* filesystem based device */ - FH_NETDRIVE= FHDEV (0, 194), + FH_PIPE = FHDEV (DEV_VIRTFS_MAJOR, 199), + FH_PIPER = FHDEV (DEV_VIRTFS_MAJOR, 198), + FH_PIPEW = FHDEV (DEV_VIRTFS_MAJOR, 197), + FH_FIFO = FHDEV (DEV_VIRTFS_MAJOR, 196), + FH_FS = FHDEV (DEV_VIRTFS_MAJOR, 195), /* filesystem based device */ + FH_NETDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 194), DEV_FLOPPY_MAJOR = 2, FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0), diff --git a/winsup/cygwin/fhandler_dev.cc b/winsup/cygwin/fhandler_dev.cc index ad39961e5..27b1ef321 100644 --- a/winsup/cygwin/fhandler_dev.cc +++ b/winsup/cygwin/fhandler_dev.cc @@ -32,6 +32,7 @@ int fhandler_dev::readdir (DIR *dir, dirent *de) { int ret; + device dev; if (dir_exists && !lastrealpos) { @@ -40,7 +41,6 @@ fhandler_dev::readdir (DIR *dir, dirent *de) /* Avoid to print devices for which users have created files under /dev already, for instance by using the old script from Igor Peshansky. */ - device dev; dev.name = de->d_name; if (!bsearch (&dev, ext_dev_storage, dev_storage_size, sizeof dev, device_cmp)) @@ -56,36 +56,57 @@ fhandler_dev::readdir (DIR *dir, dirent *de) idx < dev_storage_size; ++idx) { - struct __stat64 st; - ++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 0: - if (ext_dev_storage[idx].d.minor == FH_FIFO - || ext_dev_storage[idx].d.minor == FH_PIPE) - continue; + 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: - if (ext_dev_storage[idx].d.minor - || !strcmp (ext_dev_storage[idx].name, "/dev/ptm0")) + /* Only /dev/ptmx is user-visible. */ + if (strcmp (ext_dev_storage[idx].name + dev_prefix_len, "ptmx")) 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_SERIAL_MAJOR: case DEV_SD_MAJOR: case DEV_SD1_MAJOR: case DEV_SD2_MAJOR: @@ -94,6 +115,7 @@ fhandler_dev::readdir (DIR *dir, dirent *de) 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; @@ -105,8 +127,9 @@ fhandler_dev::readdir (DIR *dir, dirent *de) RtlInitUnicodeString (&upath, wpath); InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL); - /* The native paths are devices, not symlinks, so we expect - a matching error message. */ + /* 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) @@ -123,14 +146,40 @@ fhandler_dev::readdir (DIR *dir, dirent *de) } break; } - if (!lstat64 (ext_dev_storage[idx].name, &st)) + 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) { - strcpy (de->d_name, ext_dev_storage[idx].name + dev_prefix_len); - de->d_ino = st.st_ino; - de->d_type = S_ISBLK (st.st_mode) ? DT_BLK : DT_CHR; - ret = 0; + 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; break; } + ret = 0; + break; } } return ret;