@@ -10,6 +10,7 @@ use std::collections::{HashMap, HashSet};
1010use std:: env;
1111#[ cfg( not( windows) ) ]
1212use std:: ffi:: CString ;
13+ use std:: ffi:: OsString ;
1314use std:: fs:: { self , File , Metadata , OpenOptions , Permissions } ;
1415use std:: io;
1516#[ cfg( unix) ]
@@ -692,7 +693,7 @@ pub fn uu_app() -> Command {
692693 Arg :: new ( options:: PATHS )
693694 . action ( ArgAction :: Append )
694695 . value_hint ( clap:: ValueHint :: AnyPath )
695- . value_parser ( ValueParser :: path_buf ( ) ) ,
696+ . value_parser ( clap :: value_parser! ( OsString ) ) ,
696697 )
697698}
698699
@@ -722,8 +723,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
722723 }
723724
724725 let paths: Vec < PathBuf > = matches
725- . remove_many :: < PathBuf > ( options:: PATHS )
726- . map ( |v| v. collect ( ) )
726+ . remove_many :: < OsString > ( options:: PATHS )
727+ . map ( |v| v. map ( PathBuf :: from ) . collect ( ) )
727728 . unwrap_or_default ( ) ;
728729
729730 let ( sources, target) = parse_path_args ( paths, & options) ?;
@@ -1134,7 +1135,24 @@ fn parse_path_args(
11341135 }
11351136 }
11361137
1137- Ok ( ( paths, target) )
1138+ // If the path exists and is valid keep it in the argument list.
1139+ // Exception for symlinks as they are a bit more tricky to handle
1140+ // and there's logic further down the execution to handle them.
1141+ let ( ok_paths, invalid_paths) : ( Vec < _ > , Vec < _ > ) = paths
1142+ . into_iter ( )
1143+ . partition ( |p| p. is_symlink ( ) || p. exists ( ) ) ;
1144+
1145+ if !invalid_paths. is_empty ( ) {
1146+ for p in invalid_paths. into_iter ( ) {
1147+ eprintln ! (
1148+ "cp: cannot stat '{}': No such file or directory" ,
1149+ p. display( )
1150+ ) ;
1151+ }
1152+ set_exit_code ( EXIT_ERR ) ;
1153+ }
1154+
1155+ Ok ( ( ok_paths, target) )
11381156}
11391157
11401158/// When handling errors, we don't always want to show them to the user. This function handles that.
0 commit comments