i still don't understand why not using GetConsoleMode() and see if it
fails or not.

if it fails : redirection is done with named pipes
if not : it's standard win32 I/O

it's simple and works in my tests (DOS console, MSYS1, mintty, MSYS2
and cygwin terminal >= 1.8)

Vincent Torri


On Sun, Nov 13, 2016 at 1:00 AM, Mihail Konev <k....@ya.ru> wrote:
> Applications now could call iscygtty(STDIN_FILENO)
> in order to detect whether they are running from
> Cygwin/MSys terminal.
>
> Without that, they have no choice but to think that
> stdin is redirected from a named pipe.
>
> 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
> ---
> v7:
> - set errno if returning false
> - do not depend on ntdll.dll being linked, use GetProcAddress
> - stricter name check
> - act as cygwin.dll isatty()
>   I.e. is-it-mintty-or-cmd?
>   To get the previous is-it-mintty? behaviour, just omit the "if (_isatty)".
>
> The is-it-mintty? is actually a leftover from initial example;
> the "real" version could as well aggressively alias the stanard api
> (especially given that applications could still call the is-it-cmd? _isatty() 
> if they want to).
>
> Don't know how to make it a substitute for isatty(), through.
> Putting this into io.h results in implicit declarations and errors.
>
> Should all used types be declared locally in the function,
> or headers be rearranged (but how?)?
>
> Also typedef proc_NtQueryObject could be broken in some compiler; should
> it not be used?
>
> This function is intended for:
> - "mingw64-" Cygwin packages
> - "mingw-w64-" MSYS packages
> Both should be built using mingw-w64 toolchain, and currenly have isatty() 
> being _isatty().
>
>  mingw-w64-headers/include/iscygtty.c | 96 
> ++++++++++++++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
>  create mode 100644 mingw-w64-headers/include/iscygtty.c
>
> diff --git a/mingw-w64-headers/include/iscygtty.c 
> b/mingw-w64-headers/include/iscygtty.c
> new file mode 100644
> index 000000000000..1c7a394d965b
> --- /dev/null
> +++ b/mingw-w64-headers/include/iscygtty.c
> @@ -0,0 +1,96 @@
> +#ifndef __ISCYGTTY_C__
> +#define __ISCYGTTY_C__
> +
> +#include <io.h>
> +#include <winternl.h>
> +
> +#include <wchar.h>
> +#include <windows.h>
> +
> +static int iscygtty(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;
> +}
> +
> +#endif /* __ISCYGTTY_C__ */
> --
> 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

------------------------------------------------------------------------------
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

Reply via email to