1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 03:57:44 +00:00

true: Rework to return true more often

Now treats recognized command line options and ignores unrecognized
command line options instead of returning a special exit status for
them.

There is one point of interest, which is related to an implementation
detail in GNU `true`. It may return a non-true exit status (in
particular EXIT_FAIL) if writing the diagnostics of a GNU specific
option fails. For example `true --version > /dev/full` would fail and
have exit status 1.

	This behavior was acknowledged in gnu in commit
	<9a6a486e6503520fd2581f2d3356b7149f1b225d>. No further
	justification provided for keeping this quirk.

POSIX knows no such options, and requires an exit status of 0 in all
cases. We replicate GNU here which is a consistency improvement over the
prior implementation. Adds documentation to clarify the intended
behavior more properly.
This commit is contained in:
Andreas Molzer 2022-02-01 00:35:26 +01:00
parent 1194a8ce53
commit b29e219e4d

View file

@ -4,16 +4,41 @@
// *
// * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code.
use clap::{App, AppSettings, ErrorKind};
use std::io::Write;
use uucore::error::{set_exit_code, UResult};
use clap::{App, AppSettings};
use uucore::error::UResult;
static ABOUT: &str = "
Returns true, a successful exit status.
Immediately returns with the exit status `0`, except when invoked with one of the recognized
options. In those cases it will try to write the help or version text. Any IO error during this
operation causes the program to return `1` instead.
";
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
uu_app().get_matches_from(args);
let app = uu_app();
if let Err(err) = app.try_get_matches_from(args) {
if let ErrorKind::DisplayHelp | ErrorKind::DisplayVersion = err.kind {
if let Err(print_fail) = err.print() {
// Try to display this error.
let _ = writeln!(std::io::stderr(), "{}: {}", uucore::util_name(), print_fail);
// Mirror GNU options. When failing to print warnings or version flags, then we exit
// with FAIL. This avoids allocation some error information which may result in yet
// other types of failure.
set_exit_code(1);
}
}
}
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name()).setting(AppSettings::InferLongArgs)
App::new(uucore::util_name())
.version(clap::crate_version!())
.about(ABOUT)
.setting(AppSettings::InferLongArgs)
}