Before, isatty() was an alias for WinAPI _isatty(). This resulted in wrong result for mintty.
Implement a pipe name check in a static isatty(). This makes io.h include NT and Windows APIs. The change isn't strictly standard, as it adds 'static' to the isatty() signature. Signed-off-by: Mihail Konev <k....@ya.ru> Moved-from: https://github.com/Alexpux/mingw-w64/pull/3 Adapted-from: https://cygwin.com/ml/cygwin-developers/2016-11/msg00002.html --- v1: moved from v7 v2: edit description mingw-w64-headers/crt/io.h | 94 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/mingw-w64-headers/crt/io.h b/mingw-w64-headers/crt/io.h index c61e94ab8743..5e64352df6b4 100644 --- a/mingw-w64-headers/crt/io.h +++ b/mingw-w64-headers/crt/io.h @@ -9,6 +9,13 @@ #include <crtdefs.h> #include <string.h> +/* for cygwin-compatible isatty */ +#include <wchar.h> +#include <errno.h> +#include <io.h> +#include <winternl.h> +#include <windows.h> + #pragma pack(push,_CRT_PACKING) #ifdef __cplusplus @@ -322,7 +329,6 @@ _CRTIMP char* __cdecl _getcwd (char*, int); int __cdecl dup2(int _FileHandleSrc,int _FileHandleDst) __MINGW_ATTRIB_DEPRECATED_MSVC2005; int __cdecl eof(int _FileHandle) __MINGW_ATTRIB_DEPRECATED_MSVC2005; long __cdecl filelength(int _FileHandle) __MINGW_ATTRIB_DEPRECATED_MSVC2005; - int __cdecl isatty(int _FileHandle) __MINGW_ATTRIB_DEPRECATED_MSVC2005; int __cdecl locking(int _FileHandle,int _LockMode,long _NumOfBytes) __MINGW_ATTRIB_DEPRECATED_MSVC2005; long __cdecl lseek(int _FileHandle,long _Offset,int _Origin) __MINGW_ATTRIB_DEPRECATED_MSVC2005; char *__cdecl mktemp(char *_TemplateName) __MINGW_ATTRIB_DEPRECATED_MSVC2005; @@ -335,6 +341,92 @@ _CRTIMP char* __cdecl _getcwd (char*, int); int __cdecl write(int _Filehandle,const void *_Buf,unsigned int _MaxCharCount) __MINGW_ATTRIB_DEPRECATED_MSVC2005; #endif +static int __cdecl isatty(int fd) { + typedef NTSTATUS (NTAPI proc_NtQueryObject) (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG); + proc_NtQueryObject *pNtQueryObject; + + HANDLE h_fd; + + /* NtQueryObject needs space for OBJECT_NAME_INFORMATION.Name->Buffer also. */ + char ntfn_bytes[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; + + OBJECT_NAME_INFORMATION *ntfn = (OBJECT_NAME_INFORMATION*) ntfn_bytes; + NTSTATUS status; + ULONG ntfn_size = sizeof(ntfn_bytes); + + wchar_t c, *s; + USHORT i; + + h_fd = (HANDLE) _get_osfhandle(fd); + if (!h_fd || h_fd == INVALID_HANDLE_VALUE) { + errno = EBADF; + return 0; + } + + pNtQueryObject = (proc_NtQueryObject*) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryObject"); + if (!pNtQueryObject) + goto no_tty; + + memset(ntfn, 0, ntfn_size); + status = pNtQueryObject((HANDLE)h_fd, ObjectNameInformation, + ntfn, ntfn_size, &ntfn_size); + + if (!NT_SUCCESS(status)) { + /* If it is not NUL (i.e. \Device\Null, which would succeed), + * then normal isatty() could be consulted. + * */ + if (_isatty(fd)) + return 1; + goto no_tty; + } + + s = ntfn->Name.Buffer; + s[ntfn->Name.Length / sizeof(WCHAR)] = 0; + + /* Look for \Device\NamedPipe\(cygwin|msys)-[a-fA-F0-9]{16}-pty[0-9]{1,4}-(from-master|to-master|to-master-cyg) */ + + if (wcsncmp(s, L"\\Device\\NamedPipe\\", 18)) + goto no_tty; + s += 18; + + if (!wcsncmp(s, L"cygwin-", 7)) + s += 7; + else if (!wcsncmp(s, L"msys-", 5)) + s += 5; + else + goto no_tty; + + for (i = 0; i < 16; i++) { + c = *s++; + if (!( (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') )) + goto no_tty; + } + + if (wcsncmp(s, L"-pty", 4)) + goto no_tty; + s += 4; + + for (i = 0; i < 4; i++, s++) { + c = *s; + if (!( c >= '0' && c <= '9' )) + break; + } + + if (i == 0) + goto no_tty; + + if (wcscmp(s, L"-from-master") && + wcscmp(s, L"-to-master") && + wcscmp(s, L"-to-master-cyg")) + goto no_tty; + + return 1; + +no_tty: + errno = EINVAL; + return 0; +} + #ifndef _FILE_OFFSET_BITS_SET_LSEEK #define _FILE_OFFSET_BITS_SET_LSEEK #if (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) -- 2.9.2 ------------------------------------------------------------------------------ Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE. Training and support from Colfax. Order your platform today. http://sdm.link/xeonphi _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public