diff options
Diffstat (limited to 'winsup/cygwin/fhandler_procsys.cc')
-rw-r--r-- | winsup/cygwin/fhandler_procsys.cc | 387 |
1 files changed, 0 insertions, 387 deletions
diff --git a/winsup/cygwin/fhandler_procsys.cc b/winsup/cygwin/fhandler_procsys.cc deleted file mode 100644 index 0f4cc1747..000000000 --- a/winsup/cygwin/fhandler_procsys.cc +++ /dev/null @@ -1,387 +0,0 @@ -/* fhandler_procsys.cc: fhandler for native NT namespace. - - Copyright 2010 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "winsup.h" -#include <stdlib.h> -#include "cygerrno.h" -#include "security.h" -#include "path.h" -#include "fhandler.h" -#include "dtable.h" -#include "cygheap.h" -#include <winioctl.h> -#include "ntdll.h" -#include "tls_pbuf.h" - -#include <dirent.h> - -/* Path of the /proc/sys filesystem */ -const char procsys[] = "/proc/sys"; -const size_t procsys_len = sizeof (procsys) - 1; - -#define mk_unicode_path(p) \ - WCHAR namebuf[strlen (get_name ()) + 1]; \ - { \ - const char *from; \ - PWCHAR to; \ - for (to = namebuf, from = get_name () + procsys_len; *from; \ - to++, from++) \ - /* The NT device namespace is ASCII only. */ \ - *to = (*from == '/') ? L'\\' : (WCHAR) *from; \ - if (to == namebuf) \ - *to++ = L'\\'; \ - *to = L'\0'; \ - 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 __stat64 *buf) -{ - UNICODE_STRING path; \ - OBJECT_ATTRIBUTES attr; - IO_STATUS_BLOCK io; - NTSTATUS status; - HANDLE h; - FILE_BASIC_INFORMATION fbi; - /* Default device type is character device. */ - virtual_ftype_t file_type = virt_chr; - - if (strlen (get_name ()) == procsys_len) - return virt_rootdir; - mk_unicode_path (&path); - /* First try to open as file/device to get more info. */ - InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL); - status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES, &attr, &io, - FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT); - if (status == STATUS_OBJECT_NAME_INVALID) - return virt_none; - /* If no media is found, or we get this dreaded sharing violation, let - the caller immediately try again as normal file. */ - if (status == STATUS_NO_MEDIA_IN_DEVICE - || status == STATUS_SHARING_VIOLATION) - return virt_fsfile; /* Just try again as normal file. */ - /* If file or path can't be found, let caller try again as normal file. */ - if (status == STATUS_OBJECT_PATH_NOT_FOUND - || status == STATUS_OBJECT_NAME_NOT_FOUND) - file_type = virt_fsfile; - /* Check for pipe errors, which make a good hint... */ - else if (status >= STATUS_PIPE_NOT_AVAILABLE && status <= STATUS_PIPE_BUSY) - file_type = virt_pipe; - else if (status == STATUS_ACCESS_DENIED) - { - /* Check if this is just some file or dir on a real FS to circumvent - most permission problems. */ - status = NtQueryAttributesFile (&attr, &fbi); - if (NT_SUCCESS (status)) - return (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ? virt_fsdir : virt_fsfile; - } - else if (NT_SUCCESS (status)) - { - NTSTATUS dev_stat; - FILE_FS_DEVICE_INFORMATION ffdi; - - /* If requested, check permissions. */ - if (buf) - get_object_attribute (h, &buf->st_uid, &buf->st_gid, &buf->st_mode); - /* Check for the device type. */ - dev_stat = NtQueryVolumeInformationFile (h, &io, &ffdi, sizeof ffdi, - FileFsDeviceInformation); - /* And check for file attributes. If we get them, we peeked into - a real FS through /proc/sys. */ - status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, - FileBasicInformation); - NtClose (h); - if (NT_SUCCESS (dev_stat)) - { - if (ffdi.DeviceType == FILE_DEVICE_NAMED_PIPE) - file_type = NT_SUCCESS (status) ? virt_pipe : virt_blk; - else if (NT_SUCCESS (status)) - file_type = (fbi.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ? virt_fsdir : virt_fsfile; - else if (ffdi.DeviceType == FILE_DEVICE_DISK - || ffdi.DeviceType == FILE_DEVICE_CD_ROM - || ffdi.DeviceType == FILE_DEVICE_DFS - || ffdi.DeviceType == FILE_DEVICE_VIRTUAL_DISK) - file_type = virt_blk; - } - } - /* Then check if it's a symlink. */ - status = NtOpenSymbolicLinkObject (&h, READ_CONTROL | SYMBOLIC_LINK_QUERY, - &attr); - if (NT_SUCCESS (status)) - { - /* If requested, check permissions. */ - if (buf) - get_object_attribute (h, &buf->st_uid, &buf->st_gid, &buf->st_mode); - NtClose (h); - return virt_symlink; - } - /* Eventually, test if it's an object directory. */ - status = NtOpenDirectoryObject (&h, READ_CONTROL | DIRECTORY_QUERY, &attr); - if (NT_SUCCESS (status)) - { - /* If requested, check permissions. */ - if (buf) - get_object_attribute (h, &buf->st_uid, &buf->st_gid, &buf->st_mode); - NtClose (h); - return virt_directory; - } - else if (status == STATUS_ACCESS_DENIED) - return virt_directory; - /* That's it. Return type we found above. */ - return file_type; -} - -virtual_ftype_t -fhandler_procsys::exists () -{ - return exists (NULL); -} - -fhandler_procsys::fhandler_procsys (): - fhandler_virtual () -{ -} - -bool -fhandler_procsys::fill_filebuf () -{ - char *fnamep; - UNICODE_STRING path, target; - OBJECT_ATTRIBUTES attr; - NTSTATUS status; - HANDLE h; - tmp_pathbuf tp; - - mk_unicode_path (&path); - if (path.Buffer[path.Length / sizeof (WCHAR) - 1] == L'\\') - path.Length -= sizeof (WCHAR); - InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL); - status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, &attr); - if (!NT_SUCCESS (status)) - return false; - RtlInitEmptyUnicodeString (&target, tp.w_get (), - (NT_MAX_PATH - 1) * sizeof (WCHAR)); - status = NtQuerySymbolicLinkObject (h, &target, NULL); - NtClose (h); - if (!NT_SUCCESS (status)) - return false; - size_t len = sys_wcstombs (NULL, 0, target.Buffer, - target.Length / sizeof (WCHAR)); - filebuf = (char *) crealloc_abort (filebuf, procsys_len + len + 1); - sys_wcstombs (fnamep = stpcpy (filebuf, procsys), len + 1, target.Buffer, - target.Length / sizeof (WCHAR)); - while ((fnamep = strchr (fnamep, '\\'))) - *fnamep = '/'; - return true; -} - -int -fhandler_procsys::fstat (struct __stat64 *buf) -{ - const char *path = get_name (); - debug_printf ("fstat (%s)", path); - - fhandler_base::fstat (buf); - /* Best bet. */ - buf->st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; - buf->st_uid = 544; - buf->st_gid = 18; - buf->st_dev = buf->st_rdev = dev ().devn; - buf->st_ino = get_ino (); - switch (exists (buf)) - { - case virt_directory: - case virt_rootdir: - case virt_fsdir: - buf->st_mode |= S_IFDIR; - if (buf->st_mode & S_IRUSR) - buf->st_mode |= S_IXUSR; - if (buf->st_mode & S_IRGRP) - buf->st_mode |= S_IXGRP; - if (buf->st_mode & S_IROTH) - buf->st_mode |= S_IXOTH; - break; - case virt_file: - case virt_fsfile: - buf->st_mode |= S_IFREG; - break; - case virt_symlink: - buf->st_mode |= S_IFLNK; - break; - case virt_pipe: - buf->st_mode |= S_IFIFO; - break; - case virt_socket: - buf->st_mode |= S_IFSOCK; - break; - case virt_chr: - buf->st_mode |= S_IFCHR; - break; - case virt_blk: - buf->st_mode |= S_IFBLK; - break; - default: - set_errno (ENOENT); - return -1; - } - return 0; -} - -DIR * -fhandler_procsys::opendir (int fd) -{ - UNICODE_STRING path; - OBJECT_ATTRIBUTES attr; - NTSTATUS status; - HANDLE h; - DIR *dir = fhandler_virtual::opendir (fd); - - mk_unicode_path (&path); - InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL); - status = NtOpenDirectoryObject (&h, DIRECTORY_QUERY, &attr); - if (!NT_SUCCESS (status)) - { - free (dir); - __seterrno_from_nt_status (status); - return NULL; - } - dir->__handle = h; - return dir; -} - -int -fhandler_procsys::readdir (DIR *dir, dirent *de) -{ - NTSTATUS status; - struct fdbi - { - DIRECTORY_BASIC_INFORMATION dbi; - WCHAR buf[2][NAME_MAX + 1]; - } f; - int res = EBADF; - - if (dir->__handle != INVALID_HANDLE_VALUE) - { - BOOLEAN restart = dir->__d_position ? FALSE : TRUE; - status = NtQueryDirectoryObject (dir->__handle, &f, sizeof f, TRUE, - restart, (PULONG) &dir->__d_position, - NULL); - if (!NT_SUCCESS (status)) - res = ENMFILE; - else - { - sys_wcstombs (de->d_name, NAME_MAX + 1, f.dbi.ObjectName.Buffer, - f.dbi.ObjectName.Length / sizeof (WCHAR)); - de->d_ino = hash_path_name (get_ino (), de->d_name); - de->d_type = 0; - res = 0; - } - } - syscall_printf ("%d = readdir (%p, %p)", res, dir, de); - return res; -} - -long -fhandler_procsys::telldir (DIR *dir) -{ - return dir->__d_position; -} - -void -fhandler_procsys::seekdir (DIR *dir, long pos) -{ - dir->__d_position = pos; -} - -int -fhandler_procsys::closedir (DIR *dir) -{ - if (dir->__handle != INVALID_HANDLE_VALUE) - { - NtClose (dir->__handle); - dir->__handle = INVALID_HANDLE_VALUE; - } - return fhandler_virtual::closedir (dir); -} - -void __stdcall -fhandler_procsys::read (void *ptr, size_t& len) -{ - NTSTATUS status; - IO_STATUS_BLOCK io; - LARGE_INTEGER off = { QuadPart:0LL }; - - status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr, len, - &off, NULL); - if (!NT_SUCCESS (status)) - { - __seterrno_from_nt_status (status); - len = -1; - } - else - len = io.Information; -} - -ssize_t __stdcall -fhandler_procsys::write (const void *ptr, size_t len) -{ - return fhandler_base::raw_write (ptr, len); -} - -int -fhandler_procsys::open (int flags, mode_t mode) -{ - int res = 0; - - if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) - set_errno (EINVAL); - else - { - switch (exists ()) - { - case virt_directory: - case virt_rootdir: - if ((flags & O_ACCMODE) != O_RDONLY) - set_errno (EISDIR); - else - { - nohandle (true); - res = 1; - } - break; - case virt_none: - set_errno (ENOENT); - break; - default: - res = fhandler_base::open (flags, mode); - break; - } - } - syscall_printf ("%d = fhandler_procsys::open (%p, %d)", res, flags, mode); - return res; -} - -int -fhandler_procsys::close () -{ - if (!nohandle ()) - NtClose (get_handle ()); - return fhandler_virtual::close (); -} -#if 0 -int -fhandler_procsys::ioctl (unsigned int cmd, void *) -{ -} -#endif |