@@ -42,9 +42,12 @@ pub fn resolve_command_path(
4242 return Err ( CommandPathResolutionError :: CommandEmpty ) ;
4343 }
4444
45- // check for absolute
46- if PathBuf :: from ( command_name) . is_absolute ( ) {
47- return Ok ( PathBuf :: from ( command_name) ) ;
45+ // check for absolute or relative path
46+ let path = Path :: new ( command_name) ;
47+ if path. is_absolute ( ) {
48+ return Ok ( path. to_path_buf ( ) ) ;
49+ } else if path. components ( ) . count ( ) > 1 {
50+ return Ok ( base_dir. join ( command_name) ) ;
4851 }
4952
5053 let result = which:: WhichConfig :: new_with_sys ( state. clone ( ) )
@@ -95,7 +98,7 @@ impl which::sys::Sys for ShellState {
9598 fn env_windows_path_ext ( & self ) -> Cow < ' static , [ String ] > {
9699 Cow :: Owned (
97100 self
98- . env_path_ext ( )
101+ . get_var ( OsStr :: new ( "PATHEXT" ) )
99102 . and_then ( |pathext| {
100103 Some (
101104 pathext
@@ -141,13 +144,42 @@ impl which::sys::Sys for ShellState {
141144 Ok ( Box :: new ( iter) )
142145 }
143146
147+ #[ cfg( unix) ]
144148 fn is_valid_executable (
145149 & self ,
146- _path : & std:: path:: Path ,
150+ path : & std:: path:: Path ,
147151 ) -> std:: io:: Result < bool > {
148- // we've considered everything to be executable so that cross platform
149- // shebangs work and so that people don't need to bother marking an
150- // item as executable in git, which is annoying for Windows users
151- Ok ( true )
152+ use nix:: unistd:: AccessFlags ;
153+ use nix:: unistd:: access;
154+
155+ match access ( path, AccessFlags :: X_OK ) {
156+ Ok ( ( ) ) => Ok ( true ) ,
157+ Err ( nix:: errno:: Errno :: ENOENT ) => Ok ( false ) ,
158+ Err ( e) => Err ( std:: io:: Error :: from_raw_os_error ( e as i32 ) ) ,
159+ }
160+ }
161+
162+ #[ cfg( windows) ]
163+ fn is_valid_executable (
164+ & self ,
165+ path : & std:: path:: Path ,
166+ ) -> std:: io:: Result < bool > {
167+ use std:: os:: windows:: ffi:: OsStrExt ;
168+
169+ let name = path
170+ . as_os_str ( )
171+ . encode_wide ( )
172+ . chain ( Some ( 0 ) )
173+ . collect :: < Vec < u16 > > ( ) ;
174+ let mut bt: u32 = 0 ;
175+ // SAFETY: winapi call
176+ unsafe {
177+ Ok (
178+ windows_sys:: Win32 :: Storage :: FileSystem :: GetBinaryTypeW (
179+ name. as_ptr ( ) ,
180+ & mut bt,
181+ ) != 0 ,
182+ )
183+ }
152184 }
153185}
0 commit comments