diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2010-09-06 13:47:01 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2010-09-06 13:47:01 +0400 |
commit | 43f65cdd7dae0bbeb5b5f26b008c8645d524869d (patch) | |
tree | ccc368e556e96032ec5ee254bf881842a08842c9 /winsup/cygwin/fhandler_proc.cc | |
parent | 0de488378f3bb2b881436a9e0781b66a0eda815f (diff) |
* Makefile.in (DLL_OFILES): Add fhandler_procsys.o.
* devices.h (enum fh_devices): Add FH_PROCSYS.
* devices.in (dev_procsys_storage): New device.
* devices.cc: Regenerate.
* dtable.cc (build_fh_pc): Add code to allocate fhandler_procsys.
* fhandler.h (proc_len): Convert to size_t.
(procsys): Declare.
(procsys_len): Declare.
(enum virtual_ftype_t): Move here from fhandler_virtual.h.
Add members supported by fhandler_procsys.
(fhandler_virtual::exists): Return virtual_ftype_t. Change
in all derived classes.
(class fhandler_procsys): New class.
(fhandler_union): Add fhandler_procnet and fhandler_procsys members.
* fhandler_disk_file.cc (__DIR_mounts::check_missing_mount): Use
ro_u_proc.
(fhandler_base::fstat_by_handle): Don't copy attributes if file is an
NT device.
(fhandler_base::fstat_by_name): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::exists): Return
virtual_ftype_t.
* fhandler_proc.cc (proc_tab): Sort alphabetically. Use _VN macro
to store length.
(proc_len): Change to size_t.
(proc_tab_cmp): New static function.
(virt_tab_search): New function to search entry in virt_tab_t
arrays. Use throughout in /proc and sibling classes instead of
loop.
(fhandler_proc::exists): Return virtual_ftype_t.
* fhandler_process.cc (process_tab): Sort alphabetically. Use _VN
macro to store length.
(fhandler_process::exists): Return virtual_ftype_t.
(fhandler_process::open): Simplify code.
* fhandler_procnet.cc (procnet_tab): Sort alphabetically. Use _VN
macro to store length.
(fhandler_procnet::exists): Return virtual_ftype_t.
(fhandler_procnet::open): Simplify.
* fhandler_procsys.cc: New file.
* fhandler_registry.cc (fhandler_registry::exists): Return
virtual_ftype_t.
* fhandler_virtual.cc (fhandler_virtual::exists): Ditto.
* fhandler_virtual.h (enum virtual_ftype_t): Move to fhandler.h.
(virt_tab_t): Add name_len member.
(_VN): New macro.
(virt_tab_search): Declare.
* mount.cc (mount_info::conv_to_win32_path): Fix comment. Backslashify
isprocsys_dev paths.
* ntdll.h (STATUS_OBJECT_TYPE_MISMATCH): Define
(STATUS_INSTANCE_NOT_AVAILABLE): Define.
(STATUS_PIPE_NOT_AVAILABLE): Define.
(STATUS_INVALID_PIPE_STATE): Define.
(STATUS_PIPE_BUSY): Define.
(SYMBOLIC_LINK_QUERY): Define.
(NtOpenSymbolicLinkObject): Declare.
(NtQuerySymbolicLinkObject): Declare.
* path.cc (path_conv::check): Accommodate fact that exists method
returns virtual_ftype_t now. Add cases for new virtual_ftype_t
types.
(cygwin_conv_path): Add GLOBALROOT prefix to native device paths.
Make sure to strip \\?\ prefix only for actual filesystem-based
paths, not for all paths.
* path.h (isproc_dev): Add FH_PROCSYS.
(isprocsys_dev): Define.
Diffstat (limited to 'winsup/cygwin/fhandler_proc.cc')
-rw-r--r-- | winsup/cygwin/fhandler_proc.cc | 124 |
1 files changed, 75 insertions, 49 deletions
diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index 3289acb15..df381127a 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -46,23 +46,24 @@ static _off64_t format_proc_filesystems (void *, char *&); /* names of objects in /proc */ static const virt_tab_t proc_tab[] = { - { ".", FH_PROC, virt_directory, NULL }, - { "..", FH_PROC, virt_directory, NULL }, - { "loadavg", FH_PROC, virt_file, format_proc_loadavg }, - { "meminfo", FH_PROC, virt_file, format_proc_meminfo }, - { "registry", FH_REGISTRY, virt_directory, NULL }, - { "stat", FH_PROC, virt_file, format_proc_stat }, - { "version", FH_PROC, virt_file, format_proc_version }, - { "uptime", FH_PROC, virt_file, format_proc_uptime }, - { "cpuinfo", FH_PROC, virt_file, format_proc_cpuinfo }, - { "partitions", FH_PROC, virt_file, format_proc_partitions }, - { "self", FH_PROC, virt_symlink, format_proc_self }, - { "mounts", FH_PROC, virt_symlink, format_proc_mounts }, - { "registry32", FH_REGISTRY, virt_directory, NULL }, - { "registry64", FH_REGISTRY, virt_directory, NULL }, - { "net", FH_PROCNET, virt_directory, NULL }, - { "filesystems", FH_PROC, virt_file, format_proc_filesystems }, - { NULL, 0, virt_none, NULL } + { _VN ("."), FH_PROC, virt_directory, NULL }, + { _VN (".."), FH_PROC, virt_directory, NULL }, + { _VN ("cpuinfo"), FH_PROC, virt_file, format_proc_cpuinfo }, + { _VN ("filesystems"), FH_PROC, virt_file, format_proc_filesystems }, + { _VN ("loadavg"), FH_PROC, virt_file, format_proc_loadavg }, + { _VN ("meminfo"), FH_PROC, virt_file, format_proc_meminfo }, + { _VN ("mounts"), FH_PROC, virt_symlink, format_proc_mounts }, + { _VN ("net"), FH_PROCNET, virt_directory, NULL }, + { _VN ("partitions"), FH_PROC, virt_file, format_proc_partitions }, + { _VN ("registry"), FH_REGISTRY, virt_directory, NULL }, + { _VN ("registry32"), FH_REGISTRY, virt_directory, NULL }, + { _VN ("registry64"), FH_REGISTRY, virt_directory, NULL }, + { _VN ("self"), FH_PROC, virt_symlink, format_proc_self }, + { _VN ("stat"), FH_PROC, virt_file, format_proc_stat }, + { _VN ("sys"), FH_PROCSYS, virt_directory, NULL }, + { _VN ("uptime"), FH_PROC, virt_file, format_proc_uptime }, + { _VN ("version"), FH_PROC, virt_file, format_proc_version }, + { NULL, 0, 0, virt_none, NULL } }; #define PROC_DIR_COUNT 4 @@ -71,11 +72,37 @@ static const int PROC_LINK_COUNT = (sizeof (proc_tab) / sizeof (virt_tab_t)) - 1 /* name of the /proc filesystem */ const char proc[] = "/proc"; -const int proc_len = sizeof (proc) - 1; +const size_t proc_len = sizeof (proc) - 1; -/* Auxillary function that returns the fhandler associated with the given path - this is where it would be nice to have pattern matching in C - polymorphism - just doesn't cut it. */ +/* bsearch compare function. */ +static int +proc_tab_cmp (const void *key, const void *memb) +{ + int ret = strncmp (((virt_tab_t *) key)->name, ((virt_tab_t *) memb)->name, + ((virt_tab_t *) memb)->name_len); + if (!ret && ((virt_tab_t *) key)->name[((virt_tab_t *) memb)->name_len] != '\0' && ((virt_tab_t *) key)->name[((virt_tab_t *) memb)->name_len] != '/') + return 1; + return ret; +} + +/* Helper function to perform a binary search of the incoming pathname + against the alpha-sorted virtual file table. */ +virt_tab_t * +virt_tab_search (const char *path, bool prefix, const virt_tab_t *table, + size_t nelem) +{ + virt_tab_t key = { path, 0, 0, virt_none, NULL }; + virt_tab_t *entry = (virt_tab_t *) bsearch (&key, table, nelem, + sizeof (virt_tab_t), + proc_tab_cmp); + if (entry && (path[entry->name_len] == '\0' + || (prefix && path[entry->name_len] == '/'))) + return entry; + return NULL; +} + +/* Auxillary function that returns the fhandler associated with the given + path. */ DWORD fhandler_proc::get_proc_fhandler (const char *path) { @@ -91,12 +118,10 @@ fhandler_proc::get_proc_fhandler (const char *path) if (*path == 0) return FH_PROC; - for (int i = 0; proc_tab[i].name; i++) - { - if (path_prefix_p (proc_tab[i].name, path, strlen (proc_tab[i].name), - false)) - return proc_tab[i].fhandler; - } + virt_tab_t *entry = virt_tab_search (path, true, proc_tab, + PROC_LINK_COUNT); + if (entry) + return entry->fhandler; if (pinfo (atoi (path))) return FH_PROCESS; @@ -120,7 +145,7 @@ fhandler_proc::get_proc_fhandler (const char *path) /* 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. */ -int +virtual_ftype_t fhandler_proc::exists () { const char *path = get_name (); @@ -128,12 +153,13 @@ fhandler_proc::exists () path += proc_len; if (*path == 0) return virt_rootdir; - for (int i = 0; proc_tab[i].name; i++) - if (!strcmp (path + 1, proc_tab[i].name)) - { - fileid = i; - return proc_tab[i].type; - } + virt_tab_t *entry = virt_tab_search (path + 1, false, proc_tab, + PROC_LINK_COUNT); + if (entry) + { + fileid = entry - proc_tab; + return entry->type; + } return virt_none; } @@ -163,21 +189,21 @@ fhandler_proc::fstat (struct __stat64 *buf) } else { - path++; - for (int i = 0; proc_tab[i].name; i++) - if (!strcmp (path, proc_tab[i].name)) - { - if (proc_tab[i].type == virt_directory) - buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - else if (proc_tab[i].type == virt_symlink) - buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; - else - { - buf->st_mode &= NO_X; - buf->st_mode |= S_IFREG; - } - return 0; - } + virt_tab_t *entry = virt_tab_search (path + 1, false, proc_tab, + PROC_LINK_COUNT); + if (entry) + { + if (entry->type == virt_directory) + buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; + else if (entry->type == virt_symlink) + buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; + else + { + buf->st_mode &= NO_X; + buf->st_mode |= S_IFREG; + } + return 0; + } } set_errno (ENOENT); return -1; |