Merge branch 'main' into long_help_file

This commit is contained in:
Sylvestre Ledru 2022-08-20 11:58:37 +02:00 committed by GitHub
commit 71e51d120a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
114 changed files with 1701 additions and 869 deletions

View file

@ -849,6 +849,7 @@ jobs:
name: Test Android builds
needs: [ min_version, deps ]
runs-on: macos-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
@ -904,6 +905,7 @@ jobs:
name: Tests/FreeBSD test suite
needs: [ min_version, deps ]
runs-on: ${{ matrix.job.os }}
timeout-minutes: 90
strategy:
fail-fast: false
matrix:

541
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -190,6 +190,7 @@ feat_require_unix = [
"nohup",
"pathchk",
"stat",
"stty",
"timeout",
"tty",
"uname",
@ -261,7 +262,7 @@ uudoc = [ "zip" ]
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
clap_complete = "3.1"
once_cell = "1.13.0"
once_cell = "1.13.1"
phf = "0.10.1"
selinux = { version="0.2", optional = true }
textwrap = { version="0.15", features=["terminal_size"] }
@ -348,6 +349,7 @@ sort = { optional=true, version="0.0.14", package="uu_sort", path="src/uu/so
split = { optional=true, version="0.0.14", package="uu_split", path="src/uu/split" }
stat = { optional=true, version="0.0.14", package="uu_stat", path="src/uu/stat" }
stdbuf = { optional=true, version="0.0.14", package="uu_stdbuf", path="src/uu/stdbuf" }
stty = { optional=true, version="0.0.14", package="uu_stty", path="src/uu/stty" }
sum = { optional=true, version="0.0.14", package="uu_sum", path="src/uu/sum" }
sync = { optional=true, version="0.0.14", package="uu_sync", path="src/uu/sync" }
tac = { optional=true, version="0.0.14", package="uu_tac", path="src/uu/tac" }
@ -402,7 +404,7 @@ hex-literal = "0.3.1"
rlimit = "0.8.3"
[target.'cfg(unix)'.dev-dependencies]
nix = { version = "0.24.2", default-features = false, features = ["process", "signal", "user"] }
nix = { version = "0.25", default-features = false, features = ["process", "signal", "user"] }
rust-users = { version="0.11", package="users" }
unix_socket = "0.5.0"

186
README.md
View file

@ -17,6 +17,8 @@
uutils is an attempt at writing universal (as in cross-platform) CLI
utilities in [Rust](http://www.rust-lang.org).
While all programs hve been implemented, some options might be missing
or different behavior might be experienced.
To install it:
@ -408,98 +410,98 @@ Please note that this is not fully accurate:
See https://github.com/uutils/coreutils/issues/3336 for the main meta bugs
(many are missing).
| Done | WIP | To Do |
|-----------|-----------|--------|
| arch | cp | stty |
| base32 | date | |
| base64 | dd | |
| basename | df | |
| basenc | expr | |
| cat | install | |
| chcon | ls | |
| chgrp | more | |
| chmod | numfmt | |
| chown | od (`--strings` and 128-bit data types missing) | |
| chroot | pr | |
| cksum | printf | |
| comm | sort | |
| csplit | split | |
| cut | tac | |
| dircolors | test | |
| dirname | dir | |
| du | vdir | |
| echo | | |
| env | | |
| expand | | |
| factor | | |
| false | | |
| fmt | | |
| fold | | |
| groups | | |
| hashsum | | |
| head | | |
| hostid | | |
| hostname | | |
| id | | |
| join | | |
| kill | | |
| link | | |
| ln | | |
| logname | | |
| ~~md5sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | | |
| ~~sha1sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | | |
| ~~sha224sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | | |
| ~~sha256sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | | |
| ~~sha384sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | | |
| ~~sha512sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | | |
| mkdir | | |
| mkfifo | | |
| mknod | | |
| mktemp | | |
| mv | | |
| nice | | |
| nl | | |
| nohup | | |
| nproc | | |
| paste | | |
| pathchk | | |
| pinky | | |
| printenv | | |
| ptx | | |
| pwd | | |
| readlink | | |
| realpath | | |
| relpath | | |
| rm | | |
| rmdir | | |
| runcon | | |
| seq | | |
| shred | | |
| shuf | | |
| sleep | | |
| stat | | |
| stdbuf | | |
| sum | | |
| sync | | |
| tail | | |
| tee | | |
| timeout | | |
| touch | | |
| tr | | |
| true | | |
| truncate | | |
| tsort | | |
| tty | | |
| uname | | |
| unexpand | | |
| uniq | | |
| unlink | | |
| uptime | | |
| users | | |
| wc | | |
| who | | |
| whoami | | |
| yes | | |
| Done | WIP |
|-----------|-----------|
| arch | cp |
| base32 | date |
| base64 | dd |
| basename | df |
| basenc | expr |
| cat | install |
| chcon | ls |
| chgrp | more |
| chmod | numfmt |
| chown | od (`--strings` and 128-bit data types missing) |
| chroot | pr |
| cksum | printf |
| comm | sort |
| csplit | split |
| cut | tac |
| dircolors | test |
| dirname | dir |
| du | vdir |
| echo | stty |
| env | |
| expand | |
| factor | |
| false | |
| fmt | |
| fold | |
| groups | |
| hashsum | |
| head | |
| hostid | |
| hostname | |
| id | |
| join | |
| kill | |
| link | |
| ln | |
| logname | |
| ~~md5sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | |
| ~~sha1sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | |
| ~~sha224sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | |
| ~~sha256sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | |
| ~~sha384sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | |
| ~~sha512sum~~ (replaced by [hashsum](https://github.com/uutils/coreutils/blob/main/src/uu/hashsum/src/hashsum.rs)) | |
| mkdir | |
| mkfifo | |
| mknod | |
| mktemp | |
| mv | |
| nice | |
| nl | |
| nohup | |
| nproc | |
| paste | |
| pathchk | |
| pinky | |
| printenv | |
| ptx | |
| pwd | |
| readlink | |
| realpath | |
| relpath | |
| rm | |
| rmdir | |
| runcon | |
| seq | |
| shred | |
| shuf | |
| sleep | |
| stat | |
| stdbuf | |
| sum | |
| sync | |
| tail | |
| tee | |
| timeout | |
| touch | |
| tr | |
| true | |
| truncate | |
| tsort | |
| tty | |
| uname | |
| unexpand | |
| uniq | |
| unlink | |
| uptime | |
| users | |
| wc | |
| who | |
| whoami | |
| yes | |
## License

View file

@ -30,6 +30,7 @@ allow = [
"BSD-3-Clause",
"CC0-1.0",
"MPL-2.0", # XXX considered copyleft?
"Unicode-DFS-2016",
]
copyleft = "deny"
allow-osi-fsf-free = "neither"
@ -69,8 +70,6 @@ skip = [
{ name = "arrayvec", version = "=0.7.2" },
# flimit/unix_socket
{ name = "cfg-if", version = "=0.1.10" },
# indexmap
{ name = "hashbrown", version = "=0.11.2" },
# kernel32-sys
{ name = "winapi", version = "=0.2.8" },
# bindgen 0.59.2

View file

@ -1 +0,0 @@
include!("../src/bin/coreutils.rs");

View file

@ -1 +0,0 @@
include!("../src/bin/coreutils.rs");

View file

@ -147,22 +147,19 @@ fn gen_completions<T: uucore::Args>(
)
.arg(
Arg::new("shell")
.value_parser(clap::builder::PossibleValuesParser::new(
Shell::possible_values(),
))
.value_parser(clap::builder::EnumValueParser::<Shell>::new())
.required(true),
)
.get_matches_from(std::iter::once(OsString::from("completion")).chain(args));
let utility = matches.value_of("utility").unwrap();
let shell = matches.value_of("shell").unwrap();
let shell = matches.get_one::<Shell>("shell").unwrap().to_owned();
let mut command = if utility == "coreutils" {
gen_coreutils_app(util_map)
} else {
util_map.get(utility).unwrap().1()
};
let shell: Shell = shell.parse().unwrap();
let bin_name = std::env::var("PROG_PREFIX").unwrap_or_default() + utility;
clap_complete::generate(shell, &mut command, bin_name, &mut io::stdout());

View file

@ -15,7 +15,7 @@ edition = "2021"
path = "src/arch.rs"
[dependencies]
platform-info = "0.2"
platform-info = "1.0.0"
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -12,7 +12,7 @@ use std::io::{stdout, Read, Write};
use uucore::display::Quotable;
use uucore::encoding::{wrap_print, Data, Format};
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
use std::fs::File;
use std::io::{BufReader, Stdin};
@ -87,9 +87,7 @@ impl Config {
pub fn parse_base_cmd_args(args: impl uucore::Args, about: &str, usage: &str) -> UResult<Config> {
let command = base_app(about, usage);
let arg_list = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let arg_list = args.collect_lossy();
Config::from(&command.try_get_matches_from(arg_list)?)
}

View file

@ -11,7 +11,7 @@ use clap::{crate_version, Arg, Command};
use std::path::{is_separator, PathBuf};
use uucore::display::Quotable;
use uucore::error::{UResult, UUsageError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = r#"Print NAME with any leading directory components removed
If specified, also remove a trailing SUFFIX"#;
@ -28,9 +28,7 @@ pub mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
// Since options have to go before names,
// if the first argument is not an option, then there is no option,

View file

@ -14,7 +14,6 @@ use uu_base32::base_common::{self, Config, BASE_CMD_PARSE_ERROR};
use uucore::{
encoding::Format,
error::{UResult, UUsageError},
InvalidEncodingHandling,
};
use std::io::{stdin, Read};
@ -52,10 +51,7 @@ pub fn uu_app<'a>() -> Command<'a> {
fn parse_cmd_args(args: impl uucore::Args) -> UResult<(Config, Format)> {
let matches = uu_app()
.try_get_matches_from(
args.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any(),
)
.try_get_matches_from(args.collect_lossy())
.with_exit_code(1)?;
let format = ENCODINGS
.iter()

View file

@ -22,7 +22,7 @@ uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=[
[target.'cfg(unix)'.dependencies]
unix_socket = "0.5.0"
nix = { version = "0.24.2", default-features = false }
nix = { version = "0.25", default-features = false }
[[bin]]
name = "cat"

View file

@ -36,7 +36,7 @@ use std::net::Shutdown;
use std::os::unix::fs::FileTypeExt;
#[cfg(unix)]
use unix_socket::UnixStream;
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static NAME: &str = "cat";
static USAGE: &str = "{} [OPTION]... [FILE]...";
@ -184,9 +184,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().try_get_matches_from(args)?;

View file

@ -357,9 +357,9 @@ fn parse_command_line(config: clap::Command, args: impl uucore::Args) -> Result<
// By default, do not preserve root.
let preserve_root = matches.contains_id(options::preserve_root::PRESERVE_ROOT);
let mut files = matches.values_of_os("FILE").unwrap_or_default();
let mut files = matches.get_many::<PathBuf>("FILE").unwrap_or_default();
let mode = if let Some(path) = matches.value_of_os(options::REFERENCE) {
let mode = if let Some(path) = matches.get_one::<OsString>(options::REFERENCE) {
CommandLineMode::ReferenceBased {
reference: PathBuf::from(path),
}
@ -369,10 +369,10 @@ fn parse_command_line(config: clap::Command, args: impl uucore::Args) -> Result<
|| matches.contains_id(options::RANGE)
{
CommandLineMode::Custom {
user: matches.value_of_os(options::USER).map(Into::into),
role: matches.value_of_os(options::ROLE).map(Into::into),
the_type: matches.value_of_os(options::TYPE).map(Into::into),
range: matches.value_of_os(options::RANGE).map(Into::into),
user: matches.get_one::<OsString>(options::USER).map(Into::into),
role: matches.get_one::<OsString>(options::ROLE).map(Into::into),
the_type: matches.get_one::<OsString>(options::TYPE).map(Into::into),
range: matches.get_one::<OsString>(options::RANGE).map(Into::into),
}
} else if let Some(context) = files.next() {
CommandLineMode::ContextBased {

View file

@ -16,7 +16,7 @@ path = "src/chmod.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs", "mode"] }
[[bin]]

View file

@ -18,7 +18,7 @@ use uucore::fs::is_symlink;
use uucore::libc::mode_t;
#[cfg(not(windows))]
use uucore::mode;
use uucore::{format_usage, show_error, InvalidEncodingHandling};
use uucore::{format_usage, show_error};
static ABOUT: &str = "Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.";
@ -46,9 +46,7 @@ fn get_long_usage() -> String {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let mut args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let mut args = args.collect_lossy();
// Before we can parse 'args' with clap (and previously getopts),
// a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").

View file

@ -17,7 +17,7 @@ use std::path::Path;
use std::process;
use uucore::error::{set_exit_code, UResult};
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
use uucore::{entries, format_usage, InvalidEncodingHandling};
use uucore::{entries, format_usage};
static ABOUT: &str = "Run COMMAND with root directory set to NEWROOT.";
static USAGE: &str = "{} [OPTION]... NEWROOT [COMMAND [ARG]...]";
@ -33,9 +33,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -12,7 +12,6 @@ use std::io::{self, stdin, BufReader, Read};
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, show};
// NOTE: CRC_TABLE_LEN *must* be <= 256 as we cast 0..CRC_TABLE_LEN to u8
@ -114,9 +113,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);

View file

@ -13,7 +13,7 @@ use std::io::{self, stdin, BufRead, BufReader, Stdin};
use std::path::Path;
use uucore::error::FromIo;
use uucore::error::UResult;
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
use clap::{crate_version, Arg, ArgMatches, Command};
@ -132,9 +132,7 @@ fn open_file(name: &str) -> io::Result<LineReader> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);
let filename1 = matches.value_of(options::FILE_1).unwrap();

View file

@ -21,7 +21,7 @@ path = "src/cp.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
filetime = "0.2"
libc = "0.2.126"
libc = "0.2.132"
quick-error = "2.0.1"
selinux = { version="0.2", optional=true }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs", "perms", "mode"] }

View file

@ -46,7 +46,7 @@ use std::path::{Path, PathBuf, StripPrefixError};
use std::str::FromStr;
use std::string::ToString;
use uucore::backup_control::{self, BackupMode};
use uucore::error::{set_exit_code, ExitCode, UClapError, UError, UResult};
use uucore::error::{set_exit_code, UClapError, UError, UResult, UUsageError};
use uucore::fs::{canonicalize, is_symlink, MissingHandling, ResolveMode};
use walkdir::WalkDir;
@ -498,8 +498,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let options = Options::from_matches(&matches)?;
if options.overwrite == OverwriteMode::NoClobber && options.backup != BackupMode::NoBackup {
show_usage_error!("options --backup and --no-clobber are mutually exclusive");
return Err(ExitCode(EXIT_ERR).into());
return Err(UUsageError::new(
EXIT_ERR,
"options --backup and --no-clobber are mutually exclusive",
));
}
let paths: Vec<String> = matches

View file

@ -16,7 +16,7 @@ use clap::{crate_version, Arg, ArgMatches, Command};
use regex::Regex;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
mod csplit_error;
mod patterns;
@ -713,9 +713,7 @@ mod tests {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);

View file

@ -19,8 +19,8 @@ use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
use self::searcher::Searcher;
use uucore::format_usage;
use uucore::ranges::Range;
use uucore::{format_usage, InvalidEncodingHandling};
mod searcher;
@ -398,9 +398,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let delimiter_is_equal = args.contains(&"-d=".to_string()); // special case
let matches = uu_app().get_matches_from(args);

View file

@ -37,7 +37,7 @@ use clap::{crate_version, Arg, ArgMatches, Command};
use gcd::Gcd;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
use uucore::{show_error, InvalidEncodingHandling};
use uucore::show_error;
const ABOUT: &str = "copy, and optionally convert, a file system resource";
const BUF_INIT_BYTE: u8 = 0xDD;
@ -146,7 +146,7 @@ impl Input<File> {
}
opts.open(fname)
.map_err_context(|| "failed to open input file".to_string())?
.map_err_context(|| format!("failed to open {}", fname.quote()))?
};
// The --skip and --iseek flags are additive. On a file, they seek.
@ -706,8 +706,7 @@ fn append_dashes_if_not_present(mut acc: Vec<String>, mut s: String) -> Vec<Stri
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let dashed_args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any()
.collect_ignore()
.into_iter()
.fold(Vec::new(), append_dashes_if_not_present);

View file

@ -35,6 +35,7 @@ pub enum ParseError {
IbsOutOfRange,
ObsOutOfRange,
CbsOutOfRange,
InvalidNumber(String),
}
impl ParseError {
@ -56,6 +57,7 @@ impl ParseError {
Self::IbsOutOfRange => Self::IbsOutOfRange,
Self::ObsOutOfRange => Self::ObsOutOfRange,
Self::CbsOutOfRange => Self::CbsOutOfRange,
Self::InvalidNumber(_) => Self::InvalidNumber(s),
}
}
}
@ -79,7 +81,12 @@ impl std::fmt::Display for ParseError {
write!(f, "Only one ov conv=excl or conv=nocreat may be specified")
}
Self::FlagNoMatch(arg) => {
write!(f, "Unrecognized iflag=FLAG or oflag=FLAG -> {}", arg)
// Additional message about 'dd --help' is displayed only in this situation.
write!(
f,
"invalid input flag: {}\nTry 'dd --help' for more information.",
arg
)
}
Self::ConvFlagNoMatch(arg) => {
write!(f, "Unrecognized conv=CONV -> {}", arg)
@ -115,6 +122,9 @@ impl std::fmt::Display for ParseError {
Self::Unimplemented(arg) => {
write!(f, "feature not implemented on this system -> {}", arg)
}
Self::InvalidNumber(arg) => {
write!(f, "invalid number: {}", arg)
}
}
}
}
@ -389,7 +399,7 @@ fn parse_bytes_no_x(s: &str) -> Result<u64, ParseError> {
(None, None, None) => match uucore::parse_size::parse_size(s) {
Ok(n) => (n, 1),
Err(ParseSizeError::InvalidSuffix(s)) | Err(ParseSizeError::ParseFailure(s)) => {
return Err(ParseError::MultiplierStringParseFailure(s))
return Err(ParseError::InvalidNumber(s))
}
Err(ParseSizeError::SizeTooBig(s)) => {
return Err(ParseError::MultiplierStringOverflow(s))

View file

@ -6,6 +6,7 @@
// * that was distributed with this source code.
use clap::Command;
use std::ffi::OsString;
use std::path::Path;
use uu_ls::{options, Config, Format};
use uucore::error::UResult;
@ -13,7 +14,7 @@ use uucore::quoting_style::{Quotes, QuotingStyle};
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let command = uu_ls::uu_app();
let command = uu_app();
let matches = command.get_matches_from(args);
@ -55,7 +56,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
let locs = matches
.values_of_os(options::PATHS)
.get_many::<OsString>(options::PATHS)
.map(|v| v.map(Path::new).collect())
.unwrap_or_else(|| vec![Path::new(".")]);
@ -64,7 +65,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// To avoid code duplication, we reuse ls uu_app function which has the same
// arguments. However, coreutils won't compile if one of the utils is missing
// an uu_app function, so we need this dummy one.
// an uu_app function, so we return the `ls` app.
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
uu_ls::uu_app()
}

View file

@ -65,9 +65,7 @@ pub fn guess_syntax() -> OutputFmt {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(&args);
@ -278,7 +276,7 @@ enum ParseState {
}
use std::collections::HashMap;
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
fn parse<T>(lines: T, fmt: &OutputFmt, fp: &str) -> Result<String, String>
where

View file

@ -9,7 +9,7 @@ use clap::{crate_version, Arg, Command};
use std::path::Path;
use uucore::display::print_verbatim;
use uucore::error::{UResult, UUsageError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = "strip last component from file name";
const USAGE: &str = "{} [OPTION] NAME...";
@ -28,9 +28,7 @@ fn get_long_usage() -> String {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let after_help = get_long_usage();

View file

@ -39,7 +39,6 @@ use uucore::error::{UError, UResult};
use uucore::format_usage;
use uucore::parse_glob;
use uucore::parse_size::{parse_size, ParseSizeError};
use uucore::InvalidEncodingHandling;
#[cfg(windows)]
use winapi::shared::minwindef::{DWORD, LPVOID};
#[cfg(windows)]
@ -516,9 +515,7 @@ fn build_exclude_patterns(matches: &ArgMatches) -> UResult<Vec<Pattern>> {
#[uucore::main]
#[allow(clippy::cognitive_complexity)]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);

View file

@ -11,7 +11,7 @@ use std::io::{self, Write};
use std::iter::Peekable;
use std::str::Chars;
use uucore::error::{FromIo, UResult};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
const NAME: &str = "echo";
const ABOUT: &str = "display a line of text";
@ -110,9 +110,7 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<bool> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);
let no_newline = matches.contains_id(options::NO_NEWLINE);

View file

@ -22,7 +22,7 @@ use std::str::from_utf8;
use unicode_width::UnicodeWidthChar;
use uucore::display::Quotable;
use uucore::error::{FromIo, UError, UResult};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = "Convert tabs in each FILE to spaces, writing to standard output.
With no FILE, or when FILE is -, read standard input.";
@ -269,9 +269,7 @@ fn expand_shortcuts(args: &[String]) -> Vec<String> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(expand_shortcuts(&args));

View file

@ -7,7 +7,6 @@
use clap::{crate_version, Arg, Command};
use uucore::error::{UResult, USimpleError};
use uucore::InvalidEncodingHandling;
mod syntax_tree;
mod tokens;
@ -33,9 +32,7 @@ pub fn uu_app<'a>() -> Command<'a> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
// For expr utility we do not want getopts.
// The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)`

View file

@ -13,7 +13,7 @@ use std::io::{stdin, BufRead, BufReader, Read};
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
const TAB_WIDTH: usize = 8;
@ -31,9 +31,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let (args, obs_width) = handle_obsolete(&args[..]);
let matches = uu_app().get_matches_from(args);

View file

@ -320,8 +320,8 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
warn,
};
match matches.values_of_os("FILE") {
Some(files) => hashsum(opts, files),
match matches.get_many::<OsString>("FILE") {
Some(files) => hashsum(opts, files.map(|f| f.as_os_str())),
None => hashsum(opts, iter::once(OsStr::new("-"))),
}
}

View file

@ -16,7 +16,7 @@ path = "src/hostid.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -18,6 +18,8 @@ path = "src/hostname.rs"
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
hostname = { version = "0.3", features = ["set"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["wide"] }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version="0.3", features=["sysinfoapi", "winsock2"] }
[[bin]]

View file

@ -7,9 +7,9 @@
// spell-checker:ignore (ToDO) MAKEWORD addrs hashset
use std::collections::hash_set::HashSet;
use std::net::ToSocketAddrs;
use std::str;
use std::{collections::hash_set::HashSet, ffi::OsString};
use clap::{crate_version, Arg, ArgMatches, Command};
@ -65,7 +65,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
#[cfg(windows)]
let _handle = wsa::start().map_err_context(|| "failed to start Winsock".to_owned())?;
match matches.value_of_os(OPT_HOST) {
match matches.get_one::<OsString>(OPT_HOST) {
None => display_hostname(&matches),
Some(host) => hostname::set(host).map_err_context(|| "failed to set hostname".to_owned()),
}

View file

@ -15,6 +15,7 @@ use memchr::{memchr3_iter, memchr_iter};
use std::cmp::Ordering;
use std::convert::From;
use std::error::Error;
use std::ffi::OsString;
use std::fmt::Display;
use std::fs::File;
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Split, Stdin, Write};
@ -627,7 +628,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
settings.key1 = get_field_number(keys, key1)?;
settings.key2 = get_field_number(keys, key2)?;
if let Some(value_os) = matches.value_of_os("t") {
if let Some(value_os) = matches.get_one::<OsString>("t") {
#[cfg(unix)]
let value = value_os.as_bytes();
#[cfg(not(unix))]

View file

@ -16,7 +16,7 @@ path = "src/kill.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
nix = { version = "0.24.2", features = ["signal"] }
nix = { version = "0.25", features = ["signal"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["signals"] }
[[bin]]

View file

@ -16,8 +16,8 @@ use nix::unistd::Pid;
use std::io::Error;
use uucore::display::Quotable;
use uucore::error::{FromIo, UError, UResult, USimpleError};
use uucore::format_usage;
use uucore::signals::{signal_by_name_or_value, ALL_SIGNALS};
use uucore::{format_usage, InvalidEncodingHandling};
static ABOUT: &str = "Send signal to processes or list information about signals.";
const USAGE: &str = "{} [OPTIONS]... PID...";
@ -38,9 +38,7 @@ pub enum Mode {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let mut args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let mut args = args.collect_ignore();
let obs_signal = handle_obsolete(&mut args);
let matches = uu_app().get_matches_from(args);

View file

@ -5,6 +5,7 @@
// * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code.
use clap::{crate_version, Arg, Command};
use std::ffi::OsString;
use std::fs::hard_link;
use std::path::Path;
use uucore::display::Quotable;
@ -23,7 +24,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().get_matches_from(args);
let files: Vec<_> = matches
.values_of_os(options::FILES)
.get_many::<OsString>(options::FILES)
.unwrap_or_default()
.collect();
let old = Path::new(files[0]);

View file

@ -15,7 +15,7 @@ edition = "2021"
path = "src/logname.rs"
[dependencies]
libc = "0.2.126"
libc = "0.2.132"
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -15,7 +15,6 @@ extern crate uucore;
use clap::{crate_version, Command};
use std::ffi::CStr;
use uucore::error::UResult;
use uucore::InvalidEncodingHandling;
extern "C" {
// POSIX requires using getlogin (or equivalent code)
@ -37,9 +36,7 @@ static ABOUT: &str = "Print user's login name";
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let _ = uu_app().get_matches_from(args);

View file

@ -22,9 +22,9 @@ number_prefix = "0.4"
term_grid = "0.1.5"
termsize = "0.1.6"
glob = "0.3.0"
lscolors = { version = "0.11.0", features = ["ansi_term"] }
lscolors = { version = "0.12.0", features = ["ansi_term"] }
uucore = { version = ">=0.0.8", package = "uucore", path = "../../uucore", features = ["entries", "fs"] }
once_cell = "1.13.0"
once_cell = "1.13.1"
atty = "0.2"
selinux = { version="0.2", optional = true }

View file

@ -898,7 +898,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let config = Config::from(&matches)?;
let locs = matches
.values_of_os(options::PATHS)
.get_many::<OsString>(options::PATHS)
.map(|v| v.map(Path::new).collect())
.unwrap_or_else(|| vec![Path::new(".")]);

View file

@ -10,15 +10,17 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, Arg, ArgMatches, Command, OsValues};
use clap::parser::ValuesRef;
use clap::{crate_version, Arg, ArgMatches, Command};
use std::ffi::OsString;
use std::path::{Path, PathBuf};
#[cfg(not(windows))]
use uucore::error::FromIo;
use uucore::error::{UResult, USimpleError};
use uucore::format_usage;
#[cfg(not(windows))]
use uucore::mode;
use uucore::{display::Quotable, fs::dir_strip_dot_for_creation};
use uucore::{format_usage, InvalidEncodingHandling};
static DEFAULT_PERM: u32 = 0o755;
@ -83,9 +85,7 @@ fn strip_minus_from_mode(args: &mut Vec<String>) -> bool {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let mut args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let mut args = args.collect_lossy();
// Before we can parse 'args' with clap (and previously getopts),
// a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").
@ -97,7 +97,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// " of each created directory to CTX"),
let matches = uu_app().after_help(&after_help[..]).get_matches_from(args);
let dirs = matches.values_of_os(options::DIRS).unwrap_or_default();
let dirs = matches
.get_many::<OsString>(options::DIRS)
.unwrap_or_default();
let verbose = matches.contains_id(options::VERBOSE);
let recursive = matches.contains_id(options::PARENTS);
@ -145,7 +147,7 @@ pub fn uu_app<'a>() -> Command<'a> {
/**
* Create the list of new directories
*/
fn exec(dirs: OsValues, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
fn exec(dirs: ValuesRef<OsString>, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
for dir in dirs {
// Special case to match GNU's behavior:
// mkdir -p foo/. should work and just create foo/

View file

@ -16,7 +16,7 @@ path = "src/mkfifo.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -11,9 +11,9 @@ extern crate uucore;
use clap::{crate_version, Arg, Command};
use libc::mkfifo;
use std::ffi::CString;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError};
use uucore::format_usage;
use uucore::{display::Quotable, InvalidEncodingHandling};
static NAME: &str = "mkfifo";
static USAGE: &str = "{} [OPTION]... NAME...";
@ -28,9 +28,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);

View file

@ -17,7 +17,7 @@ path = "src/mknod.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "^0.2.126"
libc = "^0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["mode"] }
[[bin]]

View file

@ -15,7 +15,7 @@ use libc::{S_IFBLK, S_IFCHR, S_IFIFO, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOT
use uucore::display::Quotable;
use uucore::error::{set_exit_code, UResult, USimpleError, UUsageError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = "Create the special file NAME of the given TYPE.";
static USAGE: &str = "{} [OPTION]... NAME TYPE [MAJOR MINOR]";
@ -81,9 +81,7 @@ fn _mknod(file_name: &str, mode: mode_t, dev: dev_t) -> i32 {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
// Linux-specific options, not implemented
// opts.optflag("Z", "", "set the SELinux security context to default type");
// opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX");

View file

@ -316,7 +316,7 @@ impl Params {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args.collect_str_lossy().accept_any();
let args = args.collect_lossy();
let matches = uu_app().try_get_matches_from(&args)?;

View file

@ -23,7 +23,7 @@ unicode-width = "0.1.7"
unicode-segmentation = "1.9.0"
[target.'cfg(all(unix, not(target_os = "fuchsia")))'.dependencies]
nix = { version = "0.24.2", default-features = false }
nix = { version = "0.25", default-features = false }
[[bin]]
name = "more"

View file

@ -18,6 +18,7 @@ use std::{
extern crate nix;
use clap::{crate_version, Arg, Command};
use crossterm::event::KeyEventKind;
use crossterm::{
event::{self, Event, KeyCode, KeyEvent, KeyModifiers},
execute, queue,
@ -229,13 +230,21 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool)
let mut wrong_key = None;
if event::poll(Duration::from_millis(10)).unwrap() {
match event::read().unwrap() {
Event::Key(KeyEvent {
kind: KeyEventKind::Release,
..
}) => continue,
Event::Key(KeyEvent {
code: KeyCode::Char('q'),
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
..
})
| Event::Key(KeyEvent {
code: KeyCode::Char('c'),
modifiers: KeyModifiers::CONTROL,
kind: KeyEventKind::Press,
..
}) => {
reset_term(stdout);
std::process::exit(0);
@ -243,10 +252,12 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool)
Event::Key(KeyEvent {
code: KeyCode::Down,
modifiers: KeyModifiers::NONE,
..
})
| Event::Key(KeyEvent {
code: KeyCode::Char(' '),
modifiers: KeyModifiers::NONE,
..
}) => {
if pager.should_close() {
return Ok(());
@ -257,12 +268,14 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool)
Event::Key(KeyEvent {
code: KeyCode::Up,
modifiers: KeyModifiers::NONE,
..
}) => {
pager.page_up();
}
Event::Key(KeyEvent {
code: KeyCode::Char('j'),
modifiers: KeyModifiers::NONE,
..
}) => {
if pager.should_close() {
return Ok(());
@ -273,6 +286,7 @@ fn more(buff: &str, stdout: &mut Stdout, next_file: Option<&str>, silent: bool)
Event::Key(KeyEvent {
code: KeyCode::Char('k'),
modifiers: KeyModifiers::NONE,
..
}) => {
pager.prev_line();
}

View file

@ -92,7 +92,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
let files: Vec<OsString> = matches
.values_of_os(ARG_FILES)
.get_many::<OsString>(ARG_FILES)
.unwrap_or_default()
.map(|v| v.to_os_string())
.collect();
@ -115,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
suffix: backup_suffix,
update: matches.contains_id(OPT_UPDATE),
target_dir: matches
.value_of_os(OPT_TARGET_DIRECTORY)
.get_one::<OsString>(OPT_TARGET_DIRECTORY)
.map(OsString::from),
no_target_dir: matches.contains_id(OPT_NO_TARGET_DIRECTORY),
verbose: matches.contains_id(OPT_VERBOSE),

View file

@ -16,8 +16,8 @@ path = "src/nice.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
nix = { version = "0.24.2", default-features = false }
libc = "0.2.132"
nix = { version = "0.25", default-features = false }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -14,7 +14,7 @@ use std::io::{stdin, BufRead, BufReader, Read};
use std::iter::repeat;
use std::path::Path;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
mod helper;
@ -84,9 +84,7 @@ pub mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -16,7 +16,7 @@ path = "src/nohup.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
atty = "0.2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }

View file

@ -22,7 +22,7 @@ use std::os::unix::prelude::*;
use std::path::{Path, PathBuf};
use uucore::display::Quotable;
use uucore::error::{set_exit_code, UError, UResult};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = "Run COMMAND ignoring hangup signals.";
static LONG_HELP: &str = "
@ -86,9 +86,7 @@ impl Display for NohupError {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -15,7 +15,7 @@ edition = "2021"
path = "src/nproc.rs"
[dependencies]
libc = "0.2.126"
libc = "0.2.132"
num_cpus = "1.10"
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }

View file

@ -14,6 +14,7 @@ use std::io::{BufRead, Write};
use units::{IEC_BASES, SI_BASES};
use uucore::display::Quotable;
use uucore::error::UResult;
use uucore::format_usage;
use uucore::ranges::Range;
use uucore::{format_usage, help_section, help_usage, InvalidEncodingHandling};
@ -227,9 +228,7 @@ fn concat_format_arg_and_value(args: &[String]) -> Vec<String> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(concat_format_arg_and_value(&args));

View file

@ -48,7 +48,6 @@ use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError};
use uucore::format_usage;
use uucore::parse_size::ParseSizeError;
use uucore::InvalidEncodingHandling;
const PEEK_BUFFER_SIZE: usize = 4; // utf-8 can be 4 bytes
static ABOUT: &str = "dump files in octal and other formats";
@ -256,9 +255,7 @@ impl OdOptions {
/// opens the input and calls `odfunc` to process the input.
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let clap_opts = uu_app();

View file

@ -16,7 +16,7 @@ path = "src/pathchk.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -13,7 +13,7 @@ use std::fs;
use std::io::{ErrorKind, Write};
use uucore::display::Quotable;
use uucore::error::{set_exit_code, UResult, UUsageError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
// operating mode
enum Mode {
@ -39,9 +39,7 @@ const POSIX_NAME_MAX: usize = 14;
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -20,7 +20,7 @@ use std::os::unix::fs::MetadataExt;
use clap::{crate_version, Arg, Command};
use std::path::PathBuf;
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = "lightweight finger";
const USAGE: &str = "{} [OPTION]... [USER]...";
@ -49,9 +49,7 @@ fn get_long_usage() -> String {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let after_help = get_long_usage();

View file

@ -378,9 +378,7 @@ pub fn uu_app<'a>() -> Command<'a> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(uucore::InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let opt_args = recreate_arguments(&args);

View file

@ -4,7 +4,6 @@
use clap::{crate_version, Arg, Command};
use uucore::error::{UResult, UUsageError};
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, memo};
const VERSION: &str = "version";
@ -271,9 +270,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);
let format_string = matches

View file

@ -19,7 +19,7 @@ use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
use std::num::ParseIntError;
use uucore::display::Quotable;
use uucore::error::{FromIo, UError, UResult};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static NAME: &str = "ptx";
const USAGE: &str = "\
@ -722,9 +722,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
// let mut opts = Options::new();
let matches = uu_app().get_matches_from(args);

View file

@ -12,8 +12,8 @@ use std::env;
use std::path::{Path, PathBuf};
use uucore::display::println_verbatim;
use uucore::error::{FromIo, UResult};
use uucore::format_usage;
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};
use uucore::{format_usage, InvalidEncodingHandling};
static ABOUT: &str = "Convert TO destination to the relative path from the FROM dir.
If FROM path is omitted, current working dir will be used.";
@ -27,9 +27,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -17,7 +17,7 @@ path = "src/rmdir.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
libc = "0.2.126"
libc = "0.2.132"
[[bin]]
name = "rmdir"

View file

@ -11,6 +11,7 @@
extern crate uucore;
use clap::{crate_version, Arg, Command};
use std::ffi::OsString;
use std::fs::{read_dir, remove_dir};
use std::io;
use std::path::Path;
@ -40,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
};
for path in matches
.values_of_os(ARG_DIRS)
.get_many::<OsString>(ARG_DIRS)
.unwrap_or_default()
.map(Path::new)
{

View file

@ -212,7 +212,7 @@ fn parse_command_line(config: Command, args: impl uucore::Args) -> Result<Option
let compute_transition_context = matches.contains_id(options::COMPUTE);
let mut args = matches
.values_of_os("ARG")
.get_many::<OsString>("ARG")
.unwrap_or_default()
.map(OsString::from);
@ -226,10 +226,10 @@ fn parse_command_line(config: Command, args: impl uucore::Args) -> Result<Option
let mode = CommandLineMode::CustomContext {
compute_transition_context,
user: matches.value_of_os(options::USER).map(Into::into),
role: matches.value_of_os(options::ROLE).map(Into::into),
the_type: matches.value_of_os(options::TYPE).map(Into::into),
range: matches.value_of_os(options::RANGE).map(Into::into),
user: matches.get_one::<OsString>(options::USER).map(Into::into),
role: matches.get_one::<OsString>(options::ROLE).map(Into::into),
the_type: matches.get_one::<OsString>(options::TYPE).map(Into::into),
range: matches.get_one::<OsString>(options::RANGE).map(Into::into),
command: args.next(),
};

View file

@ -20,7 +20,7 @@ use std::io::SeekFrom;
use std::path::{Path, PathBuf};
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::{format_usage, util_name, InvalidEncodingHandling};
use uucore::{format_usage, util_name};
#[macro_use]
extern crate uucore;
@ -266,9 +266,7 @@ pub mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);

View file

@ -15,7 +15,7 @@ use std::fs::File;
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
mod rand_read_adapter;
@ -56,9 +56,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -47,9 +47,9 @@ use std::str::Utf8Error;
use unicode_width::UnicodeWidthStr;
use uucore::display::Quotable;
use uucore::error::{set_exit_code, strip_errno, UError, UResult, USimpleError, UUsageError};
use uucore::format_usage;
use uucore::parse_size::{parse_size, ParseSizeError};
use uucore::version_cmp::version_cmp;
use uucore::{format_usage, InvalidEncodingHandling};
use crate::tmp_dir::TmpDirWrapper;
@ -1055,9 +1055,7 @@ fn make_sort_mode_arg<'a>(mode: &'a str, short: char, help: &'a str) -> Arg<'a>
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let mut settings: GlobalSettings = Default::default();
let matches = match uu_app().try_get_matches_from(args) {
@ -1081,7 +1079,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// check whether user specified a zero terminated list of files for input, otherwise read files from args
let mut files: Vec<OsString> = if matches.contains_id(options::FILES0_FROM) {
let files0_from: Vec<OsString> = matches
.values_of_os(options::FILES0_FROM)
.get_many::<OsString>(options::FILES0_FROM)
.map(|v| v.map(ToOwned::to_owned).collect())
.unwrap_or_default();
@ -1099,7 +1097,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
files
} else {
matches
.values_of_os(options::FILES)
.get_many::<OsString>(options::FILES)
.map(|v| v.map(ToOwned::to_owned).collect())
.unwrap_or_default()
};
@ -1203,7 +1201,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
));
}
if let Some(arg) = matches.value_of_os(options::SEPARATOR) {
if let Some(arg) = matches.get_one::<OsString>(options::SEPARATOR) {
let mut separator = arg.to_str().ok_or_else(|| {
UUsageError::new(
2,

View file

@ -474,7 +474,7 @@ impl Stater {
fn new(matches: &ArgMatches) -> UResult<Self> {
let files = matches
.values_of_os(ARG_FILES)
.get_many::<OsString>(ARG_FILES)
.map(|v| v.map(OsString::from).collect())
.unwrap_or_default();
let format_str = if matches.contains_id(options::PRINTF) {

View file

@ -19,8 +19,8 @@ use std::process;
use tempfile::tempdir;
use tempfile::TempDir;
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::format_usage;
use uucore::parse_size::parse_size;
use uucore::{format_usage, InvalidEncodingHandling};
static ABOUT: &str =
"Run COMMAND, with modified buffering operations for its standard streams.\n\n\
@ -156,9 +156,7 @@ fn get_preload_env(tmp_dir: &mut TempDir) -> io::Result<(String, PathBuf)> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(args);

24
src/uu/stty/Cargo.toml Normal file
View file

@ -0,0 +1,24 @@
[package]
name = "uu_stty"
version = "0.0.14"
authors = ["uutils developers"]
license = "MIT"
description = "stty ~ (uutils) print or change terminal characteristics"
homepage = "https://github.com/uutils/coreutils"
repository = "https://github.com/uutils/coreutils/tree/main/src/uu/stty"
keywords = ["coreutils", "uutils", "cross-platform", "cli", "utility"]
categories = ["command-line-utilities"]
edition = "2021"
[lib]
path = "src/stty.rs"
[dependencies]
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
nix = { version="0.25", features = ["term"] }
[[bin]]
name = "stty"
path = "src/main.rs"

1
src/uu/stty/LICENSE Symbolic link
View file

@ -0,0 +1 @@
../../../LICENSE

315
src/uu/stty/src/flags.rs Normal file
View file

@ -0,0 +1,315 @@
// * This file is part of the uutils coreutils package.
// *
// * For the full copyright and license information, please view the LICENSE file
// * that was distributed with this source code.
// spell-checker:ignore parenb parodd cmspar hupcl cstopb cread clocal crtscts CSIZE
// spell-checker:ignore ignbrk brkint ignpar parmrk inpck istrip inlcr igncr icrnl ixoff ixon iuclc ixany imaxbel iutf
// spell-checker:ignore opost olcuc ocrnl onlcr onocr onlret ofill ofdel nldly crdly tabdly bsdly vtdly ffdly
// spell-checker:ignore isig icanon iexten echoe crterase echok echonl noflsh xcase tostop echoprt prterase echoctl ctlecho echoke crtkill flusho extproc
use crate::Flag;
#[cfg(not(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"
)))]
use nix::sys::termios::BaudRate;
use nix::sys::termios::{ControlFlags as C, InputFlags as I, LocalFlags as L, OutputFlags as O};
pub const CONTROL_FLAGS: &[Flag<C>] = &[
Flag::new("parenb", C::PARENB),
Flag::new("parodd", C::PARODD),
#[cfg(any(
target_os = "android",
all(target_os = "linux", not(target_arch = "mips"))
))]
Flag::new("cmspar", C::CMSPAR),
Flag::new_grouped("cs5", C::CS5, C::CSIZE),
Flag::new_grouped("cs6", C::CS6, C::CSIZE),
Flag::new_grouped("cs7", C::CS7, C::CSIZE),
Flag::new_grouped("cs8", C::CS8, C::CSIZE).sane(),
Flag::new("hupcl", C::HUPCL),
Flag::new("cstopb", C::CSTOPB),
Flag::new("cread", C::CREAD).sane(),
Flag::new("clocal", C::CLOCAL),
Flag::new("crtscts", C::CRTSCTS),
];
pub const INPUT_FLAGS: &[Flag<I>] = &[
Flag::new("ignbrk", I::IGNBRK),
Flag::new("brkint", I::BRKINT).sane(),
Flag::new("ignpar", I::IGNPAR),
Flag::new("parmrk", I::PARMRK),
Flag::new("inpck", I::INPCK),
Flag::new("istrip", I::ISTRIP),
Flag::new("inlcr", I::INLCR),
Flag::new("igncr", I::IGNCR),
Flag::new("icrnl", I::ICRNL).sane(),
Flag::new("ixoff", I::IXOFF),
Flag::new("tandem", I::IXOFF),
Flag::new("ixon", I::IXON),
// not supported by nix
// Flag::new("iuclc", I::IUCLC),
Flag::new("ixany", I::IXANY),
Flag::new("imaxbel", I::IMAXBEL).sane(),
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
Flag::new("iutf8", I::IUTF8),
];
pub const OUTPUT_FLAGS: &[Flag<O>] = &[
Flag::new("opost", O::OPOST).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "linux",
target_os = "openbsd"
))]
Flag::new("olcuc", O::OLCUC),
Flag::new("ocrnl", O::OCRNL),
Flag::new("onlcr", O::ONLCR).sane(),
Flag::new("onocr", O::ONOCR),
Flag::new("onlret", O::ONLRET),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new("ofill", O::OFILL),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new("ofdel", O::OFDEL),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("nl0", O::NL0, O::NLDLY).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("nl1", O::NL1, O::NLDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("cr0", O::CR0, O::CRDLY).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("cr1", O::CR1, O::CRDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("cr2", O::CR2, O::CRDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("cr3", O::CR3, O::CRDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("tab0", O::TAB0, O::TABDLY).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("tab1", O::TAB1, O::TABDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("tab2", O::TAB2, O::TABDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("tab3", O::TAB3, O::TABDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("bs0", O::BS0, O::BSDLY).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("bs1", O::BS1, O::BSDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("vt0", O::VT0, O::VTDLY).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("vt1", O::VT1, O::VTDLY),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("ff0", O::FF0, O::FFDLY).sane(),
#[cfg(any(
target_os = "android",
target_os = "haiku",
target_os = "ios",
target_os = "linux",
target_os = "macos"
))]
Flag::new_grouped("ff1", O::FF1, O::FFDLY),
];
pub const LOCAL_FLAGS: &[Flag<L>] = &[
Flag::new("isig", L::ISIG).sane(),
Flag::new("icanon", L::ICANON).sane(),
Flag::new("iexten", L::IEXTEN).sane(),
Flag::new("echo", L::ECHO).sane(),
Flag::new("echoe", L::ECHOE).sane(),
Flag::new("crterase", L::ECHOE).hidden().sane(),
Flag::new("echok", L::ECHOK).sane(),
Flag::new("echonl", L::ECHONL),
Flag::new("noflsh", L::NOFLSH),
// Not supported by nix
// Flag::new("xcase", L::XCASE),
Flag::new("tostop", L::TOSTOP),
Flag::new("echoprt", L::ECHOPRT),
Flag::new("prterase", L::ECHOPRT).hidden(),
Flag::new("echoctl", L::ECHOCTL).sane(),
Flag::new("ctlecho", L::ECHOCTL).sane().hidden(),
Flag::new("echoke", L::ECHOKE).sane(),
Flag::new("crtkill", L::ECHOKE).sane().hidden(),
Flag::new("flusho", L::FLUSHO),
Flag::new("extproc", L::EXTPROC),
];
// BSD's use u32 as baud rate, to using the enum is unnecessary.
#[cfg(not(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"
)))]
pub const BAUD_RATES: &[(&str, BaudRate)] = &[
("0", BaudRate::B0),
("50", BaudRate::B50),
("75", BaudRate::B75),
("110", BaudRate::B110),
("134", BaudRate::B134),
("150", BaudRate::B150),
("200", BaudRate::B200),
("300", BaudRate::B300),
("600", BaudRate::B600),
("1200", BaudRate::B1200),
("1800", BaudRate::B1800),
("2400", BaudRate::B2400),
("9600", BaudRate::B9600),
("19200", BaudRate::B19200),
("38400", BaudRate::B38400),
("57600", BaudRate::B57600),
("115200", BaudRate::B115200),
("230400", BaudRate::B230400),
#[cfg(any(target_os = "android", target_os = "linux"))]
("500000", BaudRate::B500000),
#[cfg(any(target_os = "android", target_os = "linux"))]
("576000", BaudRate::B576000),
#[cfg(any(target_os = "android", target_os = "linux",))]
("921600", BaudRate::B921600),
#[cfg(any(target_os = "android", target_os = "linux"))]
("1000000", BaudRate::B1000000),
#[cfg(any(target_os = "android", target_os = "linux"))]
("1152000", BaudRate::B1152000),
#[cfg(any(target_os = "android", target_os = "linux"))]
("1500000", BaudRate::B1500000),
#[cfg(any(target_os = "android", target_os = "linux"))]
("2000000", BaudRate::B2000000),
#[cfg(any(
target_os = "android",
all(target_os = "linux", not(target_arch = "sparc64"))
))]
("2500000", BaudRate::B2500000),
#[cfg(any(
target_os = "android",
all(target_os = "linux", not(target_arch = "sparc64"))
))]
("3000000", BaudRate::B3000000),
#[cfg(any(
target_os = "android",
all(target_os = "linux", not(target_arch = "sparc64"))
))]
("3500000", BaudRate::B3500000),
#[cfg(any(
target_os = "android",
all(target_os = "linux", not(target_arch = "sparc64"))
))]
("4000000", BaudRate::B4000000),
];

1
src/uu/stty/src/main.rs Normal file
View file

@ -0,0 +1 @@
uucore::bin!(uu_stty);

401
src/uu/stty/src/stty.rs Normal file
View file

@ -0,0 +1,401 @@
// * This file is part of the uutils coreutils package.
// *
// * For the full copyright and license information, please view the LICENSE file
// * that was distributed with this source code.
// spell-checker:ignore tcgetattr tcsetattr tcsanow tiocgwinsz tiocswinsz cfgetospeed ushort
mod flags;
use clap::{crate_version, Arg, ArgMatches, Command};
use nix::libc::{c_ushort, TIOCGWINSZ, TIOCSWINSZ};
use nix::sys::termios::{
cfgetospeed, tcgetattr, tcsetattr, ControlFlags, InputFlags, LocalFlags, OutputFlags, Termios,
};
use nix::{ioctl_read_bad, ioctl_write_ptr_bad};
use std::io::{self, stdout};
use std::ops::ControlFlow;
use std::os::unix::io::{AsRawFd, RawFd};
use uucore::error::{UResult, USimpleError};
use uucore::format_usage;
#[cfg(not(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"
)))]
use flags::BAUD_RATES;
use flags::{CONTROL_FLAGS, INPUT_FLAGS, LOCAL_FLAGS, OUTPUT_FLAGS};
const NAME: &str = "stty";
const USAGE: &str = "\
{} [-F DEVICE | --file=DEVICE] [SETTING]...
{} [-F DEVICE | --file=DEVICE] [-a|--all]
{} [-F DEVICE | --file=DEVICE] [-g|--save]";
const SUMMARY: &str = "Print or change terminal characteristics.";
#[derive(Clone, Copy, Debug)]
pub struct Flag<T> {
name: &'static str,
flag: T,
show: bool,
sane: bool,
group: Option<T>,
}
impl<T> Flag<T> {
pub const fn new(name: &'static str, flag: T) -> Self {
Self {
name,
flag,
show: true,
sane: false,
group: None,
}
}
pub const fn new_grouped(name: &'static str, flag: T, group: T) -> Self {
Self {
name,
flag,
show: true,
sane: false,
group: Some(group),
}
}
pub const fn hidden(mut self) -> Self {
self.show = false;
self
}
pub const fn sane(mut self) -> Self {
self.sane = true;
self
}
}
trait TermiosFlag: Copy {
fn is_in(&self, termios: &Termios, group: Option<Self>) -> bool;
fn apply(&self, termios: &mut Termios, val: bool);
}
mod options {
pub const ALL: &str = "all";
pub const SAVE: &str = "save";
pub const FILE: &str = "file";
pub const SETTINGS: &str = "settings";
}
struct Options<'a> {
all: bool,
save: bool,
file: RawFd,
settings: Option<Vec<&'a str>>,
}
impl<'a> Options<'a> {
fn from(matches: &'a ArgMatches) -> io::Result<Self> {
Ok(Self {
all: matches.is_present(options::ALL),
save: matches.is_present(options::SAVE),
file: match matches.value_of(options::FILE) {
Some(_f) => todo!(),
None => stdout().as_raw_fd(),
},
settings: matches.values_of(options::SETTINGS).map(|v| v.collect()),
})
}
}
// Needs to be repr(C) because we pass it to the ioctl calls.
#[repr(C)]
#[derive(Default, Debug)]
pub struct TermSize {
rows: c_ushort,
columns: c_ushort,
x: c_ushort,
y: c_ushort,
}
ioctl_read_bad!(
/// Get terminal window size
tiocgwinsz,
TIOCGWINSZ,
TermSize
);
ioctl_write_ptr_bad!(
/// Set terminal window size
tiocswinsz,
TIOCSWINSZ,
TermSize
);
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);
let opts = Options::from(&matches)?;
stty(&opts)
}
fn stty(opts: &Options) -> UResult<()> {
if opts.save && opts.all {
return Err(USimpleError::new(
1,
"the options for verbose and stty-readable output styles are mutually exclusive",
));
}
if opts.settings.is_some() && (opts.save || opts.all) {
return Err(USimpleError::new(
1,
"when specifying an output style, modes may not be set",
));
}
// TODO: Figure out the right error message for when tcgetattr fails
let mut termios = tcgetattr(opts.file).expect("Could not get terminal attributes");
if let Some(settings) = &opts.settings {
for setting in settings {
if let ControlFlow::Break(false) = apply_setting(&mut termios, setting) {
return Err(USimpleError::new(
1,
format!("invalid argument '{}'", setting),
));
}
}
tcsetattr(opts.file, nix::sys::termios::SetArg::TCSANOW, &termios)
.expect("Could not write terminal attributes");
} else {
print_settings(&termios, opts).expect("TODO: make proper error here from nix error");
}
Ok(())
}
fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> {
let speed = cfgetospeed(termios);
// BSDs use a u32 for the baud rate, so we can simply print it.
#[cfg(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"
))]
print!("speed {} baud; ", speed);
// Other platforms need to use the baud rate enum, so printing the right value
// becomes slightly more complicated.
#[cfg(not(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"
)))]
for (text, baud_rate) in BAUD_RATES {
if *baud_rate == speed {
print!("speed {} baud; ", text);
break;
}
}
if opts.all {
let mut size = TermSize::default();
unsafe { tiocgwinsz(opts.file, &mut size as *mut _)? };
print!("rows {}; columns {}; ", size.rows, size.columns);
}
#[cfg(any(target_os = "linux", target_os = "redox"))]
{
// For some reason the normal nix Termios struct does not expose the line,
// so we get the underlying libc::termios struct to get that information.
let libc_termios: nix::libc::termios = termios.clone().into();
let line = libc_termios.c_line;
print!("line = {};", line);
}
println!();
Ok(())
}
fn print_settings(termios: &Termios, opts: &Options) -> nix::Result<()> {
print_terminal_size(termios, opts)?;
print_flags(termios, opts, CONTROL_FLAGS);
print_flags(termios, opts, INPUT_FLAGS);
print_flags(termios, opts, OUTPUT_FLAGS);
print_flags(termios, opts, LOCAL_FLAGS);
Ok(())
}
fn print_flags<T: TermiosFlag>(termios: &Termios, opts: &Options, flags: &[Flag<T>]) {
let mut printed = false;
for &Flag {
name,
flag,
show,
sane,
group,
} in flags
{
if !show {
continue;
}
let val = flag.is_in(termios, group);
if group.is_some() {
if val && (!sane || opts.all) {
print!("{} ", name);
printed = true;
}
} else if opts.all || val != sane {
if !val {
print!("-");
}
print!("{} ", name);
printed = true;
}
}
if printed {
println!();
}
}
/// Apply a single setting
///
/// The value inside the `Break` variant of the `ControlFlow` indicates whether
/// the setting has been applied.
fn apply_setting(termios: &mut Termios, s: &str) -> ControlFlow<bool> {
let (remove, name) = match s.strip_prefix('-') {
Some(s) => (true, s),
None => (false, s),
};
apply_flag(termios, CONTROL_FLAGS, name, remove)?;
apply_flag(termios, INPUT_FLAGS, name, remove)?;
apply_flag(termios, OUTPUT_FLAGS, name, remove)?;
apply_flag(termios, LOCAL_FLAGS, name, remove)?;
ControlFlow::Break(false)
}
/// Apply a flag to a slice of flags
///
/// The value inside the `Break` variant of the `ControlFlow` indicates whether
/// the setting has been applied.
fn apply_flag<T: TermiosFlag>(
termios: &mut Termios,
flags: &[Flag<T>],
input: &str,
remove: bool,
) -> ControlFlow<bool> {
for Flag {
name, flag, group, ..
} in flags
{
if input == *name {
// Flags with groups cannot be removed
// Since the name matches, we can short circuit and don't have to check the other flags.
if remove && group.is_some() {
return ControlFlow::Break(false);
}
// If there is a group, the bits for that group should be cleared before applying the flag
if let Some(group) = group {
group.apply(termios, false);
}
flag.apply(termios, !remove);
return ControlFlow::Break(true);
}
}
ControlFlow::Continue(())
}
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.name(NAME)
.version(crate_version!())
.override_usage(format_usage(USAGE))
.about(SUMMARY)
.infer_long_args(true)
.arg(
Arg::new(options::ALL)
.short('a')
.long(options::ALL)
.help("print all current settings in human-readable form"),
)
.arg(
Arg::new(options::SAVE)
.short('g')
.long(options::SAVE)
.help("print all current settings in a stty-readable form"),
)
.arg(
Arg::new(options::FILE)
.short('F')
.long(options::FILE)
.takes_value(true)
.value_hint(clap::ValueHint::FilePath)
.value_name("DEVICE")
.help("open and use the specified DEVICE instead of stdin"),
)
.arg(
Arg::new(options::SETTINGS)
.takes_value(true)
.multiple_values(true)
.help("settings to change"),
)
}
impl TermiosFlag for ControlFlags {
fn is_in(&self, termios: &Termios, group: Option<Self>) -> bool {
termios.control_flags.contains(*self)
&& group.map_or(true, |g| !termios.control_flags.intersects(g - *self))
}
fn apply(&self, termios: &mut Termios, val: bool) {
termios.control_flags.set(*self, val);
}
}
impl TermiosFlag for InputFlags {
fn is_in(&self, termios: &Termios, group: Option<Self>) -> bool {
termios.input_flags.contains(*self)
&& group.map_or(true, |g| !termios.input_flags.intersects(g - *self))
}
fn apply(&self, termios: &mut Termios, val: bool) {
termios.input_flags.set(*self, val);
}
}
impl TermiosFlag for OutputFlags {
fn is_in(&self, termios: &Termios, group: Option<Self>) -> bool {
termios.output_flags.contains(*self)
&& group.map_or(true, |g| !termios.output_flags.intersects(g - *self))
}
fn apply(&self, termios: &mut Termios, val: bool) {
termios.output_flags.set(*self, val);
}
}
impl TermiosFlag for LocalFlags {
fn is_in(&self, termios: &Termios, group: Option<Self>) -> bool {
termios.local_flags.contains(*self)
&& group.map_or(true, |g| !termios.local_flags.intersects(g - *self))
}
fn apply(&self, termios: &mut Termios, val: bool) {
termios.local_flags.set(*self, val);
}
}

