* dtable.cc (DEV_SOCKET): New static WCHAR string. Name of
the native NT socket device. (dtable::init_std_file_from_handle): Remove unused tmp_pathbuf variable. Move check for sockets into FILE_TYPE_PIPE clause. Rely on handle_to_fn having recognized socket, or check if getsockopt works to accommodate NT4 shortcoming. (handle_to_fn): Use tmp_pathbuf for OBJECT_NAME_INFORMATION buffer and simplify code due to that. Check name returned by NtQueryObject for socket device.
This commit is contained in:
parent
78d959ce6f
commit
019fc8d880
@ -1,3 +1,15 @@
|
|||||||
|
2009-08-10 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* dtable.cc (DEV_SOCKET): New static WCHAR string. Name of
|
||||||
|
the native NT socket device.
|
||||||
|
(dtable::init_std_file_from_handle): Remove unused tmp_pathbuf
|
||||||
|
variable. Move check for sockets into FILE_TYPE_PIPE clause.
|
||||||
|
Rely on handle_to_fn having recognized socket, or check if
|
||||||
|
getsockopt works to accommodate NT4 shortcoming.
|
||||||
|
(handle_to_fn): Use tmp_pathbuf for OBJECT_NAME_INFORMATION
|
||||||
|
buffer and simplify code due to that. Check name returned by
|
||||||
|
NtQueryObject for socket device.
|
||||||
|
|
||||||
2009-08-10 Christopher Faylor <me+cygwin@cgf.cx>
|
2009-08-10 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* fhandler_console.cc (create_invisible_console_workaround): Fix size
|
* fhandler_console.cc (create_invisible_console_workaround): Fix size
|
||||||
|
@ -40,6 +40,7 @@ static bool handle_to_fn (HANDLE, char *);
|
|||||||
#define WCLEN(x) ((sizeof (x) / sizeof (WCHAR)) - 1)
|
#define WCLEN(x) ((sizeof (x) / sizeof (WCHAR)) - 1)
|
||||||
char unknown_file[] = "some disk file";
|
char unknown_file[] = "some disk file";
|
||||||
const WCHAR DEV_NULL[] = L"\\Device\\Null";
|
const WCHAR DEV_NULL[] = L"\\Device\\Null";
|
||||||
|
static const WCHAR DEV_SOCKET[] = L"\\Device\\Afd";
|
||||||
|
|
||||||
const WCHAR DEVICE_PREFIX[] = L"\\device\\";
|
const WCHAR DEVICE_PREFIX[] = L"\\device\\";
|
||||||
const size_t DEVICE_PREFIX_LEN WCLEN (DEVICE_PREFIX);
|
const size_t DEVICE_PREFIX_LEN WCLEN (DEVICE_PREFIX);
|
||||||
@ -271,12 +272,9 @@ void
|
|||||||
dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_INFO buf;
|
CONSOLE_SCREEN_BUFFER_INFO buf;
|
||||||
struct sockaddr sa;
|
|
||||||
int sal = sizeof (sa);
|
|
||||||
DCB dcb;
|
DCB dcb;
|
||||||
unsigned bin = O_BINARY;
|
unsigned bin = O_BINARY;
|
||||||
device dev;
|
device dev;
|
||||||
tmp_pathbuf tp;
|
|
||||||
|
|
||||||
dev.devn = 0; /* FIXME: device */
|
dev.devn = 0; /* FIXME: device */
|
||||||
first_fd_for_open = 0;
|
first_fd_for_open = 0;
|
||||||
@ -293,8 +291,21 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||||||
/* can't figure out what this is */;
|
/* can't figure out what this is */;
|
||||||
else if (ft == FILE_TYPE_PIPE)
|
else if (ft == FILE_TYPE_PIPE)
|
||||||
{
|
{
|
||||||
|
int rcv = 0, len = sizeof (int);
|
||||||
|
|
||||||
if (handle_to_fn (handle, name))
|
if (handle_to_fn (handle, name))
|
||||||
/* ok */;
|
/* ok */;
|
||||||
|
else if (strcmp (name, ":sock:") == 0
|
||||||
|
/* On NT4, NtQueryObject returns STATUS_NOT_IMPLEMENTED when
|
||||||
|
called for a socket handle. */
|
||||||
|
|| (strcmp (name, unknown_file) == 0
|
||||||
|
&& !::getsockopt ((SOCKET) handle, SOL_SOCKET, SO_RCVBUF,
|
||||||
|
(char *) &rcv, &len)))
|
||||||
|
{
|
||||||
|
/* socket */
|
||||||
|
dev = *tcp_dev;
|
||||||
|
name[0] = '\0';
|
||||||
|
}
|
||||||
else if (fd == 0)
|
else if (fd == 0)
|
||||||
dev = *piper_dev;
|
dev = *piper_dev;
|
||||||
else
|
else
|
||||||
@ -318,9 +329,6 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||||||
else
|
else
|
||||||
dev = *console_dev;
|
dev = *console_dev;
|
||||||
}
|
}
|
||||||
else if (wsock_started && getpeername ((SOCKET) handle, &sa, &sal) == 0)
|
|
||||||
/* socket */
|
|
||||||
dev = *tcp_dev;
|
|
||||||
else if (GetCommState (handle, &dcb))
|
else if (GetCommState (handle, &dcb))
|
||||||
/* serial */
|
/* serial */
|
||||||
dev.parse (DEV_TTYS_MAJOR, 0);
|
dev.parse (DEV_TTYS_MAJOR, 0);
|
||||||
@ -881,122 +889,118 @@ handle_to_fn (HANDLE h, char *posix_fn)
|
|||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
ULONG len = 0;
|
ULONG len = 0;
|
||||||
OBJECT_NAME_INFORMATION dummy_oni;
|
|
||||||
WCHAR *maxmatchdos = NULL;
|
WCHAR *maxmatchdos = NULL;
|
||||||
int maxmatchlen = 0;
|
int maxmatchlen = 0;
|
||||||
|
OBJECT_NAME_INFORMATION *ntfn = (OBJECT_NAME_INFORMATION *) tp.w_get ();
|
||||||
|
|
||||||
NTSTATUS status = NtQueryObject (h, ObjectNameInformation, &dummy_oni,
|
NTSTATUS status = NtQueryObject (h, ObjectNameInformation, ntfn, 65536, &len);
|
||||||
sizeof (dummy_oni), &len);
|
if (!NT_SUCCESS (status))
|
||||||
if (!NT_SUCCESS (status) || !len)
|
debug_printf ("NtQueryObject failed, %p", status);
|
||||||
debug_printf ("NtQueryObject failed 1");
|
// NT seems to do this on an unopened file
|
||||||
|
else if (!ntfn->Name.Buffer)
|
||||||
|
debug_printf ("nt->Name.Buffer == NULL");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OBJECT_NAME_INFORMATION *ntfn = (OBJECT_NAME_INFORMATION *) alloca (len + sizeof (WCHAR));
|
WCHAR *w32 = ntfn->Name.Buffer;
|
||||||
NTSTATUS res = NtQueryObject (h, ObjectNameInformation, ntfn, len, NULL);
|
size_t w32len = ntfn->Name.Length / sizeof (WCHAR);
|
||||||
|
w32[w32len] = L'\0';
|
||||||
|
|
||||||
if (!NT_SUCCESS (res))
|
if (wcscasecmp (w32, DEV_NULL) == 0)
|
||||||
debug_printf ("NtQueryObject failed 2");
|
|
||||||
// NT seems to do this on an unopened file
|
|
||||||
else if (!ntfn->Name.Buffer)
|
|
||||||
debug_printf ("nt->Name.Buffer == NULL");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
WCHAR *w32 = ntfn->Name.Buffer;
|
strcpy (posix_fn, "/dev/null");
|
||||||
size_t w32len = ntfn->Name.Length / sizeof (WCHAR);
|
|
||||||
w32[w32len] = L'\0';
|
|
||||||
|
|
||||||
if (wcscasecmp (w32, DEV_NULL) == 0)
|
|
||||||
{
|
|
||||||
strcpy (posix_fn, "/dev/null");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wcsncasecmp (w32, DEV_NAMED_PIPE, DEV_NAMED_PIPE_LEN) == 0)
|
|
||||||
{
|
|
||||||
w32 += DEV_NAMED_PIPE_LEN;
|
|
||||||
if (wcsncmp (w32, L"cygwin-", WCLEN (L"cygwin-")) != 0)
|
|
||||||
return false;
|
|
||||||
w32 += WCLEN (L"cygwin-");
|
|
||||||
bool istty = wcsncmp (w32, L"tty", WCLEN (L"tty")) == 0;
|
|
||||||
if (istty)
|
|
||||||
decode_tty (posix_fn, w32 + WCLEN (L"tty"));
|
|
||||||
else if (wcsncmp (w32, L"pipe", WCLEN (L"pipe")) == 0)
|
|
||||||
strcpy (posix_fn, "/dev/pipe");
|
|
||||||
return istty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WCHAR fnbuf[64 * 1024];
|
|
||||||
if (wcsncasecmp (w32, DEVICE_PREFIX, DEVICE_PREFIX_LEN) != 0
|
|
||||||
|| !QueryDosDeviceW (NULL, fnbuf, sizeof (fnbuf)))
|
|
||||||
{
|
|
||||||
sys_wcstombs (posix_fn, NT_MAX_PATH, w32, w32len);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (WCHAR *s = fnbuf; *s; s = wcschr (s, '\0') + 1)
|
|
||||||
{
|
|
||||||
WCHAR device[NT_MAX_PATH];
|
|
||||||
if (!QueryDosDeviceW (s, device, sizeof (device)))
|
|
||||||
continue;
|
|
||||||
if (wcschr (s, ':') == NULL)
|
|
||||||
continue;
|
|
||||||
WCHAR *q = wcsrchr (device, ';');
|
|
||||||
if (q)
|
|
||||||
{
|
|
||||||
WCHAR *r = wcschr (q, '\\');
|
|
||||||
if (r)
|
|
||||||
wcscpy (q, r + 1);
|
|
||||||
}
|
|
||||||
int devlen = wcslen (device);
|
|
||||||
if (device[devlen - 1] == L'\\')
|
|
||||||
device[--devlen] = L'\0';
|
|
||||||
if (devlen < maxmatchlen)
|
|
||||||
continue;
|
|
||||||
if (wcsncmp (device, w32, devlen) != 0||
|
|
||||||
(w32[devlen] != L'\0' && w32[devlen] != L'\\'))
|
|
||||||
continue;
|
|
||||||
maxmatchlen = devlen;
|
|
||||||
maxmatchdos = s;
|
|
||||||
debug_printf ("current match '%W' = '%W'\n", s, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxmatchlen)
|
|
||||||
{
|
|
||||||
WCHAR *p = wcschr (w32 + DEVICE_PREFIX_LEN, L'\\');
|
|
||||||
size_t n = wcslen (maxmatchdos);
|
|
||||||
WCHAR ch;
|
|
||||||
if (!p)
|
|
||||||
ch = L'\0';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (maxmatchdos[n - 1] == L'\\')
|
|
||||||
n--;
|
|
||||||
w32 += maxmatchlen - n;
|
|
||||||
ch = L'\\';
|
|
||||||
}
|
|
||||||
memcpy (w32, maxmatchdos, n * sizeof (WCHAR));
|
|
||||||
w32[n] = ch;
|
|
||||||
}
|
|
||||||
else if (wcsncmp (w32, DEV_REMOTE, DEV_REMOTE_LEN) == 0)
|
|
||||||
{
|
|
||||||
w32 += DEV_REMOTE_LEN - 2;
|
|
||||||
*w32 = L'\\';
|
|
||||||
debug_printf ("remote drive");
|
|
||||||
}
|
|
||||||
else if (wcsncmp (w32, DEV_REMOTE1, DEV_REMOTE1_LEN) == 0)
|
|
||||||
{
|
|
||||||
w32 += DEV_REMOTE1_LEN - 2;
|
|
||||||
*w32 = L'\\';
|
|
||||||
debug_printf ("remote drive");
|
|
||||||
}
|
|
||||||
|
|
||||||
cygwin_conv_path (CCP_WIN_W_TO_POSIX | CCP_ABSOLUTE, w32, posix_fn,
|
|
||||||
NT_MAX_PATH);
|
|
||||||
|
|
||||||
debug_printf ("derived path '%W', posix '%s'", w32, posix_fn);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wcscasecmp (w32, DEV_SOCKET) == 0)
|
||||||
|
{
|
||||||
|
strcpy (posix_fn, ":sock:");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wcsncasecmp (w32, DEV_NAMED_PIPE, DEV_NAMED_PIPE_LEN) == 0)
|
||||||
|
{
|
||||||
|
w32 += DEV_NAMED_PIPE_LEN;
|
||||||
|
if (wcsncmp (w32, L"cygwin-", WCLEN (L"cygwin-")) != 0)
|
||||||
|
return false;
|
||||||
|
w32 += WCLEN (L"cygwin-");
|
||||||
|
bool istty = wcsncmp (w32, L"tty", WCLEN (L"tty")) == 0;
|
||||||
|
if (istty)
|
||||||
|
decode_tty (posix_fn, w32 + WCLEN (L"tty"));
|
||||||
|
else if (wcsncmp (w32, L"pipe", WCLEN (L"pipe")) == 0)
|
||||||
|
strcpy (posix_fn, "/dev/pipe");
|
||||||
|
return istty;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR fnbuf[64 * 1024];
|
||||||
|
if (wcsncasecmp (w32, DEVICE_PREFIX, DEVICE_PREFIX_LEN) != 0
|
||||||
|
|| !QueryDosDeviceW (NULL, fnbuf, sizeof (fnbuf)))
|
||||||
|
{
|
||||||
|
sys_wcstombs (posix_fn, NT_MAX_PATH, w32, w32len);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WCHAR *s = fnbuf; *s; s = wcschr (s, '\0') + 1)
|
||||||
|
{
|
||||||
|
WCHAR device[NT_MAX_PATH];
|
||||||
|
if (!QueryDosDeviceW (s, device, sizeof (device)))
|
||||||
|
continue;
|
||||||
|
if (wcschr (s, ':') == NULL)
|
||||||
|
continue;
|
||||||
|
WCHAR *q = wcsrchr (device, ';');
|
||||||
|
if (q)
|
||||||
|
{
|
||||||
|
WCHAR *r = wcschr (q, '\\');
|
||||||
|
if (r)
|
||||||
|
wcscpy (q, r + 1);
|
||||||
|
}
|
||||||
|
int devlen = wcslen (device);
|
||||||
|
if (device[devlen - 1] == L'\\')
|
||||||
|
device[--devlen] = L'\0';
|
||||||
|
if (devlen < maxmatchlen)
|
||||||
|
continue;
|
||||||
|
if (wcsncmp (device, w32, devlen) != 0||
|
||||||
|
(w32[devlen] != L'\0' && w32[devlen] != L'\\'))
|
||||||
|
continue;
|
||||||
|
maxmatchlen = devlen;
|
||||||
|
maxmatchdos = s;
|
||||||
|
debug_printf ("current match '%W' = '%W'\n", s, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxmatchlen)
|
||||||
|
{
|
||||||
|
WCHAR *p = wcschr (w32 + DEVICE_PREFIX_LEN, L'\\');
|
||||||
|
size_t n = wcslen (maxmatchdos);
|
||||||
|
WCHAR ch;
|
||||||
|
if (!p)
|
||||||
|
ch = L'\0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (maxmatchdos[n - 1] == L'\\')
|
||||||
|
n--;
|
||||||
|
w32 += maxmatchlen - n;
|
||||||
|
ch = L'\\';
|
||||||
|
}
|
||||||
|
memcpy (w32, maxmatchdos, n * sizeof (WCHAR));
|
||||||
|
w32[n] = ch;
|
||||||
|
}
|
||||||
|
else if (wcsncmp (w32, DEV_REMOTE, DEV_REMOTE_LEN) == 0)
|
||||||
|
{
|
||||||
|
w32 += DEV_REMOTE_LEN - 2;
|
||||||
|
*w32 = L'\\';
|
||||||
|
debug_printf ("remote drive");
|
||||||
|
}
|
||||||
|
else if (wcsncmp (w32, DEV_REMOTE1, DEV_REMOTE1_LEN) == 0)
|
||||||
|
{
|
||||||
|
w32 += DEV_REMOTE1_LEN - 2;
|
||||||
|
*w32 = L'\\';
|
||||||
|
debug_printf ("remote drive");
|
||||||
|
}
|
||||||
|
|
||||||
|
cygwin_conv_path (CCP_WIN_W_TO_POSIX | CCP_ABSOLUTE, w32, posix_fn,
|
||||||
|
NT_MAX_PATH);
|
||||||
|
|
||||||
|
debug_printf ("derived path '%W', posix '%s'", w32, posix_fn);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy (posix_fn, unknown_file);
|
strcpy (posix_fn, unknown_file);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user