diff --git a/src/uu/pwd/locales/en-US.ftl b/src/uu/pwd/locales/en-US.ftl index ffed18f37..035f81e62 100644 --- a/src/uu/pwd/locales/en-US.ftl +++ b/src/uu/pwd/locales/en-US.ftl @@ -5,6 +5,9 @@ pwd-usage = pwd [OPTION]... pwd-help-logical = use PWD from environment, even if it contains symlinks pwd-help-physical = avoid all symlinks +# Warning messages +pwd-ignoring-non-option-arguments = ignoring non-option arguments + # Error messages pwd-error-failed-to-get-current-directory = failed to get current directory pwd-error-failed-to-print-current-directory = failed to print current directory diff --git a/src/uu/pwd/locales/fr-FR.ftl b/src/uu/pwd/locales/fr-FR.ftl index 95a79a362..a13bb33f7 100644 --- a/src/uu/pwd/locales/fr-FR.ftl +++ b/src/uu/pwd/locales/fr-FR.ftl @@ -5,6 +5,9 @@ pwd-usage = pwd [OPTION]... pwd-help-logical = utiliser PWD de l'environnement, même s'il contient des liens symboliques pwd-help-physical = éviter tous les liens symboliques +# Messages d'avertissement +pwd-ignoring-non-option-arguments = arguments non-option ignorés + # Messages d'erreur pwd-error-failed-to-get-current-directory = échec de l'obtention du répertoire actuel pwd-error-failed-to-print-current-directory = échec de l'affichage du répertoire actuel diff --git a/src/uu/pwd/src/pwd.rs b/src/uu/pwd/src/pwd.rs index 193af4ccc..41d568b72 100644 --- a/src/uu/pwd/src/pwd.rs +++ b/src/uu/pwd/src/pwd.rs @@ -12,10 +12,12 @@ use uucore::format_usage; use uucore::display::println_verbatim; use uucore::error::{FromIo, UResult}; +use uucore::show_error; use uucore::translate; const OPT_LOGICAL: &str = "logical"; const OPT_PHYSICAL: &str = "physical"; +const ARG_OPERANDS: &str = "operands"; fn physical_path() -> io::Result { // std::env::current_dir() is a thin wrapper around libc::getcwd(). @@ -110,6 +112,12 @@ fn logical_path() -> io::Result { #[uucore::main(no_signals)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?; + + // GNU pwd ignores any non-option operands but warns about them. + if matches.contains_id(ARG_OPERANDS) { + show_error!("{}", translate!("pwd-ignoring-non-option-arguments")); + } + // if POSIXLY_CORRECT is set, we want to a logical resolution. // This produces a different output when doing mkdir -p a/b && ln -s a/b c && cd c && pwd // We should get c in this case instead of a/b at the end of the path @@ -160,4 +168,10 @@ pub fn uu_app() -> Command { .help(translate!("pwd-help-physical")) .action(ArgAction::SetTrue), ) + .arg( + Arg::new(ARG_OPERANDS) + .action(ArgAction::Append) + .num_args(1..) + .hide(true), + ) } diff --git a/tests/by-util/test_pwd.rs b/tests/by-util/test_pwd.rs index ce63fb889..a6e1bd798 100644 --- a/tests/by-util/test_pwd.rs +++ b/tests/by-util/test_pwd.rs @@ -22,9 +22,13 @@ fn test_default() { } #[test] -fn test_failed() { - let (_at, mut ucmd) = at_and_ucmd!(); - ucmd.arg("will-fail").fails(); +fn test_ignores_non_option_arguments() { + // GNU pwd ignores non-option operands, warning on stderr but exiting 0. + let (at, mut ucmd) = at_and_ucmd!(); + ucmd.arg("will-fail") + .succeeds() + .stdout_is(at.root_dir_resolved() + "\n") + .stderr_is("pwd: ignoring non-option arguments\n"); } #[cfg(unix)] diff --git a/util/gnu-patches/series b/util/gnu-patches/series index f39561323..f9b7fd826 100644 --- a/util/gnu-patches/series +++ b/util/gnu-patches/series @@ -11,3 +11,4 @@ tests_du_move_dir_while_traversing.patch test_mkdir_restorecon.patch error_msg_uniq.diff tests_numfmt.patch +tests_pwd-long.patch diff --git a/util/gnu-patches/tests_pwd-long.patch b/util/gnu-patches/tests_pwd-long.patch new file mode 100644 index 000000000..a26847e26 --- /dev/null +++ b/util/gnu-patches/tests_pwd-long.patch @@ -0,0 +1,28 @@ +Index: gnu/tests/pwd/pwd-long.sh +=================================================================== +--- gnu.orig/tests/pwd/pwd-long.sh ++++ gnu/tests/pwd/pwd-long.sh +@@ -19,7 +19,6 @@ + + . "${srcdir=.}/tests/init.sh"; + print_ver_ pwd +-uses_strace_ + + require_readable_root_ + require_perl_ +@@ -27,11 +26,10 @@ + ARGV_0=$0 + export ARGV_0 + +-# Disable the getcwd syscall if possible, so more of our code is exercised. +-no_sys_getcwd() { +- strace -f -o /dev/null -e 'getcwd' -e fault=all:error=ENOSYS "$@" +-} +-no_sys_getcwd true || no_sys_getcwd() { "$@"; } ++# uutils: our pwd has no userspace getcwd reimplementation like GNU's; it ++# relies on the kernel getcwd(), which already handles paths longer than ++# PATH_MAX. So run pwd directly instead of disabling the getcwd syscall. ++no_sys_getcwd() { "$@"; } + + # Don't use CuTmpdir here, since File::Temp's use of rmtree can't + # remove the deep tree we create.