mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-01 13:37:48 +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:
parent
1194a8ce53
commit
b29e219e4d
1 changed files with 29 additions and 4 deletions
|
@ -4,16 +4,41 @@
|
||||||
// *
|
// *
|
||||||
// * For the full copyright and license information, please view the LICENSE
|
// * For the full copyright and license information, please view the LICENSE
|
||||||
// * file that was distributed with this source code.
|
// * 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};
|
static ABOUT: &str = "
|
||||||
use uucore::error::UResult;
|
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]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uu_app<'a>() -> App<'a> {
|
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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue