tail: enable non-utf8 paths

This commit is contained in:
Benjamin Bara 2023-02-18 15:44:49 +01:00
parent dc34e89d50
commit f6edea2d05
3 changed files with 15 additions and 26 deletions

View file

@ -13,6 +13,7 @@ use fundu::DurationParser;
use is_terminal::IsTerminal; use is_terminal::IsTerminal;
use same_file::Handle; use same_file::Handle;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::ffi::OsString;
use std::time::Duration; use std::time::Duration;
use uucore::error::{UResult, USimpleError, UUsageError}; use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::parse_size::{parse_size, ParseSizeError}; use uucore::parse_size::{parse_size, ParseSizeError};
@ -144,7 +145,7 @@ pub struct Settings {
} }
impl Settings { impl Settings {
pub fn from_obsolete_args(args: &parse::ObsoleteArgs, name: Option<&str>) -> Self { pub fn from_obsolete_args(args: &parse::ObsoleteArgs, name: Option<OsString>) -> Self {
let mut settings: Self = Self { let mut settings: Self = Self {
sleep_sec: Duration::from_secs_f32(1.0), sleep_sec: Duration::from_secs_f32(1.0),
max_unchanged_stats: 5, max_unchanged_stats: 5,
@ -159,7 +160,7 @@ impl Settings {
} }
settings.mode = FilterMode::from_obsolete_args(args); settings.mode = FilterMode::from_obsolete_args(args);
let input = if let Some(name) = name { let input = if let Some(name) = name {
Input::from(name.to_string()) Input::from(&name)
} else { } else {
Input::default() Input::default()
}; };
@ -249,7 +250,7 @@ impl Settings {
let mut inputs: VecDeque<Input> = matches let mut inputs: VecDeque<Input> = matches
.get_many::<String>(options::ARG_FILES) .get_many::<String>(options::ARG_FILES)
.map(|v| v.map(|string| Input::from(string.clone())).collect()) .map(|v| v.map(|string| Input::from(&string)).collect())
.unwrap_or_default(); .unwrap_or_default();
// apply default and add '-' to inputs if none is present // apply default and add '-' to inputs if none is present
@ -575,7 +576,10 @@ mod tests {
#[test] #[test]
fn test_parse_obsolete_settings_f() { fn test_parse_obsolete_settings_f() {
let args = ObsoleteArgs { follow: true, ..Default::default() }; let args = ObsoleteArgs {
follow: true,
..Default::default()
};
let result = Settings::from_obsolete_args(&args, None); let result = Settings::from_obsolete_args(&args, None);
assert_eq!(result.follow, Some(FollowMode::Descriptor)); assert_eq!(result.follow, Some(FollowMode::Descriptor));

View file

@ -6,6 +6,7 @@
// spell-checker:ignore tailable seekable stdlib (stdlib) // spell-checker:ignore tailable seekable stdlib (stdlib)
use crate::text; use crate::text;
use std::ffi::OsStr;
use std::fs::{File, Metadata}; use std::fs::{File, Metadata};
use std::io::{Seek, SeekFrom}; use std::io::{Seek, SeekFrom};
#[cfg(unix)] #[cfg(unix)]
@ -26,21 +27,21 @@ pub struct Input {
} }
impl Input { impl Input {
// TODO: from &str may be the better choice pub fn from<T: AsRef<OsStr>>(string: &T) -> Self {
pub fn from(string: String) -> Self { let valid_string = string.as_ref().to_str();
let kind = if string == text::DASH { let kind = if valid_string.is_some() && valid_string.unwrap() == text::DASH {
InputKind::Stdin InputKind::Stdin
} else { } else {
InputKind::File(PathBuf::from(&string)) InputKind::File(PathBuf::from(string.as_ref()))
}; };
let display_name = match kind { let display_name = match kind {
InputKind::File(_) => string, InputKind::File(_) => string.as_ref().to_string_lossy().to_string(),
InputKind::Stdin => { InputKind::Stdin => {
if cfg!(unix) { if cfg!(unix) {
text::STDIN_HEADER.to_string() text::STDIN_HEADER.to_string()
} else { } else {
string string.as_ref().to_string_lossy().to_string()
} }
} }
}; };

View file

@ -4768,7 +4768,6 @@ fn test_obsolete_encoding_unix() {
let scene = TestScenario::new(util_name!()); let scene = TestScenario::new(util_name!());
let invalid_utf8_arg = OsStr::from_bytes(&[b'-', INVALID_UTF8, b'b']); let invalid_utf8_arg = OsStr::from_bytes(&[b'-', INVALID_UTF8, b'b']);
let valid_utf8_arg = OsStr::from_bytes(&[b'-', b'b']);
scene scene
.ucmd() .ucmd()
@ -4777,13 +4776,6 @@ fn test_obsolete_encoding_unix() {
.no_stdout() .no_stdout()
.stderr_is("tail: bad argument encoding: '-<2D>b'\n") .stderr_is("tail: bad argument encoding: '-<2D>b'\n")
.code_is(1); .code_is(1);
scene
.ucmd()
.args(&[valid_utf8_arg, invalid_utf8_arg])
.fails()
.no_stdout()
.stderr_is("tail: bad argument encoding\n")
.code_is(1);
} }
#[test] #[test]
@ -4794,7 +4786,6 @@ fn test_obsolete_encoding_windows() {
let scene = TestScenario::new(util_name!()); let scene = TestScenario::new(util_name!());
let invalid_utf16_arg = OsString::from_wide(&['-' as u16, INVALID_UTF16, 'b' as u16]); let invalid_utf16_arg = OsString::from_wide(&['-' as u16, INVALID_UTF16, 'b' as u16]);
let valid_utf16_arg = OsString::from("-b");
scene scene
.ucmd() .ucmd()
@ -4803,11 +4794,4 @@ fn test_obsolete_encoding_windows() {
.no_stdout() .no_stdout()
.stderr_is("tail: bad argument encoding: '-<2D>b'\n") .stderr_is("tail: bad argument encoding: '-<2D>b'\n")
.code_is(1); .code_is(1);
scene
.ucmd()
.args(&[&valid_utf16_arg, &invalid_utf16_arg])
.fails()
.no_stdout()
.stderr_is("tail: bad argument encoding\n")
.code_is(1);
} }