xargs doesn't limit command line lengths properly
$ find ~ -print0 | ./target/debug/xargs -0 echo >/dev/null
Error: Command could not be run: Argument list too long (os error 7)
From a quick look, there's at least an issue here: https://github.com/uutils/findutils/blob/36e3229537de84a9b68bedc984a4366a6ea24357/src/xargs/mod.rs#L141-L146
This needs to count not only the length of the string, but also the size of the pointer that ends up in argv/envp.
It might be worth using the https://crates.io/crates/argmax crate to do this accounting for us. It could also help for #6.
Hi, @tavianator . What you think about use something like:
#[cfg(unix)]
fn count_osstr_chars_for_exec(s: &OsStr) -> (usize, usize) {
use std::os::unix::ffi::OsStrExt;
let cmd = Command::new(s);
let args: Vec<&OsStr> = cmd.get_args().collect();
// Include +1 for the null terminator.
(s.as_bytes().len() + 1, args.len())
}
To this issue? We mantain the count for string and get argv count together.
@Every2 I would strongly recommend using https://crates.io/crates/argmax, it already contains a well-tested implementation of command line length limiting. It was also recently added to this project's find implementation: #515
@tavianator I see. Just confirming if I understood correctly. The structure of the code shouldn't be changed, only the function count_osstr_chars_for_exec instead of using an OsStr, use argmax equivalent (I believe argmax::command and it's methods)?
The structure of the code shouldn't be changed, only the function
count_osstr_chars_for_exec
No, i feel like the code in xargs/mod.rs should be mostly re-written to take advantage of the argmax crate instead of using its own logic (MaxArgsCommandSizeLimiter etc.)
No, i feel like the code in xargs/mod.rs should be mostly re-written to take advantage of the argmax crate instead of using its own logic (MaxArgsCommandSizeLimiter etc.)
I'll start working on it then! One more thing. Is it better to send small PRs or send it all at once?