mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-06 16:07:47 +00:00
Merge branch 'main' of github.com:pyoky/coreutils
This commit is contained in:
commit
65a45ae5e1
9 changed files with 231 additions and 102 deletions
|
@ -7,13 +7,18 @@ function progressBar(totals) {
|
|||
totalTests += value;
|
||||
}
|
||||
const passPercentage = Math.round(100 * totals["PASS"] / totalTests);
|
||||
const skipPercentage = passPercentage + Math.round(100 * totals["PASS"] / totalTests);
|
||||
const skipPercentage = passPercentage + Math.round(100 * totals["SKIP"] / totalTests);
|
||||
|
||||
// The ternary expressions are used for some edge-cases where there are no failing test,
|
||||
// but still a red (or beige) line shows up because of how CSS draws gradients.
|
||||
bar.style = `background: linear-gradient(
|
||||
to right,
|
||||
var(--PASS) ${passPercentage}%,
|
||||
var(--SKIP) ${passPercentage}%,
|
||||
var(--SKIP) ${skipPercentage}%,
|
||||
var(--FAIL) 0)`;
|
||||
var(--PASS) ${passPercentage}%`
|
||||
+ ( passPercentage === 100 ? ", var(--PASS)" :
|
||||
`, var(--SKIP) ${passPercentage}%,
|
||||
var(--SKIP) ${skipPercentage}%`
|
||||
)
|
||||
+ (skipPercentage === 100 ? ")" : ", var(--FAIL) 0)");
|
||||
|
||||
const progress = document.createElement("div");
|
||||
progress.className = "progress"
|
||||
|
@ -69,7 +74,7 @@ function parse_result(parent, obj) {
|
|||
return totals;
|
||||
}
|
||||
|
||||
fetch("https://github.com/uutils/coreutils-tracking/blob/main/gnu-full-result.json")
|
||||
fetch("https://raw.githubusercontent.com/uutils/coreutils-tracking/main/gnu-full-result.json")
|
||||
.then((r) => r.json())
|
||||
.then((obj) => {
|
||||
let parent = document.getElementById("test-cov");
|
||||
|
|
|
@ -68,7 +68,14 @@ fn write_version(w: &mut impl Write, app: &App) -> io::Result<()> {
|
|||
|
||||
fn write_usage(w: &mut impl Write, app: &mut App, name: &str) -> io::Result<()> {
|
||||
writeln!(w, "\n```")?;
|
||||
let mut usage: String = app.render_usage().lines().nth(1).unwrap().trim().into();
|
||||
let mut usage: String = app
|
||||
.render_usage()
|
||||
.lines()
|
||||
.skip(1)
|
||||
.map(|l| l.trim())
|
||||
.filter(|l| !l.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
usage = usage.replace(app.get_name(), name);
|
||||
writeln!(w, "{}", usage)?;
|
||||
writeln!(w, "```")
|
||||
|
|
|
@ -325,15 +325,15 @@ fn cat_path(
|
|||
state: &mut OutputState,
|
||||
out_info: Option<&FileInformation>,
|
||||
) -> CatResult<()> {
|
||||
if path == "-" {
|
||||
let stdin = io::stdin();
|
||||
let mut handle = InputHandle {
|
||||
reader: stdin,
|
||||
is_interactive: atty::is(atty::Stream::Stdin),
|
||||
};
|
||||
return cat_handle(&mut handle, options, state);
|
||||
}
|
||||
match get_input_type(path)? {
|
||||
InputType::StdIn => {
|
||||
let stdin = io::stdin();
|
||||
let mut handle = InputHandle {
|
||||
reader: stdin,
|
||||
is_interactive: atty::is(atty::Stream::Stdin),
|
||||
};
|
||||
cat_handle(&mut handle, options, state)
|
||||
}
|
||||
InputType::Directory => Err(CatError::IsDirectory),
|
||||
#[cfg(unix)]
|
||||
InputType::Socket => {
|
||||
|
@ -560,13 +560,12 @@ fn write_tab_to_end<W: Write>(mut in_buf: &[u8], writer: &mut W) -> usize {
|
|||
{
|
||||
Some(p) => {
|
||||
writer.write_all(&in_buf[..p]).unwrap();
|
||||
if in_buf[p] == b'\n' {
|
||||
return count + p;
|
||||
} else if in_buf[p] == b'\t' {
|
||||
if in_buf[p] == b'\t' {
|
||||
writer.write_all(b"^I").unwrap();
|
||||
in_buf = &in_buf[p + 1..];
|
||||
count += p + 1;
|
||||
} else {
|
||||
// b'\n' or b'\r'
|
||||
return count + p;
|
||||
}
|
||||
}
|
||||
|
@ -589,10 +588,10 @@ fn write_nonprint_to_end<W: Write>(in_buf: &[u8], writer: &mut W, tab: &[u8]) ->
|
|||
9 => writer.write_all(tab),
|
||||
0..=8 | 10..=31 => writer.write_all(&[b'^', byte + 64]),
|
||||
32..=126 => writer.write_all(&[byte]),
|
||||
127 => writer.write_all(&[b'^', byte - 64]),
|
||||
127 => writer.write_all(&[b'^', b'?']),
|
||||
128..=159 => writer.write_all(&[b'M', b'-', b'^', byte - 64]),
|
||||
160..=254 => writer.write_all(&[b'M', b'-', byte - 128]),
|
||||
_ => writer.write_all(&[b'M', b'-', b'^', 63]),
|
||||
_ => writer.write_all(&[b'M', b'-', b'^', b'?']),
|
||||
}
|
||||
.unwrap();
|
||||
count += 1;
|
||||
|
|
|
@ -989,6 +989,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::INFILE)
|
||||
.long(options::INFILE)
|
||||
.overrides_with(options::INFILE)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("FILE")
|
||||
|
@ -997,6 +998,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::OUTFILE)
|
||||
.long(options::OUTFILE)
|
||||
.overrides_with(options::OUTFILE)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("FILE")
|
||||
|
@ -1005,6 +1007,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::IBS)
|
||||
.long(options::IBS)
|
||||
.overrides_with(options::IBS)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1013,6 +1016,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::OBS)
|
||||
.long(options::OBS)
|
||||
.overrides_with(options::OBS)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1021,6 +1025,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::BS)
|
||||
.long(options::BS)
|
||||
.overrides_with(options::BS)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1029,6 +1034,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::CBS)
|
||||
.long(options::CBS)
|
||||
.overrides_with(options::CBS)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1037,6 +1043,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::SKIP)
|
||||
.long(options::SKIP)
|
||||
.overrides_with(options::SKIP)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1045,6 +1052,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::SEEK)
|
||||
.long(options::SEEK)
|
||||
.overrides_with(options::SEEK)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1053,6 +1061,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::COUNT)
|
||||
.long(options::COUNT)
|
||||
.overrides_with(options::COUNT)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("N")
|
||||
|
@ -1061,6 +1070,7 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.arg(
|
||||
Arg::new(options::STATUS)
|
||||
.long(options::STATUS)
|
||||
.overrides_with(options::STATUS)
|
||||
.takes_value(true)
|
||||
.require_equals(true)
|
||||
.value_name("LEVEL")
|
||||
|
@ -1086,6 +1096,10 @@ Printing performance stats is also triggered by the INFO signal (where supported
|
|||
Arg::new(options::CONV)
|
||||
.long(options::CONV)
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(true)
|
||||
.use_delimiter(true)
|
||||
.require_delimiter(true)
|
||||
.multiple_values(true)
|
||||
.require_equals(true)
|
||||
.value_name("CONV")
|
||||
.help("(alternatively conv=CONV[,CONV]) specifies a comma-separated list of conversion options or (for legacy reasons) file flags. Conversion options and file flags may be intermixed.
|
||||
|
@ -1123,6 +1137,10 @@ Conversion Flags:
|
|||
Arg::new(options::IFLAG)
|
||||
.long(options::IFLAG)
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(true)
|
||||
.use_delimiter(true)
|
||||
.require_delimiter(true)
|
||||
.multiple_values(true)
|
||||
.require_equals(true)
|
||||
.value_name("FLAG")
|
||||
.help("(alternatively iflag=FLAG[,FLAG]) a comma separated list of input flags which specify how the input source is treated. FLAG may be any of the input-flags or general-flags specified below.
|
||||
|
@ -1149,6 +1167,10 @@ General-Flags
|
|||
Arg::new(options::OFLAG)
|
||||
.long(options::OFLAG)
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(true)
|
||||
.use_delimiter(true)
|
||||
.require_delimiter(true)
|
||||
.multiple_values(true)
|
||||
.require_equals(true)
|
||||
.value_name("FLAG")
|
||||
.help("(alternatively oflag=FLAG[,FLAG]) a comma separated list of output flags which specify how the output source is treated. FLAG may be any of the output-flags or general-flags specified below.
|
||||
|
|
|
@ -490,16 +490,11 @@ fn parse_flag_list<T: std::str::FromStr<Err = ParseError>>(
|
|||
tag: &str,
|
||||
matches: &Matches,
|
||||
) -> Result<Vec<T>, ParseError> {
|
||||
let mut flags = Vec::new();
|
||||
|
||||
if let Some(comma_str) = matches.value_of(tag) {
|
||||
for s in comma_str.split(',') {
|
||||
let flag = s.parse()?;
|
||||
flags.push(flag);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(flags)
|
||||
matches
|
||||
.values_of(tag)
|
||||
.unwrap_or_default()
|
||||
.map(|f| f.parse())
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Parse Conversion Options (Input Variety)
|
||||
|
|
|
@ -299,6 +299,116 @@ fn test_status_level_noxfer() {
|
|||
assert_eq!(st, StatusLevel::Noxfer);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_flags_options() {
|
||||
let args = vec![
|
||||
String::from("dd"),
|
||||
String::from("--iflag=fullblock,directory"),
|
||||
String::from("--iflag=skip_bytes"),
|
||||
String::from("--oflag=direct"),
|
||||
String::from("--oflag=dsync"),
|
||||
String::from("--conv=ascii,ucase"),
|
||||
String::from("--conv=unblock"),
|
||||
];
|
||||
let matches = uu_app().try_get_matches_from(args).unwrap();
|
||||
|
||||
// iflag
|
||||
let iflags = parse_flag_list::<Flag>(options::IFLAG, &matches).unwrap();
|
||||
assert_eq!(
|
||||
vec![Flag::FullBlock, Flag::Directory, Flag::SkipBytes],
|
||||
iflags
|
||||
);
|
||||
|
||||
// oflag
|
||||
let oflags = parse_flag_list::<Flag>(options::OFLAG, &matches).unwrap();
|
||||
assert_eq!(vec![Flag::Direct, Flag::Dsync], oflags);
|
||||
|
||||
// conv
|
||||
let conv = parse_flag_list::<ConvFlag>(options::CONV, &matches).unwrap();
|
||||
assert_eq!(
|
||||
vec![ConvFlag::FmtEtoA, ConvFlag::UCase, ConvFlag::Unblock],
|
||||
conv
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_override_multiple_options() {
|
||||
let args = vec![
|
||||
String::from("dd"),
|
||||
String::from("--if=foo.file"),
|
||||
String::from("--if=correct.file"),
|
||||
String::from("--of=bar.file"),
|
||||
String::from("--of=correct.file"),
|
||||
String::from("--ibs=256"),
|
||||
String::from("--ibs=1024"),
|
||||
String::from("--obs=256"),
|
||||
String::from("--obs=1024"),
|
||||
String::from("--cbs=1"),
|
||||
String::from("--cbs=2"),
|
||||
String::from("--skip=0"),
|
||||
String::from("--skip=2"),
|
||||
String::from("--seek=0"),
|
||||
String::from("--seek=2"),
|
||||
String::from("--status=none"),
|
||||
String::from("--status=noxfer"),
|
||||
String::from("--count=512"),
|
||||
String::from("--count=1024"),
|
||||
];
|
||||
|
||||
let matches = uu_app().try_get_matches_from(args).unwrap();
|
||||
|
||||
// if
|
||||
assert_eq!("correct.file", matches.value_of(options::INFILE).unwrap());
|
||||
|
||||
// of
|
||||
assert_eq!("correct.file", matches.value_of(options::OUTFILE).unwrap());
|
||||
|
||||
// ibs
|
||||
assert_eq!(1024, parse_ibs(&matches).unwrap());
|
||||
|
||||
// obs
|
||||
assert_eq!(1024, parse_obs(&matches).unwrap());
|
||||
|
||||
// cbs
|
||||
assert_eq!(2, parse_cbs(&matches).unwrap().unwrap());
|
||||
|
||||
// status
|
||||
assert_eq!(
|
||||
StatusLevel::Noxfer,
|
||||
parse_status_level(&matches).unwrap().unwrap()
|
||||
);
|
||||
|
||||
// skip
|
||||
assert_eq!(
|
||||
200,
|
||||
parse_skip_amt(&100, &IFlags::default(), &matches)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
// seek
|
||||
assert_eq!(
|
||||
200,
|
||||
parse_seek_amt(&100, &OFlags::default(), &matches)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
// count
|
||||
assert_eq!(
|
||||
CountType::Bytes(1024),
|
||||
parse_count(
|
||||
&IFlags {
|
||||
count_bytes: true,
|
||||
..IFlags::default()
|
||||
},
|
||||
&matches
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// ----- IConvFlags/Output -----
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -14,7 +14,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::InvalidEncodingHandling;
|
||||
use uucore::{execution_phrase, InvalidEncodingHandling};
|
||||
|
||||
mod rand_read_adapter;
|
||||
|
||||
|
@ -26,14 +26,9 @@ enum Mode {
|
|||
|
||||
static NAME: &str = "shuf";
|
||||
static USAGE: &str = r#"shuf [OPTION]... [FILE]
|
||||
or: shuf -e [OPTION]... [ARG]...
|
||||
or: shuf -i LO-HI [OPTION]...
|
||||
Write a random permutation of the input lines to standard output.
|
||||
|
||||
With no FILE, or when FILE is -, read standard input.
|
||||
"#;
|
||||
or: shuf -e [OPTION]... [ARG]...
|
||||
or: shuf -i LO-HI [OPTION]..."#;
|
||||
static ABOUT: &str = "Shuffle the input by outputting a random permutation of input lines. Each output permutation is equally likely.";
|
||||
static TEMPLATE: &str = "Usage: {usage}\nMandatory arguments to long options are mandatory for short options too.\n{options}";
|
||||
|
||||
struct Options {
|
||||
head_count: usize,
|
||||
|
@ -60,7 +55,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
.collect_str(InvalidEncodingHandling::ConvertLossy)
|
||||
.accept_any();
|
||||
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
let matches = uu_app()
|
||||
.override_usage(&USAGE.replace(NAME, execution_phrase())[..])
|
||||
.get_matches_from(args);
|
||||
|
||||
let mode = if let Some(args) = matches.values_of(options::ECHO) {
|
||||
Mode::Echo(args.map(String::from).collect())
|
||||
|
@ -125,7 +122,6 @@ pub fn uu_app<'a>() -> App<'a> {
|
|||
.name(NAME)
|
||||
.about(ABOUT)
|
||||
.version(crate_version!())
|
||||
.help_template(TEMPLATE)
|
||||
.override_usage(USAGE)
|
||||
.setting(AppSettings::InferLongArgs)
|
||||
.arg(
|
||||
|
|
|
@ -1,28 +1,27 @@
|
|||
// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile
|
||||
|
||||
#[cfg(unix)]
|
||||
extern crate unix_socket;
|
||||
use crate::common::util::*;
|
||||
|
||||
extern crate regex;
|
||||
use self::regex::Regex;
|
||||
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
use nix::unistd::{close, dup2};
|
||||
use std::collections::HashMap;
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::path::Path;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
#[cfg(not(windows))]
|
||||
extern crate libc;
|
||||
extern crate regex;
|
||||
#[cfg(not(windows))]
|
||||
extern crate tempfile;
|
||||
#[cfg(unix)]
|
||||
extern crate unix_socket;
|
||||
|
||||
use self::regex::Regex;
|
||||
use crate::common::util::*;
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
use nix::unistd::{close, dup};
|
||||
use std::collections::HashMap;
|
||||
#[cfg(all(unix, feature = "chmod"))]
|
||||
use std::os::unix::io::IntoRawFd;
|
||||
use std::path::Path;
|
||||
#[cfg(not(windows))]
|
||||
use std::path::PathBuf;
|
||||
#[cfg(not(windows))]
|
||||
use std::sync::Mutex;
|
||||
#[cfg(not(windows))]
|
||||
extern crate tempfile;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
lazy_static! {
|
||||
|
@ -142,7 +141,7 @@ fn test_ls_devices() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "chmod"))]
|
||||
#[cfg(feature = "chmod")]
|
||||
#[test]
|
||||
fn test_ls_io_errors() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
@ -202,56 +201,52 @@ fn test_ls_io_errors() {
|
|||
#[cfg(unix)]
|
||||
{
|
||||
at.touch("some-dir4/bad-fd.txt");
|
||||
let fd1 = at.open("some-dir4/bad-fd.txt").as_raw_fd();
|
||||
let fd2 = 25000;
|
||||
let rv1 = dup2(fd1, fd2);
|
||||
let rv2 = close(fd1);
|
||||
let fd1 = at.open("some-dir4/bad-fd.txt").into_raw_fd();
|
||||
let fd2 = dup(dbg!(fd1)).unwrap();
|
||||
close(fd1).unwrap();
|
||||
|
||||
// dup and close work on the mac, but doesn't work in some linux containers
|
||||
// so check to see that return values are non-error before proceeding
|
||||
if rv1.is_ok() && rv2.is_ok() {
|
||||
// on the mac and in certain Linux containers bad fds are typed as dirs,
|
||||
// however sometimes bad fds are typed as links and directory entry on links won't fail
|
||||
if PathBuf::from(format!("/dev/fd/{fd}", fd = fd2)).is_dir() {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-alR")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.fails()
|
||||
.stderr_contains(format!(
|
||||
"cannot open directory '/dev/fd/{fd}': Bad file descriptor",
|
||||
fd = fd2
|
||||
))
|
||||
.stdout_does_not_contain(format!("{fd}:\n", fd = fd2));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-RiL")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.fails()
|
||||
.stderr_contains(format!("cannot open directory '/dev/fd/{fd}': Bad file descriptor", fd = fd2))
|
||||
// don't double print bad fd errors
|
||||
.stderr_does_not_contain(format!("ls: cannot open directory '/dev/fd/{fd}': Bad file descriptor\nls: cannot open directory '/dev/fd/{fd}': Bad file descriptor", fd = fd2));
|
||||
} else {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-alR")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.succeeds();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-RiL")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.succeeds();
|
||||
}
|
||||
// on the mac and in certain Linux containers bad fds are typed as dirs,
|
||||
// however sometimes bad fds are typed as links and directory entry on links won't fail
|
||||
if PathBuf::from(format!("/dev/fd/{fd}", fd = fd2)).is_dir() {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-alR")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.fails()
|
||||
.stderr_contains(format!(
|
||||
"cannot open directory '/dev/fd/{fd}': Bad file descriptor",
|
||||
fd = fd2
|
||||
))
|
||||
.stdout_does_not_contain(format!("{fd}:\n", fd = fd2));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-alL")
|
||||
.arg("-RiL")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.fails()
|
||||
.stderr_contains(format!("cannot open directory '/dev/fd/{fd}': Bad file descriptor", fd = fd2))
|
||||
// don't double print bad fd errors
|
||||
.stderr_does_not_contain(format!("ls: cannot open directory '/dev/fd/{fd}': Bad file descriptor\nls: cannot open directory '/dev/fd/{fd}': Bad file descriptor", fd = fd2));
|
||||
} else {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-alR")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.succeeds();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-RiL")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-alL")
|
||||
.arg(format!("/dev/fd/{fd}", fd = fd2))
|
||||
.succeeds();
|
||||
|
||||
let _ = close(fd2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -463,7 +463,7 @@ fn test_split_number_with_io_blksize() {
|
|||
assert_eq!(file_read("xab"), "fghij");
|
||||
assert_eq!(file_read("xac"), "klmno");
|
||||
assert_eq!(file_read("xad"), "pqrst");
|
||||
assert_eq!(file_read("xae"), "uvwxyz");
|
||||
assert_eq!(file_read("xae"), "uvwxyz\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue