* 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.
This commit is contained in:
Corinna Vinschen
2010-09-06 09:47:01 +00:00
parent 0de488378f
commit 43f65cdd7d
20 changed files with 816 additions and 216 deletions

View File

@ -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;