* 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:
@ -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. */
|
||||
fhandler_virtual *fh = (fhandler_virtual *) build_fh_dev (dev, path_copy);
|
||||
int file_type = fh->exists ();
|
||||
if (file_type == -2)
|
||||
virtual_ftype_t file_type = fh->exists ();
|
||||
if (file_type == virt_symlink)
|
||||
{
|
||||
fh->fill_filebuf ();
|
||||
symlen = sym.set (fh->get_filebuf ());
|
||||
@ -770,31 +770,61 @@ path_conv::check (const char *src, unsigned opt,
|
||||
delete fh;
|
||||
switch (file_type)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case virt_directory:
|
||||
case virt_rootdir:
|
||||
if (component == 0)
|
||||
fileattr = FILE_ATTRIBUTE_DIRECTORY;
|
||||
break;
|
||||
case -1:
|
||||
case virt_file:
|
||||
if (component == 0)
|
||||
fileattr = 0;
|
||||
break;
|
||||
case -2: /* /proc/self or /proc/<pid>/symlinks */
|
||||
case virt_symlink:
|
||||
goto is_virtual_symlink;
|
||||
case -3: /* /proc/<pid>/fd/pipe:[] */
|
||||
case virt_pipe:
|
||||
if (component == 0)
|
||||
{
|
||||
fileattr = 0;
|
||||
dev.parse (FH_PIPE);
|
||||
}
|
||||
break;
|
||||
case -4: /* /proc/<pid>/fd/socket:[] */
|
||||
case virt_socket:
|
||||
if (component == 0)
|
||||
{
|
||||
fileattr = 0;
|
||||
dev.parse (FH_TCP);
|
||||
}
|
||||
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:
|
||||
if (component == 0)
|
||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||
@ -841,6 +871,8 @@ path_conv::check (const char *src, unsigned opt,
|
||||
if (is_msdos)
|
||||
sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
|
||||
|
||||
is_fs_via_procsys:
|
||||
|
||||
symlen = sym.check (full_path, suff, fs, conv_handle);
|
||||
|
||||
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 */
|
||||
*(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;
|
||||
/* TODO: Incoming "." is a special case which leads to a trailing
|
||||
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,
|
||||
apparently, which don't grok long path names at all, not even
|
||||
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;
|
||||
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. */
|
||||
if (relative && !strcmp ((const char *) from, ".")
|
||||
&& !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_WIN_A_TO_POSIX:
|
||||
case CCP_WIN_W_TO_POSIX:
|
||||
strcpy ((char *) to, buf);
|
||||
stpcpy ((char *) to, buf);
|
||||
break;
|
||||
case CCP_POSIX_TO_WIN_W:
|
||||
wcscpy ((PWCHAR) to, path);
|
||||
wcpcpy ((PWCHAR) to, path);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user