From b2671d9e1c503734c64a66d57465747a05a5cc06 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 22 Jul 2019 18:40:33 +0200 Subject: [PATCH] Cygwin: change virtual_ftype_t to not rely on negative values So far negative values were denoting files, positive values denoting directories. We should prefer a less error prone method. Redefine virtual_ftype_t to contain only positive values and replace checks for negativ or positive values with inline functions virt_ftype_isfile() and virt_ftype_isdir(). Drop outdcated comments referring to numerical virtual_ftype_t values. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 37 ++++++++++++++++++--------- winsup/cygwin/fhandler_netdrive.cc | 2 -- winsup/cygwin/fhandler_proc.cc | 2 -- winsup/cygwin/fhandler_process.cc | 2 +- winsup/cygwin/fhandler_procnet.cc | 4 --- winsup/cygwin/fhandler_procsys.cc | 2 -- winsup/cygwin/fhandler_procsysvipc.cc | 3 --- winsup/cygwin/fhandler_registry.cc | 13 +++------- winsup/cygwin/fhandler_virtual.cc | 2 +- 9 files changed, 31 insertions(+), 36 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 92edf8b48..12a87b162 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -126,20 +126,33 @@ enum del_lock_called_from { }; enum virtual_ftype_t { - virt_fdsymlink = -8, /* Fd symlink (e.g. /proc//fd/0) */ - virt_blk = -7, /* Block special */ - virt_chr = -6, /* Character special */ - virt_fsfile = -5, /* FS-based file via /proc/sys */ - virt_socket = -4, /* Socket */ - virt_pipe = -3, /* Pipe */ - virt_symlink = -2, /* Symlink */ - virt_file = -1, /* Regular file */ - virt_none = 0, /* Invalid, Error */ - virt_directory = 1, /* Directory */ - virt_rootdir = 2, /* Root directory of virtual FS */ - virt_fsdir = 3, /* FS-based directory via /proc/sys */ + virt_none = 0x0000, /* Invalid, Error */ + virt_file = 0x0001, /* Regular file */ + virt_symlink = 0x0002, /* Symlink */ + virt_pipe = 0x0003, /* Pipe */ + virt_socket = 0x0004, /* Socket */ + virt_chr = 0x0005, /* Character special */ + virt_blk = 0x0006, /* Block special */ + virt_fdsymlink = 0x0007, /* Fd symlink (e.g. /proc//fd/0) */ + virt_fsfile = 0x0008, /* FS-based file via /proc/sys */ + virt_dir_type = 0x1000, + virt_directory = 0x1001, /* Directory */ + virt_rootdir = 0x1002, /* Root directory of virtual FS */ + virt_fsdir = 0x1003, /* FS-based directory via /proc/sys */ }; +static inline bool +virt_ftype_isfile (virtual_ftype_t _f) +{ + return _f != virt_none && !(_f & virt_dir_type); +} + +static inline bool +virt_ftype_isdir (virtual_ftype_t _f) +{ + return _f & virt_dir_type; +} + class fhandler_base { friend class dtable; diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc index 654360f22..129d9dd86 100644 --- a/winsup/cygwin/fhandler_netdrive.cc +++ b/winsup/cygwin/fhandler_netdrive.cc @@ -145,8 +145,6 @@ create_thread_and_wait (int what, PVOID in, PVOID out, DWORD outsize, return ndi.ret; } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if it's a symlink. */ virtual_ftype_t fhandler_netdrive::exists () { diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index c461bbc75..48476beb8 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -168,8 +168,6 @@ fhandler_proc::get_proc_fhandler (const char *path) return FH_PROC; } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if it's a symlink. */ virtual_ftype_t fhandler_proc::exists () { diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 15c0a41e2..0dafc2f0f 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -169,7 +169,7 @@ fhandler_process::fstat (struct stat *buf) buf->st_uid = p->uid; buf->st_gid = p->gid; buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - if (file_type == 1) + if (file_type == virt_directory) buf->st_nlink = 2; else buf->st_nlink = 3; diff --git a/winsup/cygwin/fhandler_procnet.cc b/winsup/cygwin/fhandler_procnet.cc index 452f33c57..2ea827c48 100644 --- a/winsup/cygwin/fhandler_procnet.cc +++ b/winsup/cygwin/fhandler_procnet.cc @@ -41,10 +41,6 @@ static const virt_tab_t procnet_tab[] = static const int PROCNET_LINK_COUNT = (sizeof (procnet_tab) / sizeof (virt_tab_t)) - 1; -/* Returns 0 if path doesn't exist, >0 if path is a directory, - * -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe, - * -4 if path is a socket. - */ virtual_ftype_t fhandler_procnet::exists () { diff --git a/winsup/cygwin/fhandler_procsys.cc b/winsup/cygwin/fhandler_procsys.cc index e2aebd5b1..d2540d0a1 100644 --- a/winsup/cygwin/fhandler_procsys.cc +++ b/winsup/cygwin/fhandler_procsys.cc @@ -39,8 +39,6 @@ const size_t procsys_len = sizeof (procsys) - 1; RtlInitUnicodeString ((p), namebuf); \ } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if it's a symlink. */ virtual_ftype_t fhandler_procsys::exists (struct stat *buf) { diff --git a/winsup/cygwin/fhandler_procsysvipc.cc b/winsup/cygwin/fhandler_procsysvipc.cc index 440771aeb..6b4fd8889 100644 --- a/winsup/cygwin/fhandler_procsysvipc.cc +++ b/winsup/cygwin/fhandler_procsysvipc.cc @@ -52,9 +52,6 @@ static const virt_tab_t procsysvipc_tab[] = static const int PROCSYSVIPC_LINK_COUNT = (sizeof (procsysvipc_tab) / sizeof (virt_tab_t)) - 1; -/* Returns 0 if path doesn't exist, >0 if path is a directory, - * -1 if path is a file. - */ virtual_ftype_t fhandler_procsysvipc::exists () { diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index ecaed085c..f7db01b99 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -306,13 +306,8 @@ multi_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc) return sum; } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - * <0 if path is a file. - * - * We open the last key but one and then enum it's sub-keys and values to see if the - * final component is there. This gets round the problem of not having security access - * to the final key in the path. - */ +/* Returns 0 if path doesn't exist, otherwise a virtual_ftype_t value + specifying the exact file type. */ virtual_ftype_t fhandler_registry::exists () { @@ -502,7 +497,7 @@ fhandler_registry::fstat (struct stat *buf) const char *path = get_name () + proc_len + prefix_len + 2; hKey = open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, wow64, - (file_type < virt_none) ? true : false); + virt_ftype_isfile (file_type) ? true : false); if (hKey == HKEY_PERFORMANCE_DATA) /* RegQueryInfoKey () always returns write time 0, @@ -519,7 +514,7 @@ fhandler_registry::fstat (struct stat *buf) to_timestruc_t ((PLARGE_INTEGER) &ftLastWriteTime, &buf->st_mtim); buf->st_ctim = buf->st_birthtim = buf->st_mtim; time_as_timestruc_t (&buf->st_atim); - if (file_type > virt_none) + if (virt_ftype_isdir (file_type)) buf->st_nlink = subkey_count + 2; else { diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index b6b95f967..6169f3c81 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -45,7 +45,7 @@ fhandler_virtual::opendir (int fd) DIR *res = NULL; size_t len; - if (exists () <= 0) + if (!virt_ftype_isdir (exists ())) set_errno (ENOTDIR); else if ((len = strlen (get_name ())) > PATH_MAX - 3) set_errno (ENAMETOOLONG);