* 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:
parent
0de488378f
commit
43f65cdd7d
|
@ -1,3 +1,69 @@
|
||||||
|
2010-09-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2010-09-04 Corinna Vinschen <corinna@vinschen.de>
|
2010-09-04 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* mount.cc (mount_info::from_fstab_line): Reorder to make sure all
|
* mount.cc (mount_info::from_fstab_line): Reorder to make sure all
|
||||||
|
|
|
@ -141,13 +141,14 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \
|
||||||
fhandler.o fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \
|
fhandler.o fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \
|
||||||
fhandler_dsp.o fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o \
|
fhandler_dsp.o fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o \
|
||||||
fhandler_mem.o fhandler_netdrive.o fhandler_nodevice.o fhandler_proc.o \
|
fhandler_mem.o fhandler_netdrive.o fhandler_nodevice.o fhandler_proc.o \
|
||||||
fhandler_process.o fhandler_procnet.o fhandler_random.o fhandler_raw.o \
|
fhandler_process.o fhandler_procnet.o fhandler_procsys.o fhandler_random.o \
|
||||||
fhandler_registry.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
|
fhandler_raw.o fhandler_registry.o fhandler_serial.o fhandler_socket.o \
|
||||||
fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
|
fhandler_tape.o fhandler_termios.o fhandler_tty.o fhandler_virtual.o \
|
||||||
fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
|
fhandler_windows.o fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o \
|
||||||
glob_pattern_p.o globals.o grp.o heap.o hookapi.o inet_addr.o inet_network.o \
|
getopt.o glob.o glob_pattern_p.o globals.o grp.o heap.o hookapi.o \
|
||||||
init.o ioctl.o ipc.o kernel32.o libstdcxx_wrapper.o localtime.o lsearch.o \
|
inet_addr.o inet_network.o init.o ioctl.o ipc.o kernel32.o \
|
||||||
malloc_wrapper.o minires-os-if.o minires.o miscfuncs.o mktemp.o mmap.o msg.o \
|
libstdcxx_wrapper.o localtime.o lsearch.o malloc_wrapper.o \
|
||||||
|
minires-os-if.o minires.o miscfuncs.o mktemp.o mmap.o msg.o \
|
||||||
mount.o net.o netdb.o nfs.o nftw.o nlsfuncs.o ntea.o passwd.o path.o \
|
mount.o net.o netdb.o nfs.o nftw.o nlsfuncs.o ntea.o passwd.o path.o \
|
||||||
pinfo.o pipe.o poll.o posix_ipc.o pseudo-reloc.o pthread.o random.o \
|
pinfo.o pipe.o poll.o posix_ipc.o pseudo-reloc.o pthread.o random.o \
|
||||||
regcomp.o regerror.o regexec.o regfree.o registry.o resource.o rexec.o \
|
regcomp.o regerror.o regexec.o regfree.o registry.o resource.o rexec.o \
|
||||||
|
|
|
@ -24,6 +24,9 @@ const device dev_proc_storage =
|
||||||
const device dev_procnet_storage =
|
const device dev_procnet_storage =
|
||||||
{"", {FH_PROCNET}, ""};
|
{"", {FH_PROCNET}, ""};
|
||||||
|
|
||||||
|
const device dev_procsys_storage =
|
||||||
|
{"", {FH_PROCSYS}, ""};
|
||||||
|
|
||||||
const device dev_netdrive_storage =
|
const device dev_netdrive_storage =
|
||||||
{"", {FH_NETDRIVE}, ""};
|
{"", {FH_NETDRIVE}, ""};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* devices.h
|
/* devices.h
|
||||||
|
|
||||||
Copyright 2002, 2003, 2004, 2005 Red Hat, Inc.
|
Copyright 2002, 2003, 2004, 2005, 2007, 2009, 2010 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ enum fh_devices
|
||||||
FH_DEV = FHDEV (0, 245),
|
FH_DEV = FHDEV (0, 245),
|
||||||
FH_PROCNET = FHDEV (0, 244),
|
FH_PROCNET = FHDEV (0, 244),
|
||||||
FH_PROCESSFD = FHDEV (0, 243),
|
FH_PROCESSFD = FHDEV (0, 243),
|
||||||
|
FH_PROCSYS = FHDEV (0, 242),
|
||||||
|
|
||||||
DEV_FLOPPY_MAJOR = 2,
|
DEV_FLOPPY_MAJOR = 2,
|
||||||
FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0),
|
FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0),
|
||||||
|
|
|
@ -20,6 +20,9 @@ const device dev_proc_storage =
|
||||||
const device dev_procnet_storage =
|
const device dev_procnet_storage =
|
||||||
{"", {FH_PROCNET}, ""};
|
{"", {FH_PROCNET}, ""};
|
||||||
|
|
||||||
|
const device dev_procsys_storage =
|
||||||
|
{"", {FH_PROCSYS}, ""};
|
||||||
|
|
||||||
const device dev_netdrive_storage =
|
const device dev_netdrive_storage =
|
||||||
{"", {FH_NETDRIVE}, ""};
|
{"", {FH_NETDRIVE}, ""};
|
||||||
|
|
||||||
|
|
|
@ -540,6 +540,9 @@ build_fh_pc (path_conv& pc, bool set_name)
|
||||||
case FH_PROCNET:
|
case FH_PROCNET:
|
||||||
fh = cnew (fhandler_procnet) ();
|
fh = cnew (fhandler_procnet) ();
|
||||||
break;
|
break;
|
||||||
|
case FH_PROCSYS:
|
||||||
|
fh = cnew (fhandler_procsys) ();
|
||||||
|
break;
|
||||||
case FH_NETDRIVE:
|
case FH_NETDRIVE:
|
||||||
fh = cnew (fhandler_netdrive) ();
|
fh = cnew (fhandler_netdrive) ();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -34,7 +34,9 @@ extern const char *windows_device_names[];
|
||||||
extern struct __cygwin_perfile *perfile_table;
|
extern struct __cygwin_perfile *perfile_table;
|
||||||
#define __fmode (*(user_data->fmode_ptr))
|
#define __fmode (*(user_data->fmode_ptr))
|
||||||
extern const char proc[];
|
extern const char proc[];
|
||||||
extern const int proc_len;
|
extern const size_t proc_len;
|
||||||
|
extern const char procsys[];
|
||||||
|
extern const size_t procsys_len;
|
||||||
|
|
||||||
class select_record;
|
class select_record;
|
||||||
class select_stuff;
|
class select_stuff;
|
||||||
|
@ -99,6 +101,20 @@ enum del_lock_called_from {
|
||||||
after_exec
|
after_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum virtual_ftype_t {
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
|
||||||
class fhandler_base
|
class fhandler_base
|
||||||
{
|
{
|
||||||
friend class dtable;
|
friend class dtable;
|
||||||
|
@ -1331,7 +1347,7 @@ class fhandler_virtual : public fhandler_base
|
||||||
fhandler_virtual ();
|
fhandler_virtual ();
|
||||||
virtual ~fhandler_virtual();
|
virtual ~fhandler_virtual();
|
||||||
|
|
||||||
virtual int exists();
|
virtual virtual_ftype_t exists();
|
||||||
DIR *opendir (int fd) __attribute__ ((regparm (2)));
|
DIR *opendir (int fd) __attribute__ ((regparm (2)));
|
||||||
long telldir (DIR *);
|
long telldir (DIR *);
|
||||||
void seekdir (DIR *, long);
|
void seekdir (DIR *, long);
|
||||||
|
@ -1357,7 +1373,7 @@ class fhandler_proc: public fhandler_virtual
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fhandler_proc ();
|
fhandler_proc ();
|
||||||
int exists();
|
virtual_ftype_t exists();
|
||||||
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||||
static DWORD get_proc_fhandler(const char *path);
|
static DWORD get_proc_fhandler(const char *path);
|
||||||
|
|
||||||
|
@ -1366,11 +1382,30 @@ class fhandler_proc: public fhandler_virtual
|
||||||
bool fill_filebuf ();
|
bool fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class fhandler_procsys: public fhandler_virtual
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
fhandler_procsys ();
|
||||||
|
virtual_ftype_t exists(struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
virtual_ftype_t exists();
|
||||||
|
DIR *opendir (int fd) __attribute__ ((regparm (2)));
|
||||||
|
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||||
|
long telldir (DIR *);
|
||||||
|
void seekdir (DIR *, long);
|
||||||
|
int closedir (DIR *);
|
||||||
|
int open (int flags, mode_t mode = 0);
|
||||||
|
int close ();
|
||||||
|
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
|
||||||
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
|
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
bool fill_filebuf ();
|
||||||
|
};
|
||||||
|
|
||||||
class fhandler_netdrive: public fhandler_virtual
|
class fhandler_netdrive: public fhandler_virtual
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fhandler_netdrive ();
|
fhandler_netdrive ();
|
||||||
int exists();
|
virtual_ftype_t exists();
|
||||||
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||||
void seekdir (DIR *, long);
|
void seekdir (DIR *, long);
|
||||||
void rewinddir (DIR *);
|
void rewinddir (DIR *);
|
||||||
|
@ -1388,7 +1423,7 @@ class fhandler_registry: public fhandler_proc
|
||||||
public:
|
public:
|
||||||
fhandler_registry ();
|
fhandler_registry ();
|
||||||
void set_name (path_conv &pc);
|
void set_name (path_conv &pc);
|
||||||
int exists();
|
virtual_ftype_t exists();
|
||||||
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||||
long telldir (DIR *);
|
long telldir (DIR *);
|
||||||
void seekdir (DIR *, long);
|
void seekdir (DIR *, long);
|
||||||
|
@ -1408,7 +1443,7 @@ class fhandler_process: public fhandler_proc
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
public:
|
public:
|
||||||
fhandler_process ();
|
fhandler_process ();
|
||||||
int exists();
|
virtual_ftype_t exists();
|
||||||
DIR *opendir (int fd) __attribute__ ((regparm (2)));
|
DIR *opendir (int fd) __attribute__ ((regparm (2)));
|
||||||
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
|
@ -1421,7 +1456,7 @@ class fhandler_procnet: public fhandler_proc
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
public:
|
public:
|
||||||
fhandler_procnet ();
|
fhandler_procnet ();
|
||||||
int exists();
|
virtual_ftype_t exists();
|
||||||
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
@ -1462,6 +1497,8 @@ typedef union
|
||||||
char __pipe[sizeof (fhandler_pipe)];
|
char __pipe[sizeof (fhandler_pipe)];
|
||||||
char __proc[sizeof (fhandler_proc)];
|
char __proc[sizeof (fhandler_proc)];
|
||||||
char __process[sizeof (fhandler_process)];
|
char __process[sizeof (fhandler_process)];
|
||||||
|
char __procnet[sizeof (fhandler_procnet)];
|
||||||
|
char __procsys[sizeof (fhandler_procsys)];
|
||||||
char __pty_master[sizeof (fhandler_pty_master)];
|
char __pty_master[sizeof (fhandler_pty_master)];
|
||||||
char __registry[sizeof (fhandler_registry)];
|
char __registry[sizeof (fhandler_registry)];
|
||||||
char __serial[sizeof (fhandler_serial)];
|
char __serial[sizeof (fhandler_serial)];
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
{
|
{
|
||||||
found[__DIR_PROC] = true;
|
found[__DIR_PROC] = true;
|
||||||
if (retname)
|
if (retname)
|
||||||
RtlInitUnicodeString (retname, L"proc");
|
*retname = ro_u_proc;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (!found[__DIR_CYGDRIVE])
|
if (!found[__DIR_CYGDRIVE])
|
||||||
|
@ -407,7 +407,9 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
||||||
entry, as in other calls to fstat_helper. */
|
entry, as in other calls to fstat_helper. */
|
||||||
if (pc.is_rep_symlink ())
|
if (pc.is_rep_symlink ())
|
||||||
fi.fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
fi.fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||||
pc.file_attributes (fi.fbi.FileAttributes);
|
/* Only copy attributes if not a device root dir. */
|
||||||
|
if (!(pc.file_attributes () & FILE_ATTRIBUTE_DEVICE))
|
||||||
|
pc.file_attributes (fi.fbi.FileAttributes);
|
||||||
return fstat_helper (buf,
|
return fstat_helper (buf,
|
||||||
fi.fbi.ChangeTime.QuadPart ? &fi.fbi.ChangeTime
|
fi.fbi.ChangeTime.QuadPart ? &fi.fbi.ChangeTime
|
||||||
: &fi.fbi.LastWriteTime,
|
: &fi.fbi.LastWriteTime,
|
||||||
|
@ -474,7 +476,9 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
||||||
entry, as in other calls to fstat_helper. */
|
entry, as in other calls to fstat_helper. */
|
||||||
if (pc.is_rep_symlink ())
|
if (pc.is_rep_symlink ())
|
||||||
fdi_buf.fdi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
fdi_buf.fdi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||||
pc.file_attributes (fdi_buf.fdi.FileAttributes);
|
/* Only copy attributes if not a device root dir. */
|
||||||
|
if (!(pc.file_attributes () & FILE_ATTRIBUTE_DEVICE))
|
||||||
|
pc.file_attributes (fdi_buf.fdi.FileAttributes);
|
||||||
return fstat_helper (buf,
|
return fstat_helper (buf,
|
||||||
fdi_buf.fdi.ChangeTime.QuadPart
|
fdi_buf.fdi.ChangeTime.QuadPart
|
||||||
? &fdi_buf.fdi.ChangeTime : &fdi_buf.fdi.LastWriteTime,
|
? &fdi_buf.fdi.ChangeTime : &fdi_buf.fdi.LastWriteTime,
|
||||||
|
|
|
@ -145,14 +145,14 @@ create_thread_and_wait (int what, PVOID in, PVOID out, DWORD outsize,
|
||||||
|
|
||||||
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
/* 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. */
|
-1 if path is a file, -2 if it's a symlink. */
|
||||||
int
|
virtual_ftype_t
|
||||||
fhandler_netdrive::exists ()
|
fhandler_netdrive::exists ()
|
||||||
{
|
{
|
||||||
char *to;
|
char *to;
|
||||||
const char *from;
|
const char *from;
|
||||||
size_t len = strlen (get_name ());
|
size_t len = strlen (get_name ());
|
||||||
if (len == 2)
|
if (len == 2)
|
||||||
return 1;
|
return virt_rootdir;
|
||||||
char namebuf[len + 1];
|
char namebuf[len + 1];
|
||||||
for (to = namebuf, from = get_name (); *from; to++, from++)
|
for (to = namebuf, from = get_name (); *from; to++, from++)
|
||||||
*to = (*from == '/') ? '\\' : *from;
|
*to = (*from == '/') ? '\\' : *from;
|
||||||
|
@ -166,7 +166,7 @@ fhandler_netdrive::exists ()
|
||||||
&nr, &nh, 0, "WNetOpenEnum");
|
&nr, &nh, 0, "WNetOpenEnum");
|
||||||
if (nh.dom)
|
if (nh.dom)
|
||||||
WNetCloseEnum (nh.dom);
|
WNetCloseEnum (nh.dom);
|
||||||
return ret != NO_ERROR ? 0 : 1;
|
return ret != NO_ERROR ? virt_none : virt_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
fhandler_netdrive::fhandler_netdrive ():
|
fhandler_netdrive::fhandler_netdrive ():
|
||||||
|
|
|
@ -46,23 +46,24 @@ static _off64_t format_proc_filesystems (void *, char *&);
|
||||||
|
|
||||||
/* names of objects in /proc */
|
/* names of objects in /proc */
|
||||||
static const virt_tab_t proc_tab[] = {
|
static const virt_tab_t proc_tab[] = {
|
||||||
{ ".", FH_PROC, virt_directory, NULL },
|
{ _VN ("."), FH_PROC, virt_directory, NULL },
|
||||||
{ "..", FH_PROC, virt_directory, NULL },
|
{ _VN (".."), FH_PROC, virt_directory, NULL },
|
||||||
{ "loadavg", FH_PROC, virt_file, format_proc_loadavg },
|
{ _VN ("cpuinfo"), FH_PROC, virt_file, format_proc_cpuinfo },
|
||||||
{ "meminfo", FH_PROC, virt_file, format_proc_meminfo },
|
{ _VN ("filesystems"), FH_PROC, virt_file, format_proc_filesystems },
|
||||||
{ "registry", FH_REGISTRY, virt_directory, NULL },
|
{ _VN ("loadavg"), FH_PROC, virt_file, format_proc_loadavg },
|
||||||
{ "stat", FH_PROC, virt_file, format_proc_stat },
|
{ _VN ("meminfo"), FH_PROC, virt_file, format_proc_meminfo },
|
||||||
{ "version", FH_PROC, virt_file, format_proc_version },
|
{ _VN ("mounts"), FH_PROC, virt_symlink, format_proc_mounts },
|
||||||
{ "uptime", FH_PROC, virt_file, format_proc_uptime },
|
{ _VN ("net"), FH_PROCNET, virt_directory, NULL },
|
||||||
{ "cpuinfo", FH_PROC, virt_file, format_proc_cpuinfo },
|
{ _VN ("partitions"), FH_PROC, virt_file, format_proc_partitions },
|
||||||
{ "partitions", FH_PROC, virt_file, format_proc_partitions },
|
{ _VN ("registry"), FH_REGISTRY, virt_directory, NULL },
|
||||||
{ "self", FH_PROC, virt_symlink, format_proc_self },
|
{ _VN ("registry32"), FH_REGISTRY, virt_directory, NULL },
|
||||||
{ "mounts", FH_PROC, virt_symlink, format_proc_mounts },
|
{ _VN ("registry64"), FH_REGISTRY, virt_directory, NULL },
|
||||||
{ "registry32", FH_REGISTRY, virt_directory, NULL },
|
{ _VN ("self"), FH_PROC, virt_symlink, format_proc_self },
|
||||||
{ "registry64", FH_REGISTRY, virt_directory, NULL },
|
{ _VN ("stat"), FH_PROC, virt_file, format_proc_stat },
|
||||||
{ "net", FH_PROCNET, virt_directory, NULL },
|
{ _VN ("sys"), FH_PROCSYS, virt_directory, NULL },
|
||||||
{ "filesystems", FH_PROC, virt_file, format_proc_filesystems },
|
{ _VN ("uptime"), FH_PROC, virt_file, format_proc_uptime },
|
||||||
{ NULL, 0, virt_none, NULL }
|
{ _VN ("version"), FH_PROC, virt_file, format_proc_version },
|
||||||
|
{ NULL, 0, 0, virt_none, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PROC_DIR_COUNT 4
|
#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 */
|
/* name of the /proc filesystem */
|
||||||
const char proc[] = "/proc";
|
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
|
/* bsearch compare function. */
|
||||||
this is where it would be nice to have pattern matching in C - polymorphism
|
static int
|
||||||
just doesn't cut it. */
|
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
|
DWORD
|
||||||
fhandler_proc::get_proc_fhandler (const char *path)
|
fhandler_proc::get_proc_fhandler (const char *path)
|
||||||
{
|
{
|
||||||
|
@ -91,12 +118,10 @@ fhandler_proc::get_proc_fhandler (const char *path)
|
||||||
if (*path == 0)
|
if (*path == 0)
|
||||||
return FH_PROC;
|
return FH_PROC;
|
||||||
|
|
||||||
for (int i = 0; proc_tab[i].name; i++)
|
virt_tab_t *entry = virt_tab_search (path, true, proc_tab,
|
||||||
{
|
PROC_LINK_COUNT);
|
||||||
if (path_prefix_p (proc_tab[i].name, path, strlen (proc_tab[i].name),
|
if (entry)
|
||||||
false))
|
return entry->fhandler;
|
||||||
return proc_tab[i].fhandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pinfo (atoi (path)))
|
if (pinfo (atoi (path)))
|
||||||
return FH_PROCESS;
|
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,
|
/* 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. */
|
-1 if path is a file, -2 if it's a symlink. */
|
||||||
int
|
virtual_ftype_t
|
||||||
fhandler_proc::exists ()
|
fhandler_proc::exists ()
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
|
@ -128,12 +153,13 @@ fhandler_proc::exists ()
|
||||||
path += proc_len;
|
path += proc_len;
|
||||||
if (*path == 0)
|
if (*path == 0)
|
||||||
return virt_rootdir;
|
return virt_rootdir;
|
||||||
for (int i = 0; proc_tab[i].name; i++)
|
virt_tab_t *entry = virt_tab_search (path + 1, false, proc_tab,
|
||||||
if (!strcmp (path + 1, proc_tab[i].name))
|
PROC_LINK_COUNT);
|
||||||
{
|
if (entry)
|
||||||
fileid = i;
|
{
|
||||||
return proc_tab[i].type;
|
fileid = entry - proc_tab;
|
||||||
}
|
return entry->type;
|
||||||
|
}
|
||||||
return virt_none;
|
return virt_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,21 +189,21 @@ fhandler_proc::fstat (struct __stat64 *buf)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
path++;
|
virt_tab_t *entry = virt_tab_search (path + 1, false, proc_tab,
|
||||||
for (int i = 0; proc_tab[i].name; i++)
|
PROC_LINK_COUNT);
|
||||||
if (!strcmp (path, proc_tab[i].name))
|
if (entry)
|
||||||
{
|
{
|
||||||
if (proc_tab[i].type == virt_directory)
|
if (entry->type == virt_directory)
|
||||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
else if (proc_tab[i].type == virt_symlink)
|
else if (entry->type == virt_symlink)
|
||||||
buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
|
buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->st_mode &= NO_X;
|
buf->st_mode &= NO_X;
|
||||||
buf->st_mode |= S_IFREG;
|
buf->st_mode |= S_IFREG;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -53,28 +53,28 @@ static _off64_t format_process_mounts (void *, char *&);
|
||||||
|
|
||||||
static const virt_tab_t process_tab[] =
|
static const virt_tab_t process_tab[] =
|
||||||
{
|
{
|
||||||
{ ".", FH_PROCESS, virt_directory, NULL },
|
{ _VN ("."), FH_PROCESS, virt_directory, NULL },
|
||||||
{ "..", FH_PROCESS, virt_directory, NULL },
|
{ _VN (".."), FH_PROCESS, virt_directory, NULL },
|
||||||
{ "ppid", FH_PROCESS, virt_file, format_process_ppid },
|
{ _VN ("cmdline"), FH_PROCESS, virt_file, format_process_cmdline },
|
||||||
{ "winpid", FH_PROCESS, virt_file, format_process_winpid },
|
{ _VN ("ctty"), FH_PROCESS, virt_file, format_process_ctty },
|
||||||
{ "winexename", FH_PROCESS, virt_file, format_process_winexename },
|
{ _VN ("cwd"), FH_PROCESS, virt_symlink, format_process_cwd },
|
||||||
{ "status", FH_PROCESS, virt_file, format_process_status },
|
{ _VN ("exe"), FH_PROCESS, virt_symlink, format_process_exename },
|
||||||
{ "uid", FH_PROCESS, virt_file, format_process_uid },
|
{ _VN ("exename"), FH_PROCESS, virt_file, format_process_exename },
|
||||||
{ "gid", FH_PROCESS, virt_file, format_process_gid },
|
{ _VN ("fd"), FH_PROCESSFD, virt_directory, format_process_fd },
|
||||||
{ "pgid", FH_PROCESS, virt_file, format_process_pgid },
|
{ _VN ("gid"), FH_PROCESS, virt_file, format_process_gid },
|
||||||
{ "sid", FH_PROCESS, virt_file, format_process_sid },
|
{ _VN ("maps"), FH_PROCESS, virt_file, format_process_maps },
|
||||||
{ "ctty", FH_PROCESS, virt_file, format_process_ctty },
|
{ _VN ("mounts"), FH_PROCESS, virt_file, format_process_mounts },
|
||||||
{ "stat", FH_PROCESS, virt_file, format_process_stat },
|
{ _VN ("pgid"), FH_PROCESS, virt_file, format_process_pgid },
|
||||||
{ "statm", FH_PROCESS, virt_file, format_process_statm },
|
{ _VN ("ppid"), FH_PROCESS, virt_file, format_process_ppid },
|
||||||
{ "cmdline", FH_PROCESS, virt_file, format_process_cmdline },
|
{ _VN ("root"), FH_PROCESS, virt_symlink, format_process_root },
|
||||||
{ "maps", FH_PROCESS, virt_file, format_process_maps },
|
{ _VN ("sid"), FH_PROCESS, virt_file, format_process_sid },
|
||||||
{ "fd", FH_PROCESSFD, virt_directory, format_process_fd },
|
{ _VN ("stat"), FH_PROCESS, virt_file, format_process_stat },
|
||||||
{ "exename", FH_PROCESS, virt_file, format_process_exename },
|
{ _VN ("statm"), FH_PROCESS, virt_file, format_process_statm },
|
||||||
{ "root", FH_PROCESS, virt_symlink, format_process_root },
|
{ _VN ("status"), FH_PROCESS, virt_file, format_process_status },
|
||||||
{ "exe", FH_PROCESS, virt_symlink, format_process_exename },
|
{ _VN ("uid"), FH_PROCESS, virt_file, format_process_uid },
|
||||||
{ "cwd", FH_PROCESS, virt_symlink, format_process_cwd },
|
{ _VN ("winexename"), FH_PROCESS, virt_file, format_process_winexename },
|
||||||
{ "mounts", FH_PROCESS, virt_file, format_process_mounts },
|
{ _VN ("winpid"), FH_PROCESS, virt_file, format_process_winpid },
|
||||||
{ NULL, 0, virt_none, NULL }
|
{ NULL, 0, 0, virt_none, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int PROCESS_LINK_COUNT =
|
static const int PROCESS_LINK_COUNT =
|
||||||
|
@ -90,7 +90,7 @@ static bool get_mem_values (DWORD dwProcessId, unsigned long *vmsize,
|
||||||
* -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe,
|
* -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe,
|
||||||
* -4 if path is a socket.
|
* -4 if path is a socket.
|
||||||
*/
|
*/
|
||||||
int
|
virtual_ftype_t
|
||||||
fhandler_process::exists ()
|
fhandler_process::exists ()
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
|
@ -99,21 +99,20 @@ fhandler_process::exists ()
|
||||||
while (*path != 0 && !isdirsep (*path))
|
while (*path != 0 && !isdirsep (*path))
|
||||||
path++;
|
path++;
|
||||||
if (*path == 0)
|
if (*path == 0)
|
||||||
return 2;
|
return virt_rootdir;
|
||||||
|
|
||||||
for (int i = 0; process_tab[i].name; i++)
|
virt_tab_t *entry = virt_tab_search (path + 1, true, process_tab,
|
||||||
|
PROCESS_LINK_COUNT);
|
||||||
|
if (entry)
|
||||||
{
|
{
|
||||||
if (!strcmp (path + 1, process_tab[i].name))
|
if (!path[entry->name_len + 1])
|
||||||
{
|
{
|
||||||
fileid = i;
|
fileid = entry - process_tab;
|
||||||
return process_tab[i].type;
|
return entry->type;
|
||||||
}
|
}
|
||||||
if (process_tab[i].type == virt_directory
|
if (entry->type == virt_directory)
|
||||||
&& !strncmp (path + 1, process_tab[i].name,
|
|
||||||
strlen (process_tab[i].name))
|
|
||||||
&& path[1 + strlen (process_tab[i].name)] == '/')
|
|
||||||
{
|
{
|
||||||
fileid = i;
|
fileid = entry - process_tab;
|
||||||
if (fill_filebuf ())
|
if (fill_filebuf ())
|
||||||
return virt_symlink;
|
return virt_symlink;
|
||||||
/* Check for nameless device entries. */
|
/* Check for nameless device entries. */
|
||||||
|
@ -232,8 +231,6 @@ out:
|
||||||
int
|
int
|
||||||
fhandler_process::open (int flags, mode_t mode)
|
fhandler_process::open (int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
int process_file_no = -1;
|
|
||||||
|
|
||||||
int res = fhandler_virtual::open (flags, mode);
|
int res = fhandler_virtual::open (flags, mode);
|
||||||
if (!res)
|
if (!res)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -267,29 +264,15 @@ fhandler_process::open (int flags, mode_t mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_file_no = -1;
|
virt_tab_t *entry;
|
||||||
for (int i = 0; process_tab[i].name; i++)
|
entry = virt_tab_search (path + 1, true, process_tab, PROCESS_LINK_COUNT);
|
||||||
|
if (!entry)
|
||||||
{
|
{
|
||||||
if (path_prefix_p (process_tab[i].name, path + 1,
|
set_errno ((flags & O_CREAT) ? EROFS : ENOENT);
|
||||||
strlen (process_tab[i].name), false))
|
res = 0;
|
||||||
process_file_no = i;
|
goto out;
|
||||||
}
|
}
|
||||||
if (process_file_no == -1)
|
if (entry->fhandler == FH_PROCESSFD)
|
||||||
{
|
|
||||||
if (flags & O_CREAT)
|
|
||||||
{
|
|
||||||
set_errno (EROFS);
|
|
||||||
res = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set_errno (ENOENT);
|
|
||||||
res = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (process_tab[process_file_no].fhandler == FH_PROCESSFD)
|
|
||||||
{
|
{
|
||||||
flags |= O_DIROPEN;
|
flags |= O_DIROPEN;
|
||||||
goto success;
|
goto success;
|
||||||
|
@ -301,7 +284,7 @@ fhandler_process::open (int flags, mode_t mode)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileid = process_file_no;
|
fileid = entry - process_tab;
|
||||||
if (!fill_filebuf ())
|
if (!fill_filebuf ())
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
|
@ -39,10 +39,10 @@ static _off64_t format_procnet_ifinet6 (void *, char *&);
|
||||||
|
|
||||||
static const virt_tab_t procnet_tab[] =
|
static const virt_tab_t procnet_tab[] =
|
||||||
{
|
{
|
||||||
{ ".", FH_PROCNET, virt_directory, NULL },
|
{ _VN ("."), FH_PROCNET, virt_directory, NULL },
|
||||||
{ "..", FH_PROCNET, virt_directory, NULL },
|
{ _VN (".."), FH_PROCNET, virt_directory, NULL },
|
||||||
{ "if_inet6", FH_PROCNET, virt_file, format_procnet_ifinet6 },
|
{ _VN ("if_inet6"), FH_PROCNET, virt_file, format_procnet_ifinet6 },
|
||||||
{ NULL, 0, virt_none, NULL }
|
{ NULL, 0, 0, virt_none, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int PROCNET_LINK_COUNT =
|
static const int PROCNET_LINK_COUNT =
|
||||||
|
@ -52,7 +52,7 @@ static const int PROCNET_LINK_COUNT =
|
||||||
* -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe,
|
* -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe,
|
||||||
* -4 if path is a socket.
|
* -4 if path is a socket.
|
||||||
*/
|
*/
|
||||||
int
|
virtual_ftype_t
|
||||||
fhandler_procnet::exists ()
|
fhandler_procnet::exists ()
|
||||||
{
|
{
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
|
@ -61,20 +61,21 @@ fhandler_procnet::exists ()
|
||||||
while (*path != 0 && !isdirsep (*path))
|
while (*path != 0 && !isdirsep (*path))
|
||||||
path++;
|
path++;
|
||||||
if (*path == 0)
|
if (*path == 0)
|
||||||
return 1;
|
return virt_rootdir;
|
||||||
|
|
||||||
for (int i = 0; procnet_tab[i].name; i++)
|
virt_tab_t *entry = virt_tab_search (path + 1, false, procnet_tab,
|
||||||
if (!strcmp (path + 1, procnet_tab[i].name))
|
PROCNET_LINK_COUNT);
|
||||||
{
|
if (entry)
|
||||||
if (procnet_tab[i].type == virt_file)
|
{
|
||||||
{
|
if (entry->type == virt_file)
|
||||||
if (!wincap.has_gaa_prefixes ()
|
{
|
||||||
|| !get_adapters_addresses (NULL, AF_INET6))
|
if (!wincap.has_gaa_prefixes ()
|
||||||
return virt_none;
|
|| !get_adapters_addresses (NULL, AF_INET6))
|
||||||
}
|
return virt_none;
|
||||||
fileid = i;
|
}
|
||||||
return procnet_tab[i].type;
|
fileid = entry - procnet_tab;
|
||||||
}
|
return entry->type;
|
||||||
|
}
|
||||||
return virt_none;
|
return virt_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +130,6 @@ out:
|
||||||
int
|
int
|
||||||
fhandler_procnet::open (int flags, mode_t mode)
|
fhandler_procnet::open (int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
int process_file_no = -1;
|
|
||||||
|
|
||||||
int res = fhandler_virtual::open (flags, mode);
|
int res = fhandler_virtual::open (flags, mode);
|
||||||
if (!res)
|
if (!res)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -163,27 +162,13 @@ fhandler_procnet::open (int flags, mode_t mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_file_no = -1;
|
virt_tab_t *entry;
|
||||||
for (int i = 0; procnet_tab[i].name; i++)
|
entry = virt_tab_search (path + 1, true, procnet_tab, PROCNET_LINK_COUNT);
|
||||||
|
if (!entry)
|
||||||
{
|
{
|
||||||
if (path_prefix_p (procnet_tab[i].name, path + 1,
|
set_errno ((flags & O_CREAT) ? EROFS : ENOENT);
|
||||||
strlen (procnet_tab[i].name), false))
|
res = 0;
|
||||||
process_file_no = i;
|
goto out;
|
||||||
}
|
|
||||||
if (process_file_no == -1)
|
|
||||||
{
|
|
||||||
if (flags & O_CREAT)
|
|
||||||
{
|
|
||||||
set_errno (EROFS);
|
|
||||||
res = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
set_errno (ENOENT);
|
|
||||||
res = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (flags & O_WRONLY)
|
if (flags & O_WRONLY)
|
||||||
{
|
{
|
||||||
|
@ -192,7 +177,7 @@ fhandler_procnet::open (int flags, mode_t mode)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileid = process_file_no;
|
fileid = entry - procnet_tab;
|
||||||
if (!fill_filebuf ())
|
if (!fill_filebuf ())
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
|
@ -0,0 +1,422 @@
|
||||||
|
/* 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;
|
||||||
|
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_PATH_NOT_FOUND)
|
||||||
|
return virt_none;
|
||||||
|
/* If the name isn't found, or we get this dreaded sharing violation, let
|
||||||
|
the caller try again as normal file. */
|
||||||
|
if (status == STATUS_OBJECT_NAME_NOT_FOUND
|
||||||
|
|| status == STATUS_NO_MEDIA_IN_DEVICE
|
||||||
|
|| status == STATUS_SHARING_VIOLATION)
|
||||||
|
return virt_fsfile; /* Just try again as normal file. */
|
||||||
|
/* Check for pipe errors, which make a good hint... */
|
||||||
|
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;
|
||||||
|
/* Give up. Just treat as character device. */
|
||||||
|
return file_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual_ftype_t
|
||||||
|
fhandler_procsys::exists ()
|
||||||
|
{
|
||||||
|
return exists (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_procsys::fhandler_procsys ():
|
||||||
|
fhandler_virtual ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fhandler_procsys::fill_filebuf ()
|
||||||
|
{
|
||||||
|
/* The NT device namespace is ASCII only. */
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
UNICODE_STRING path;
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE h;
|
||||||
|
ULONG access;
|
||||||
|
ULONG options = FILE_OPEN_FOR_BACKUP_INTENT;
|
||||||
|
|
||||||
|
|
||||||
|
int res = fhandler_virtual::open (flags, mode);
|
||||||
|
if (!res)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) || (flags & O_TRUNC))
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
mk_unicode_path (&path);
|
||||||
|
InitializeObjectAttributes (&attr, &path, OBJ_INHERIT | OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL, NULL);
|
||||||
|
switch (exists ())
|
||||||
|
{
|
||||||
|
case virt_directory:
|
||||||
|
case virt_rootdir:
|
||||||
|
if ((flags & O_ACCMODE) != O_RDONLY)
|
||||||
|
{
|
||||||
|
set_errno (EISDIR);
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
nohandle (true);
|
||||||
|
res = 1;
|
||||||
|
goto out;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((flags & O_ACCMODE) == O_RDONLY)
|
||||||
|
access = GENERIC_READ;
|
||||||
|
else if ((flags & O_ACCMODE) == O_WRONLY)
|
||||||
|
access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
|
||||||
|
else
|
||||||
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
|
if (flags & O_SYNC)
|
||||||
|
options |= FILE_WRITE_THROUGH;
|
||||||
|
if (flags & O_DIRECT)
|
||||||
|
options |= FILE_NO_INTERMEDIATE_BUFFERING;
|
||||||
|
if (!(flags & O_NONBLOCK))
|
||||||
|
{
|
||||||
|
access |= SYNCHRONIZE;
|
||||||
|
options |= FILE_SYNCHRONOUS_IO_NONALERT;
|
||||||
|
}
|
||||||
|
status = NtOpenFile (&h, access, &attr, &io, FILE_SHARE_VALID_FLAGS, options);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
set_io_handle (h);
|
||||||
|
set_open_status ();
|
||||||
|
res = 1;
|
||||||
|
out:
|
||||||
|
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
|
|
@ -268,10 +268,11 @@ multi_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc)
|
||||||
* final component is there. This gets round the problem of not having security access
|
* final component is there. This gets round the problem of not having security access
|
||||||
* to the final key in the path.
|
* to the final key in the path.
|
||||||
*/
|
*/
|
||||||
int
|
virtual_ftype_t
|
||||||
fhandler_registry::exists ()
|
fhandler_registry::exists ()
|
||||||
{
|
{
|
||||||
int file_type = 0, index = 0, pathlen;
|
virtual_ftype_t file_type = virt_none;
|
||||||
|
int index = 0, pathlen;
|
||||||
DWORD buf_size = NAME_MAX + 1;
|
DWORD buf_size = NAME_MAX + 1;
|
||||||
LONG error;
|
LONG error;
|
||||||
wchar_t buf[buf_size];
|
wchar_t buf[buf_size];
|
||||||
|
@ -285,7 +286,7 @@ fhandler_registry::exists ()
|
||||||
path++;
|
path++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file_type = 2;
|
file_type = virt_rootdir;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
pathlen = strlen (path);
|
pathlen = strlen (path);
|
||||||
|
@ -302,7 +303,7 @@ fhandler_registry::exists ()
|
||||||
if (path_prefix_p (registry_listing[i], path,
|
if (path_prefix_p (registry_listing[i], path,
|
||||||
strlen (registry_listing[i]), true))
|
strlen (registry_listing[i]), true))
|
||||||
{
|
{
|
||||||
file_type = 1;
|
file_type = virt_directory;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,12 +318,12 @@ fhandler_registry::exists ()
|
||||||
if (!val_only)
|
if (!val_only)
|
||||||
hKey = open_key (path, KEY_READ, wow64, false);
|
hKey = open_key (path, KEY_READ, wow64, false);
|
||||||
if (hKey != (HKEY) INVALID_HANDLE_VALUE || get_errno () == EACCES)
|
if (hKey != (HKEY) INVALID_HANDLE_VALUE || get_errno () == EACCES)
|
||||||
file_type = 1;
|
file_type = virt_directory;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hKey = open_key (path, KEY_READ, wow64, true);
|
hKey = open_key (path, KEY_READ, wow64, true);
|
||||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||||
return 0;
|
return virt_none;
|
||||||
|
|
||||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||||
{
|
{
|
||||||
|
@ -332,13 +333,14 @@ fhandler_registry::exists ()
|
||||||
So allow access to the generic names and to
|
So allow access to the generic names and to
|
||||||
(blank separated) lists of counter numbers.
|
(blank separated) lists of counter numbers.
|
||||||
Never allow access to "Add", see above comment. */
|
Never allow access to "Add", see above comment. */
|
||||||
for (int i = 0; i < PERF_DATA_FILE_COUNT && file_type == 0; i++)
|
for (int i = 0; i < PERF_DATA_FILE_COUNT
|
||||||
|
&& file_type == virt_none; i++)
|
||||||
{
|
{
|
||||||
if (strcasematch (perf_data_files[i], file))
|
if (strcasematch (perf_data_files[i], file))
|
||||||
file_type = -1;
|
file_type = virt_file;
|
||||||
}
|
}
|
||||||
if (file_type == 0 && !file[strspn (file, " 0123456789")])
|
if (file_type == virt_none && !file[strspn (file, " 0123456789")])
|
||||||
file_type = -1;
|
file_type = virt_file;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +353,7 @@ fhandler_registry::exists ()
|
||||||
{
|
{
|
||||||
if (!wcscasecmp (buf, dec_file))
|
if (!wcscasecmp (buf, dec_file))
|
||||||
{
|
{
|
||||||
file_type = 1;
|
file_type = virt_directory;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
buf_size = NAME_MAX + 1;
|
buf_size = NAME_MAX + 1;
|
||||||
|
@ -372,7 +374,7 @@ fhandler_registry::exists ()
|
||||||
{
|
{
|
||||||
if (!wcscasecmp (buf, dec_file))
|
if (!wcscasecmp (buf, dec_file))
|
||||||
{
|
{
|
||||||
file_type = -1;
|
file_type = virt_file;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
buf_size = NAME_MAX + 1;
|
buf_size = NAME_MAX + 1;
|
||||||
|
@ -418,32 +420,32 @@ fhandler_registry::fstat (struct __stat64 *buf)
|
||||||
{
|
{
|
||||||
fhandler_base::fstat (buf);
|
fhandler_base::fstat (buf);
|
||||||
buf->st_mode &= ~_IFMT & NO_W;
|
buf->st_mode &= ~_IFMT & NO_W;
|
||||||
int file_type = exists ();
|
virtual_ftype_t file_type = exists ();
|
||||||
switch (file_type)
|
switch (file_type)
|
||||||
{
|
{
|
||||||
case 0:
|
case virt_none:
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
return -1;
|
return -1;
|
||||||
case 1:
|
case virt_directory:
|
||||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case virt_rootdir:
|
||||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
buf->st_nlink = ROOT_KEY_COUNT;
|
buf->st_nlink = ROOT_KEY_COUNT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case -1:
|
case virt_file:
|
||||||
buf->st_mode |= S_IFREG;
|
buf->st_mode |= S_IFREG;
|
||||||
buf->st_mode &= NO_X;
|
buf->st_mode &= NO_X;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (file_type != 0 && file_type != 2)
|
if (file_type != virt_none && file_type != virt_rootdir)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
const char *path = get_name () + proc_len + prefix_len + 2;
|
const char *path = get_name () + proc_len + prefix_len + 2;
|
||||||
hKey =
|
hKey =
|
||||||
open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, wow64,
|
open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, wow64,
|
||||||
(file_type < 0) ? true : false);
|
(file_type < virt_none) ? true : false);
|
||||||
|
|
||||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||||
/* RegQueryInfoKey () always returns write time 0,
|
/* RegQueryInfoKey () always returns write time 0,
|
||||||
|
@ -461,7 +463,7 @@ fhandler_registry::fstat (struct __stat64 *buf)
|
||||||
to_timestruc_t (&ftLastWriteTime, &buf->st_mtim);
|
to_timestruc_t (&ftLastWriteTime, &buf->st_mtim);
|
||||||
buf->st_ctim = buf->st_birthtim = buf->st_mtim;
|
buf->st_ctim = buf->st_birthtim = buf->st_mtim;
|
||||||
time_as_timestruc_t (&buf->st_atim);
|
time_as_timestruc_t (&buf->st_atim);
|
||||||
if (file_type > 0)
|
if (file_type > virt_none)
|
||||||
buf->st_nlink = subkey_count + 2;
|
buf->st_nlink = subkey_count + 2;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -508,7 +510,7 @@ fhandler_registry::fstat (struct __stat64 *buf)
|
||||||
buf->st_uid = uid;
|
buf->st_uid = uid;
|
||||||
buf->st_gid = gid;
|
buf->st_gid = gid;
|
||||||
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||||
if (file_type > 0)
|
if (file_type > virt_none)
|
||||||
buf->st_mode |= S_IFDIR;
|
buf->st_mode |= S_IFDIR;
|
||||||
else
|
else
|
||||||
buf->st_mode &= NO_X;
|
buf->st_mode &= NO_X;
|
||||||
|
|
|
@ -225,10 +225,10 @@ fhandler_virtual::open (int flags, mode_t mode)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
virtual_ftype_t
|
||||||
fhandler_virtual::exists ()
|
fhandler_virtual::exists ()
|
||||||
{
|
{
|
||||||
return 0;
|
return virt_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* fhandler_virtual.h: Header for virtual fhandlers
|
/* fhandler_virtual.h: Header for virtual fhandlers
|
||||||
|
|
||||||
Copyright 2009 Red Hat, Inc.
|
Copyright 2009, 2010 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -8,20 +8,15 @@ This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
enum virtual_ftype_t {
|
|
||||||
virt_socket = -4,
|
|
||||||
virt_pipe = -3,
|
|
||||||
virt_symlink = -2,
|
|
||||||
virt_file = -1,
|
|
||||||
virt_none = 0,
|
|
||||||
virt_directory = 1,
|
|
||||||
virt_rootdir = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
struct virt_tab_t {
|
struct virt_tab_t {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
size_t name_len;
|
||||||
__dev32_t fhandler;
|
__dev32_t fhandler;
|
||||||
virtual_ftype_t type;
|
virtual_ftype_t type;
|
||||||
_off64_t (*format_func)(void *data, char *&);
|
_off64_t (*format_func)(void *data, char *&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define _VN(s) s, sizeof (s) - 1
|
||||||
|
|
||||||
|
extern virt_tab_t *virt_tab_search (const char *, bool, const virt_tab_t *,
|
||||||
|
size_t);
|
||||||
|
|
|
@ -520,7 +520,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
/* If the path is on a network drive or a //./ resp.//?/ path prefix,
|
/* If the path is on a network drive or a //./ resp. //?/ path prefix,
|
||||||
bypass the mount table. If it's // or //MACHINE, use the netdrive
|
bypass the mount table. If it's // or //MACHINE, use the netdrive
|
||||||
device. */
|
device. */
|
||||||
if (src_path[1] == '/')
|
if (src_path[1] == '/')
|
||||||
|
@ -550,7 +550,16 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
||||||
if (dev.devn == FH_BAD)
|
if (dev.devn == FH_BAD)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
set_flags (flags, PATH_BINARY);
|
set_flags (flags, PATH_BINARY);
|
||||||
strcpy (dst, src_path);
|
if (isprocsys_dev (dev.devn))
|
||||||
|
{
|
||||||
|
if (src_path[procsys_len])
|
||||||
|
backslashify (src_path + procsys_len, dst, 0);
|
||||||
|
else /* Avoid empty NT path. */
|
||||||
|
stpcpy (dst, "\\");
|
||||||
|
set_flags (flags, (unsigned) cygdrive_flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy (dst, src_path);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* Check if the cygdrive prefix was specified. If so, just strip
|
/* Check if the cygdrive prefix was specified. If so, just strip
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013)
|
#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013)
|
||||||
#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022)
|
#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022)
|
||||||
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023)
|
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023)
|
||||||
|
#define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xc0000024)
|
||||||
#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xc0000033)
|
#define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xc0000033)
|
||||||
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xc0000034)
|
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xc0000034)
|
||||||
#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xc000003A)
|
#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xc000003A)
|
||||||
|
@ -40,6 +41,10 @@
|
||||||
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xc0000056)
|
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xc0000056)
|
||||||
#define STATUS_DISK_FULL ((NTSTATUS) 0xc000007f)
|
#define STATUS_DISK_FULL ((NTSTATUS) 0xc000007f)
|
||||||
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
|
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
|
||||||
|
#define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xc00000ab)
|
||||||
|
#define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xc00000ac)
|
||||||
|
#define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xc00000ad)
|
||||||
|
#define STATUS_PIPE_BUSY ((NTSTATUS) 0xc00000ae)
|
||||||
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
|
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
|
||||||
#define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xc00000be)
|
#define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xc00000be)
|
||||||
#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xc00000c3)
|
#define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xc00000c3)
|
||||||
|
@ -208,6 +213,8 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION
|
||||||
#define DIRECTORY_CREATE_SUBDIRECTORY 8
|
#define DIRECTORY_CREATE_SUBDIRECTORY 8
|
||||||
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
|
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
|
||||||
|
|
||||||
|
#define SYMBOLIC_LINK_QUERY 1
|
||||||
|
|
||||||
#define EVENT_QUERY_STATE 1
|
#define EVENT_QUERY_STATE 1
|
||||||
#define SEMAPHORE_QUERY_STATE 1
|
#define SEMAPHORE_QUERY_STATE 1
|
||||||
|
|
||||||
|
@ -927,6 +934,8 @@ extern "C"
|
||||||
NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
||||||
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
||||||
NTSTATUS NTAPI NtOpenSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
NTSTATUS NTAPI NtOpenSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
|
||||||
|
NTSTATUS NTAPI NtOpenSymbolicLinkObject (PHANDLE, ACCESS_MASK,
|
||||||
|
POBJECT_ATTRIBUTES);
|
||||||
/* WARNING! Don't rely on the timestamp information returned by
|
/* WARNING! Don't rely on the timestamp information returned by
|
||||||
NtQueryAttributesFile. Only the DOS file attribute info is reliable. */
|
NtQueryAttributesFile. Only the DOS file attribute info is reliable. */
|
||||||
NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
|
NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
|
||||||
|
@ -956,6 +965,7 @@ extern "C"
|
||||||
|
|
||||||
NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
|
NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
|
||||||
PSECURITY_DESCRIPTOR, ULONG, PULONG);
|
PSECURITY_DESCRIPTOR, ULONG, PULONG);
|
||||||
|
NTSTATUS NTAPI NtQuerySymbolicLinkObject (HANDLE, PUNICODE_STRING, PULONG);
|
||||||
NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
|
NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
|
||||||
PVOID, ULONG, PULONG);
|
PVOID, ULONG, PULONG);
|
||||||
NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, IO_STATUS_BLOCK *,
|
NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, IO_STATUS_BLOCK *,
|
||||||
|
|
|
@ -761,8 +761,8 @@ path_conv::check (const char *src, unsigned opt,
|
||||||
{
|
{
|
||||||
/* FIXME: Calling build_fhandler here is not the right way to handle this. */
|
/* FIXME: Calling build_fhandler here is not the right way to handle this. */
|
||||||
fhandler_virtual *fh = (fhandler_virtual *) build_fh_dev (dev, path_copy);
|
fhandler_virtual *fh = (fhandler_virtual *) build_fh_dev (dev, path_copy);
|
||||||
int file_type = fh->exists ();
|
virtual_ftype_t file_type = fh->exists ();
|
||||||
if (file_type == -2)
|
if (file_type == virt_symlink)
|
||||||
{
|
{
|
||||||
fh->fill_filebuf ();
|
fh->fill_filebuf ();
|
||||||
symlen = sym.set (fh->get_filebuf ());
|
symlen = sym.set (fh->get_filebuf ());
|
||||||
|
@ -770,31 +770,61 @@ path_conv::check (const char *src, unsigned opt,
|
||||||
delete fh;
|
delete fh;
|
||||||
switch (file_type)
|
switch (file_type)
|
||||||
{
|
{
|
||||||
case 1:
|
case virt_directory:
|
||||||
case 2:
|
case virt_rootdir:
|
||||||
if (component == 0)
|
if (component == 0)
|
||||||
fileattr = FILE_ATTRIBUTE_DIRECTORY;
|
fileattr = FILE_ATTRIBUTE_DIRECTORY;
|
||||||
break;
|
break;
|
||||||
case -1:
|
case virt_file:
|
||||||
if (component == 0)
|
if (component == 0)
|
||||||
fileattr = 0;
|
fileattr = 0;
|
||||||
break;
|
break;
|
||||||
case -2: /* /proc/self or /proc/<pid>/symlinks */
|
case virt_symlink:
|
||||||
goto is_virtual_symlink;
|
goto is_virtual_symlink;
|
||||||
case -3: /* /proc/<pid>/fd/pipe:[] */
|
case virt_pipe:
|
||||||
if (component == 0)
|
if (component == 0)
|
||||||
{
|
{
|
||||||
fileattr = 0;
|
fileattr = 0;
|
||||||
dev.parse (FH_PIPE);
|
dev.parse (FH_PIPE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case -4: /* /proc/<pid>/fd/socket:[] */
|
case virt_socket:
|
||||||
if (component == 0)
|
if (component == 0)
|
||||||
{
|
{
|
||||||
fileattr = 0;
|
fileattr = 0;
|
||||||
dev.parse (FH_TCP);
|
dev.parse (FH_TCP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case virt_fsdir:
|
||||||
|
case virt_fsfile:
|
||||||
|
/* Access to real file or directory via block device
|
||||||
|
entry in /proc/sys. Convert to real file and go with
|
||||||
|
the flow. */
|
||||||
|
dev.parse (FH_FS);
|
||||||
|
goto is_fs_via_procsys;
|
||||||
|
case virt_blk:
|
||||||
|
/* Block special device. If the trailing slash has been
|
||||||
|
requested, the target is the root directory of the
|
||||||
|
filesystem on this block device. So we convert this to
|
||||||
|
a real file and attach the backslash. */
|
||||||
|
if (component || need_directory)
|
||||||
|
{
|
||||||
|
dev.parse (FH_FS);
|
||||||
|
if (component == 0)
|
||||||
|
{
|
||||||
|
strcat (full_path, "\\");
|
||||||
|
fileattr = FILE_ATTRIBUTE_DIRECTORY
|
||||||
|
| FILE_ATTRIBUTE_DEVICE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fileattr = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/*FALLTHRU*/
|
||||||
|
case virt_chr:
|
||||||
|
if (component == 0)
|
||||||
|
fileattr = FILE_ATTRIBUTE_DEVICE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (component == 0)
|
if (component == 0)
|
||||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||||
|
@ -841,6 +871,8 @@ path_conv::check (const char *src, unsigned opt,
|
||||||
if (is_msdos)
|
if (is_msdos)
|
||||||
sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
|
sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
|
||||||
|
|
||||||
|
is_fs_via_procsys:
|
||||||
|
|
||||||
symlen = sym.check (full_path, suff, fs, conv_handle);
|
symlen = sym.check (full_path, suff, fs, conv_handle);
|
||||||
|
|
||||||
is_virtual_symlink:
|
is_virtual_symlink:
|
||||||
|
@ -2850,6 +2882,14 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
||||||
if (buf[1] != ':') /* native UNC path */
|
if (buf[1] != ':') /* native UNC path */
|
||||||
*(buf += 2) = '\\';
|
*(buf += 2) = '\\';
|
||||||
}
|
}
|
||||||
|
else if (*buf == '\\')
|
||||||
|
{
|
||||||
|
/* Device name points to somewhere else in the NT namespace.
|
||||||
|
Use GLOBALROOT prefix to convert to Win32 path. */
|
||||||
|
char *p = stpcpy (buf, "\\\\.\\GLOBALROOT");
|
||||||
|
sys_wcstombs (p, NT_MAX_PATH - (p - buf),
|
||||||
|
up->Buffer, up->Length / sizeof (WCHAR));
|
||||||
|
}
|
||||||
lsiz = strlen (buf) + 1;
|
lsiz = strlen (buf) + 1;
|
||||||
/* TODO: Incoming "." is a special case which leads to a trailing
|
/* TODO: Incoming "." is a special case which leads to a trailing
|
||||||
backslash ".\\" in the Win32 path. That's a result of the
|
backslash ".\\" in the Win32 path. That's a result of the
|
||||||
|
@ -2891,7 +2931,8 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
||||||
quite a bunch of Win32 functions, especially in user32.dll,
|
quite a bunch of Win32 functions, especially in user32.dll,
|
||||||
apparently, which don't grok long path names at all, not even
|
apparently, which don't grok long path names at all, not even
|
||||||
in the UNICODE API. */
|
in the UNICODE API. */
|
||||||
if (lsiz <= MAX_PATH + 4 || (path[5] != L':' && lsiz <= MAX_PATH + 6))
|
if ((path[5] == L':' && lsiz <= MAX_PATH + 4)
|
||||||
|
|| (!wcsncmp (path + 4, L"UNC\\", 4) && lsiz <= MAX_PATH + 6))
|
||||||
{
|
{
|
||||||
path += 4;
|
path += 4;
|
||||||
lsiz -= 4;
|
lsiz -= 4;
|
||||||
|
@ -2902,6 +2943,13 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (*path == L'\\')
|
||||||
|
{
|
||||||
|
/* Device name points to somewhere else in the NT namespace.
|
||||||
|
Use GLOBALROOT prefix to convert to Win32 path. */
|
||||||
|
to = (void *) wcpcpy ((wchar_t *) to, L"\\\\.\\GLOBALROOT");
|
||||||
|
lsiz += sizeof ("\\\\.\\GLOBALROOT") - 1;
|
||||||
|
}
|
||||||
/* TODO: Same ".\\" band-aid as in CCP_POSIX_TO_WIN_A case. */
|
/* TODO: Same ".\\" band-aid as in CCP_POSIX_TO_WIN_A case. */
|
||||||
if (relative && !strcmp ((const char *) from, ".")
|
if (relative && !strcmp ((const char *) from, ".")
|
||||||
&& !wcscmp (path, L".\\"))
|
&& !wcscmp (path, L".\\"))
|
||||||
|
@ -2943,10 +2991,10 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
|
||||||
case CCP_POSIX_TO_WIN_A:
|
case CCP_POSIX_TO_WIN_A:
|
||||||
case CCP_WIN_A_TO_POSIX:
|
case CCP_WIN_A_TO_POSIX:
|
||||||
case CCP_WIN_W_TO_POSIX:
|
case CCP_WIN_W_TO_POSIX:
|
||||||
strcpy ((char *) to, buf);
|
stpcpy ((char *) to, buf);
|
||||||
break;
|
break;
|
||||||
case CCP_POSIX_TO_WIN_W:
|
case CCP_POSIX_TO_WIN_W:
|
||||||
wcscpy ((PWCHAR) to, path);
|
wcpcpy ((PWCHAR) to, path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -18,7 +18,9 @@ details. */
|
||||||
|
|
||||||
#define isproc_dev(devn) \
|
#define isproc_dev(devn) \
|
||||||
(devn == FH_PROC || devn == FH_REGISTRY || devn == FH_PROCESS || \
|
(devn == FH_PROC || devn == FH_REGISTRY || devn == FH_PROCESS || \
|
||||||
devn == FH_PROCNET)
|
devn == FH_PROCNET || devn == FH_PROCSYS)
|
||||||
|
|
||||||
|
#define isprocsys_dev(devn) (devn == FH_PROCSYS)
|
||||||
|
|
||||||
#define isvirtual_dev(devn) \
|
#define isvirtual_dev(devn) \
|
||||||
(isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE)
|
(isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE)
|
||||||
|
|
Loading…
Reference in New Issue