Mail Archives: cygwin/2012/11/26/11:05:39
--PNTmBPCT7hxwcZjr
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
On Nov 26 10:08, Konstantin Kouptsov wrote:
> On Windows, if I compile it using a Microsoft compiler:
>
> C: > cl /out:checktty.exe checktty.c
>
> the program behaves correctly when I run it from a DOS prompt or from a Cywin's bash prompt. However, if I connect to the Windows computer running Cygwin's sshd service from another Linux or Windows computer, it always gives the same result:
>
> $ ./checktty.exe
> not a tty
>
> $ ./checktty.exe < checktty.c
> not a tty
>
> (When I compile with Cygwin's gcc, everything is fine)
>
> What happens here?
Cygwin pseudo ttys are implemented as pipes, and the msvcrt runtime
has no idea about that. It sees a pipe and that's no tty from its
POV.
> Given that I must compile the program using Microsoft's compiler on Windows, how this can be worked around?
The workaround is to implement your own isatty function which recognizes
Cygwin pseudo ttys as well. I had a customer asking this question, too,
at one point and I sent them example code. I attached it to this mail.
HTH,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
--PNTmBPCT7hxwcZjr
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="isatty-for-native-apps.c"
#include <stdio.h>
#include <io.h>
#include <errno.h>
#include <wchar.h>
#include <windows.h>
#include <winternl.h>
#ifndef __MINGW64_VERSION_MAJOR
/* MS winternl.h defines FILE_INFORMATION_CLASS, but with only a
different single member. */
enum FILE_INFORMATION_CLASSX
{
FileNameInformation = 9
};
typedef struct _FILE_NAME_INFORMATION
{
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID,
ULONG, FILE_INFORMATION_CLASSX);
#else
NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID,
ULONG, FILE_INFORMATION_CLASS);
#endif
int
isatty (int fd)
{
HANDLE fh;
NTSTATUS status;
IO_STATUS_BLOCK io;
long buf[66]; /* NAME_MAX + 1 + sizeof ULONG */
PFILE_NAME_INFORMATION pfni = (PFILE_NAME_INFORMATION) buf;
PWCHAR cp;
/* First check using _isatty.
Note that this returns the wrong result for NUL, for instance!
Workaround is not to use _isatty at all, but rather GetFileType
plus object name checking. */
if (_isatty (fd))
return 1;
/* Now fetch the underlying HANDLE. */
fh = (HANDLE) _get_osfhandle (fd);
if (!fh || fh == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return 0;
}
/* Must be a pipe. */
if (GetFileType (fh) != FILE_TYPE_PIPE)
goto no_tty;
/* Calling the native NT function NtQueryInformationFile is required to
support pre-Vista systems. If that's of no concern, Vista introduced
the GetFileInformationByHandleEx call with the FileNameInfo info class,
which can be used instead. */
if (!pNtQueryInformationFile)
{
pNtQueryInformationFile = (NTSTATUS (NTAPI *)(HANDLE, PIO_STATUS_BLOCK,
PVOID, ULONG, FILE_INFORMATION_CLASS))
GetProcAddress (GetModuleHandle ("ntdll.dll"),
"NtQueryInformationFile");
if (!pNtQueryInformationFile)
goto no_tty;
}
if (!NT_SUCCESS (pNtQueryInformationFile (fh, &io, pfni, sizeof buf,
FileNameInformation)))
goto no_tty;
/* The filename is not guaranteed to be NUL-terminated. */
pfni->FileName[pfni->FileNameLength / sizeof (WCHAR)] = L'\0';
/* Now check the name pattern. The filename of a Cygwin pseudo tty pipe
looks like this:
\cygwin-%16llx-pty%d-{to,from}-master
%16llx is the hash of the Cygwin installation, (to support multiple
parallel installations), %d id the pseudo tty number, "to" or "from"
differs the pipe direction. "from" is a stdin, "to" a stdout-like
pipe. */
cp = pfni->FileName;
if (!wcsncmp (cp, L"\\cygwin-", 8)
&& !wcsncmp (cp + 24, L"-pty", 4))
{
cp = wcschr (cp + 28, '-');
if (!cp)
goto no_tty;
if (!wcscmp (cp, L"-from-master") || !wcscmp (cp, L"-to-master"))
return 1;
}
no_tty:
errno = EINVAL;
return 0;
}
int
main ()
{
if (isatty(0))
printf("tty\n");
else
printf("not a tty\n");
return 0;
}
--PNTmBPCT7hxwcZjr
Content-Type: text/plain; charset=us-ascii
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
--PNTmBPCT7hxwcZjr--
- Raw text -