View file

@ -16,7 +16,7 @@ use std::io::{stdin, Read};
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static NAME: &str = "sum";
static USAGE: &str = "{} [OPTION]... [FILE]...";
@ -109,9 +109,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -16,8 +16,10 @@ path = "src/sync.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["wide"] }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] }
[[bin]]

View file

@ -19,7 +19,6 @@ use std::{
use uucore::display::Quotable;
use uucore::error::UError;
use uucore::error::UResult;
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, show};
use crate::error::TacError;
@ -37,9 +36,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -17,7 +17,7 @@ path = "src/tail.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
notify = { version = "=5.0.0-pre.16", features=["macos_kqueue"]}
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] }
@ -26,7 +26,7 @@ winapi = { version="0.3", features=["fileapi", "handleapi", "processthreadsapi",
winapi-util = { version="0.1.5" }
[target.'cfg(unix)'.dependencies]
nix = { version = "0.24.2", features = ["fs"] }
nix = { version = "0.25", features = ["fs"] }
[[bin]]
name = "tail"

View file

@ -1037,21 +1037,28 @@ fn handle_event(
if settings.follow_descriptor() {
let new_path = event.paths.last().unwrap();
paths.push(new_path.to_owned());
// Open new file and seek to End:
let mut file = File::open(&new_path)?;
file.seek(SeekFrom::End(0))?;
// Remove old reader
let old_reader = files.remove(event_path).reader;
let reader = if old_reader.is_some() {
// Use old reader with the same file descriptor if there is one
old_reader
} else if let Ok(file) = File::open(&new_path) {
// Open new file tail from start
Some(Box::new(BufReader::new(file)) as Box<dyn BufRead>)
} else {
// Probably file was renamed/moved or removed again
None
};
// Add new reader but keep old display name
files.insert(
new_path,
PathData {
metadata: file.metadata().ok(),
reader: Some(Box::new(BufReader::new(file))),
metadata: new_path.metadata().ok(),
reader,
display_name, // mimic GNU's tail and show old name in header
},
files.get_last().unwrap() == event_path
);
// Remove old reader
files.remove(event_path);
// Unwatch old path and watch new path
let _ = watcher.unwatch(event_path);
watcher.watch_with_parent(new_path)?;
@ -1103,8 +1110,8 @@ mod files {
}
/// Wrapper for HashMap::remove using Path::canonicalize
pub fn remove(&mut self, k: &Path) {
self.map.remove(&Self::canonicalize_path(k)).unwrap();
pub fn remove(&mut self, k: &Path) -> PathData {
self.map.remove(&Self::canonicalize_path(k)).unwrap()
}
/// Wrapper for HashMap::get using Path::canonicalize

View file

@ -16,7 +16,7 @@ path = "src/tee.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
retain_mut = "=0.1.7" # ToDO: [2021-01-01; rivy; maint/MinSRV] ~ v0.1.5 uses const generics which aren't stabilized until rust v1.51.0
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc"] }

View file

@ -16,7 +16,7 @@ path = "src/test.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
libc = "0.2.132"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[target.'cfg(target_os = "redox")'.dependencies]

View file

@ -16,8 +16,8 @@ path = "src/timeout.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
nix = { version = "0.24.2", default-features = false, features = ["signal"] }
libc = "0.2.132"
nix = { version = "0.25", default-features = false, features = ["signal"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["process", "signals"] }
[[bin]]

View file

@ -20,9 +20,9 @@ use std::process::{self, Child, Stdio};
use std::time::Duration;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::format_usage;
use uucore::process::ChildExt;
use uucore::signals::{signal_by_name_or_value, signal_name_by_value};
use uucore::{format_usage, InvalidEncodingHandling};
static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION.";
const USAGE: &str = "{} [OPTION] DURATION COMMAND...";
@ -106,9 +106,7 @@ impl Config {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let command = uu_app();

View file

@ -14,6 +14,7 @@ extern crate uucore;
use clap::{crate_version, Arg, ArgGroup, Command};
use filetime::*;
use std::ffi::OsString;
use std::fs::{self, File};
use std::path::{Path, PathBuf};
use time::macros::{format_description, offset, time};
@ -69,7 +70,7 @@ fn dt_to_filename(tm: time::PrimitiveDateTime) -> FileTime {
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().get_matches_from(args);
let files = matches.values_of_os(ARG_FILES).ok_or_else(|| {
let files = matches.get_many::<OsString>(ARG_FILES).ok_or_else(|| {
USimpleError::new(
1,
r##"missing file operand
@ -77,7 +78,7 @@ Try 'touch --help' for more information."##,
)
})?;
let (mut atime, mut mtime) =
if let Some(reference) = matches.value_of_os(options::sources::REFERENCE) {
if let Some(reference) = matches.get_one::<OsString>(options::sources::REFERENCE) {
stat(
Path::new(reference),
!matches.contains_id(options::NO_DEREF),

View file

@ -18,8 +18,8 @@ use std::io::{stdin, stdout, BufReader, BufWriter};
use uucore::{format_usage, show};
use crate::operation::DeleteOperation;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::{display::Quotable, InvalidEncodingHandling};
static ABOUT: &str = "translate or delete characters";
const USAGE: &str = "{} [OPTION]... SET1 [SET2]";
@ -40,9 +40,7 @@ fn get_long_usage() -> String {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let after_help = get_long_usage();

View file

@ -12,7 +12,7 @@ use std::io::{stdin, BufRead, BufReader, Read};
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static ABOUT: &str = "Topological sort the strings in FILE.
Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline).
@ -25,9 +25,7 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let args = args.collect_lossy();
let matches = uu_app().get_matches_from(args);

View file

@ -16,7 +16,7 @@ path = "src/tty.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
libc = "0.2.126"
nix = "0.25"
atty = "0.2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }

View file

@ -10,10 +10,10 @@
// spell-checker:ignore (ToDO) ttyname filedesc
use clap::{crate_version, Arg, Command};
use std::ffi::CStr;
use std::io::Write;
use uucore::error::UResult;
use uucore::{format_usage, InvalidEncodingHandling};
use std::os::unix::io::AsRawFd;
use uucore::error::{set_exit_code, UResult};
use uucore::format_usage;
static ABOUT: &str = "Print the file name of the terminal connected to standard input.";
const USAGE: &str = "{} [OPTION]...";
@ -24,44 +24,39 @@ mod options {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let matches = uu_app().get_matches_from(args);
let silent = matches.contains_id(options::SILENT);
// Call libc function ttyname
let tty = unsafe {
let ptr = libc::ttyname(libc::STDIN_FILENO);
if !ptr.is_null() {
String::from_utf8_lossy(CStr::from_ptr(ptr).to_bytes()).to_string()
// If silent, we don't need the name, only whether or not stdin is a tty.
if silent {
return if atty::is(atty::Stream::Stdin) {
Ok(())
} else {
"".to_owned()
}
Err(1.into())
};
};
let mut stdout = std::io::stdout();
if !silent {
let write_result = if !tty.chars().all(|c| c.is_whitespace()) {
writeln!(stdout, "{}", tty)
} else {
writeln!(stdout, "not a tty")
};
if write_result.is_err() || stdout.flush().is_err() {
// Don't return to prevent a panic later when another flush is attempted
// because the `uucore_procs::main` macro inserts a flush after execution for every utility.
std::process::exit(3);
}
}
// Get the ttyname via nix
let name = nix::unistd::ttyname(std::io::stdin().as_raw_fd());
if atty::is(atty::Stream::Stdin) {
Ok(())
} else {
Err(libc::EXIT_FAILURE.into())
}
let write_result = match name {
Ok(name) => writeln!(stdout, "{}", name.display()),
Err(_) => {
set_exit_code(1);
writeln!(stdout, "not a tty")
}
};
if write_result.is_err() || stdout.flush().is_err() {
// Don't return to prevent a panic later when another flush is attempted
// because the `uucore_procs::main` macro inserts a flush after execution for every utility.
std::process::exit(3);
};
Ok(())
}
pub fn uu_app<'a>() -> Command<'a> {

View file

@ -16,7 +16,7 @@ path = "src/uname.rs"
[dependencies]
clap = { version = "3.2", features = ["wrap_help", "cargo"] }
platform-info = "0.2"
platform-info = "1.0.0"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -21,7 +21,7 @@ use std::str::from_utf8;
use unicode_width::UnicodeWidthChar;
use uucore::display::Quotable;
use uucore::error::{FromIo, UError, UResult};
use uucore::{format_usage, InvalidEncodingHandling};
use uucore::format_usage;
static NAME: &str = "unexpand";
static USAGE: &str = "{} [OPTION]... [FILE]...";
@ -165,9 +165,7 @@ fn expand_shortcuts(args: &[String]) -> Vec<String> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::Ignore)
.accept_any();
let args = args.collect_ignore();
let matches = uu_app().get_matches_from(expand_shortcuts(&args));

View file

@ -7,6 +7,7 @@
/* last synced with: unlink (GNU coreutils) 8.21 */
use std::ffi::OsString;
use std::fs::remove_file;
use std::path::Path;
@ -22,7 +23,7 @@ static OPT_PATH: &str = "FILE";
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().get_matches_from(args);
let path: &Path = matches.value_of_os(OPT_PATH).unwrap().as_ref();
let path: &Path = matches.get_one::<OsString>(OPT_PATH).unwrap().as_ref();
remove_file(path).map_err_context(|| format!("cannot unlink {}", path.quote()))
}

View file

@ -8,6 +8,7 @@
// spell-checker:ignore (paths) wtmp
use std::ffi::OsString;
use std::path::Path;
use clap::{crate_version, Arg, Command};
@ -35,7 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().after_help(&after_help[..]).get_matches_from(args);
let files: Vec<&Path> = matches
.values_of_os(ARG_FILES)
.get_many::<OsString>(ARG_FILES)
.map(|v| v.map(AsRef::as_ref).collect())
.unwrap_or_default();

Some files were not shown because too many files have changed in this diff Show more