@@ -1914,90 +1914,94 @@ console_ttyname(VALUE io)
19141914# define console_ttyname rb_f_notimplement
19151915#endif
19161916
1917- typedef enum {
1918- platform_none ,
19191917#ifdef HAVE_RB_PREPEND_MODULE
1920- platform_any ,
1918+ typedef enum {
1919+ platform_default ,
19211920#if defined _WIN32 || defined __CYGWIN__
19221921 platform_cygwin ,
19231922 platform_msys ,
19241923#endif
1924+ platform_any ,
1925+
1926+ platform_default_bit = 1U << platform_default ,
1927+ #if defined _WIN32 || defined __CYGWIN__
1928+ platform_cygwin_bit = 1U << platform_cygwin ,
1929+ platform_msys_bit = 1U << platform_msys ,
19251930#endif
1926- platform_max
1931+ platform_any_bit = ( 1U << platform_any ) - 1 /* all bits */
19271932} console_platform_t ;
19281933
1929- #ifdef HAVE_RB_PREPEND_MODULE
19301934/*
19311935 * call-seq:
1932- * io.tty?([mode]) -> true or false
1936+ * io.tty?([mode, ... ]) -> true or false
19331937 *
19341938 * Returns +true+ if the stream is associated with a terminal device (tty),
19351939 * +false+ otherwise.
19361940 *
1937- * If non-nil +mode+ is given, platform dependent tty is also checked
1938- * in addition to the default tty.
1941+ * If one or more +type+s are given, returns +true+ if the stream is
1942+ * associated with any of the specified tty types .
19391943 *
1940- * - +:any+ : Returns +true+ for any known kind of tty.
1944+ * - +:any+ : Returns +true+ for any known kind of tty, including the
1945+ * default tty.
19411946 * - +:cygwin+ : Returns +true+ for cygwin tty, on Windows.
19421947 * - +:msys+ : Returns +true+ for msys2 tty, on Windows.
19431948 */
19441949static VALUE
19451950console_platform_tty_p (int argc , VALUE * argv , VALUE io )
19461951{
1947- VALUE ret ;
1948- console_platform_t mode = platform_none ;
1952+ VALUE ret = Qfalse ;
1953+ int mode = 0 ;
19491954
1950- if (rb_check_arity (argc , 0 , 1 )) {
1951- VALUE m = argv [0 ];
1952- if (!NIL_P (m )) {
1955+ if (argc > 0 ) {
1956+ int i ;
1957+ for (i = 0 ; i < argc ; ++ i ) {
1958+ VALUE m = argv [i ];
1959+ if (NIL_P (m )) continue ;
19531960 Check_Type (m , T_SYMBOL );
19541961 if (m == ID2SYM (rb_intern ("any" ))) {
1955- mode = platform_any ;
1962+ mode |= platform_any_bit ;
19561963 }
19571964#if defined _WIN32 || defined __CYGWIN__
19581965 else if (m == ID2SYM (rb_intern ("cygwin "))) {
1959- mode = platform_cygwin ;
1966+ mode |= platform_cygwin_bit ;
19601967 }
19611968 else if (m == ID2SYM (rb_intern ("msys "))) {
1962- mode = platform_msys ;
1969+ mode |= platform_msys_bit ;
19631970 }
19641971#endif
19651972 else {
19661973 rb_raise (rb_eArgError , "unknown tty type: %+" PRIsVALUE , m );
19671974 }
19681975 }
19691976 }
1970- ret = rb_call_super (0 , 0 );
1971- if (mode != platform_none && !RTEST (ret )) {
1977+ if ((mode & platform_default_bit ) || (mode == 0 )) {
1978+ ret = rb_call_super (0 , 0 );
1979+ }
1980+ if ((mode & ~platform_default_bit ) && !RTEST (ret )) {
19721981#if defined _WIN32 || defined __CYGWIN__
1973- HANDLE h ;
1974- union {
1975- FILE_NAME_INFO info ;
1976- WCHAR rest [MAX_PATH ];
1977- } buffer ;
1978- WCHAR * const name = buffer .info .FileName ;
1979- const WCHAR * ptr ;
1980- DWORD len ;
1981-
1982- h = (HANDLE )rb_w32_get_osfhandle (GetReadFD (io ));
1983- if (GetFileType (h ) != FILE_TYPE_PIPE ) return Qfalse ;
1984- if (!GetFileInformationByHandleEx (h , FileNameInfo , & buffer , sizeof (buffer ))) return Qfalse ;
1985- len = buffer .info .FileNameLength / sizeof (WCHAR );
1986- name [len ] = L'\0' ;
1987- # define skip_platform_tty_prefix (type ) \
1988- (memcmp(name, L"\\" #type "-", sizeof(L"\\" #type)) == 0 ? \
1989- &name[rb_strlen_lit(L"\\" #type "-")] : 0)
1990- if (mode == platform_cygwin || mode == platform_any ) {
1991- ptr = skip_platform_tty_prefix (cygwin );
1992- }
1993- else if (mode == platform_msys || mode == platform_any ) {
1994- ptr = skip_platform_tty_prefix (msys );
1995- }
1996- else {
1997- return Qfalse ;
1982+ if (mode & (platform_cygwin_bit | platform_msys_bit )) {
1983+ struct {
1984+ FILE_NAME_INFO info ;
1985+ WCHAR rest [MAX_PATH ];
1986+ } buffer ;
1987+
1988+ HANDLE h = (HANDLE )rb_w32_get_osfhandle (GetReadFD (io ));
1989+ if ((GetFileType (h ) == FILE_TYPE_PIPE ) &&
1990+ GetFileInformationByHandleEx (h , FileNameInfo , & buffer , sizeof (buffer ))) {
1991+ WCHAR * const name = buffer .info .FileName ;
1992+ DWORD len = buffer .info .FileNameLength / sizeof (WCHAR );
1993+ name [len ] = L'\0' ;
1994+ # define tty_pipe_p (type ) \
1995+ (memcmp(name, L"\\" #type "-", sizeof(L"\\" #type)) == 0 && \
1996+ wcsstr(&name[rb_strlen_lit("\\" #type "-")], L"-pty") != NULL)
1997+ if (!ret && (mode & platform_cygwin_bit )) {
1998+ ret = tty_pipe_p (cygwin );
1999+ }
2000+ if (!ret && (mode & platform_msys_bit )) {
2001+ ret = tty_pipe_p (msys );
2002+ }
2003+ }
19982004 }
1999- if (!ptr ) return Qfalse ;
2000- if (wcsstr (ptr , L"-pty" )) ret = Qtrue ;
20012005#endif
20022006 }
20032007 return ret ;
0 commit comments