@@ -58,11 +58,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
5858 writeln ! ( stdout, "{}" , translate!( "tty-not-a-tty" ) )
5959 } ;
6060 #[ cfg( target_os = "windows" ) ]
61- let write_result = if std:: io:: stdin ( ) . is_terminal ( ) {
62- writeln ! ( stdout, r"\\.\CON" )
63- } else {
64- set_exit_code ( 1 ) ;
65- writeln ! ( stdout, "{}" , translate!( "tty-not-a-tty" ) )
61+ let write_result = {
62+ use std:: os:: windows:: io:: AsHandle ;
63+ let stdin = std:: io:: stdin ( ) ;
64+ let stdin_handle = stdin. as_handle ( ) ;
65+ if stdin_handle. is_terminal ( ) {
66+ if let Some ( name) = file_name ( stdin_handle) {
67+ writeln ! ( stdout, "{name}" )
68+ } else {
69+ writeln ! ( stdout, r"\\.\CON" )
70+ }
71+ } else {
72+ set_exit_code ( 1 ) ;
73+ writeln ! ( stdout, "{}" , translate!( "tty-not-a-tty" ) )
74+ }
6675 } ;
6776
6877 if write_result. is_err ( ) || stdout. flush ( ) . is_err ( ) {
@@ -74,6 +83,42 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
7483 Ok ( ( ) )
7584}
7685
86+ #[ cfg( target_os = "windows" ) ]
87+ fn file_name ( handle : std:: os:: windows:: io:: BorrowedHandle ) -> Option < String > {
88+ use std:: mem:: MaybeUninit ;
89+ use std:: os:: windows:: io:: AsRawHandle ;
90+ use windows_sys:: Win32 :: Foundation :: MAX_PATH ;
91+ use windows_sys:: Win32 :: Storage :: FileSystem :: { FileNameInfo , GetFileInformationByHandleEx } ;
92+ // Manually define FILE_NAME_INFO so we can more easily construct a stack buffer.
93+ #[ repr( C ) ]
94+ #[ allow( non_snake_case) ]
95+ struct FILE_NAME_INFO {
96+ FileNameLength : u32 ,
97+ FileName : [ MaybeUninit < u16 > ; MAX_PATH as usize ] ,
98+ }
99+ let mut name = FILE_NAME_INFO {
100+ FileNameLength : 0 ,
101+ FileName : [ MaybeUninit :: uninit ( ) ; _] ,
102+ } ;
103+ unsafe {
104+ let result = GetFileInformationByHandleEx (
105+ handle. as_raw_handle ( ) ,
106+ FileNameInfo ,
107+ ( & raw mut name) . cast ( ) ,
108+ size_of :: < FILE_NAME_INFO > ( ) as u32 ,
109+ ) ;
110+ if result == 0 {
111+ None
112+ } else {
113+ let name = name. FileName . get ( ..name. FileNameLength as usize / 2 ) ?;
114+ // SAFETY: all elements up to FileNameLength have been initialized
115+ let name: & [ u16 ] = & * ( std:: ptr:: from_ref :: < [ MaybeUninit < u16 > ] > ( name) as * const [ u16 ] ) ;
116+ // This should never fail for a valid msys terminal because they use ASCII names.
117+ String :: from_utf16 ( name) . ok ( )
118+ }
119+ }
120+ }
121+
77122pub fn uu_app ( ) -> Command {
78123 let cmd = Command :: new ( "tty" )
79124 . version ( uucore:: crate_version!( ) )
0 commit comments