* tr: Fix regression causing read error with sockets
The test used for determining if a file descriptor
tested with fstat points to a directory is traditionally
done by using the S_IFMT mask[^1][^2], e.g.:
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
In Rust, this translates to 'm & libc::S_IFMT == libc::S_IFDIR'.
is_stdin_directory() uses 'has!(mode, S_IFDIR)', which is
**not** equivalent and causes non-directory sockets to be
incorrectly recognized as directories. This causes uu-tr
to break when used with all sockets created with socketpair,
including ksh93 pipes[^3]. Below is an example Rust program
demonstrating why the current check is bogus:
fn main() {
use nix::sys::socket::{socketpair, SockFlag, AddressFamily, SockType};
use nix::sys::stat::fstat;
use libc::{S_IFDIR, S_IFMT, mode_t};
let (_fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
let mode = fstat(&fd2).unwrap().st_mode as mode_t;
if mode & S_IFMT == S_IFDIR { // Equivalent to S_ISDIR()
println!("Not reached"); // Not a dir, so unreachable
}
if mode & S_IFDIR == S_IFDIR { // Bogus check for S_IFDIR
println!("BAD");
}
}
- is_stdin_directory(): Fix the regression introduced in 3e4221a4
by replacing the bogus check with one equivalent to S_ISDIR().
- test_tr.rs: Add a regression test for this bug.
[^1]: https://sourceware.org/git/?p=glibc.git;a=blob;f=io/sys/stat.h;h=4bea9e9a#l123
[^2]: https://git.musl-libc.org/cgit/musl/tree/include/sys/stat.h?id=047a1639#n51
[^3]: cc5e0692/src/cmd/ksh93/sh/io.c (L98-L102)
Fixes https://github.com/uutils/coreutils/issues/7658
* Add comment explaining rationale
Also fix cargo clippy lint.
(In case it isn't obvious, I'm fairly new to Rust)
* Fix more lint
Fixes https://github.com/uutils/coreutils/issues/6591
"feat_external_stdbuf": use an external libstdbuf.so for stdbuf instead of embedding it into
the stdbuf binary.
There are 2 use-cases:
1. Installation of uutils-coreutils using cargo install (e.g. from crates.io
which supports only "cargo install" as installation method). In this case,
installing libstdbuf.so is impossible, because "cargo install" installs
only binary programs (no cdylib), thus libstdbuf.so must be embedded into
stdbuf and written to /tmp at runtime. This is a hack, and may not work
on some platforms, e.g. because the SELinux permissions may not allow
stdbuf to write to /tmp, /tmp may be read-only, libstdbuf.so may not work
at all without SELinux labels, etc.
2. Installation of uutils-coreutils using an external tool, e.g. dpkg/apt on
debian. In this case, libstdbuf.so should be installed separately to its
correct location and the environment variable LIBSTDBUF_PATH configures the
installation path during the build. E.g. LIBSTDBUF_PATH="/lib/libstdbuf.so"
Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com>
* chore: cleanup workspace crates
* properly add all crates to the workspace cargo.toml as members
* except `fuzz` because it still has some issues, TBD
* use quotes around `true` and `false` to ensure there is no bool confusion
* remove a few leftover readme comments
* mark all unpublishable crates as `publish = false` to avoid accidental publishing
* Add `uutests` to the main workspace
* grammar
* a bit more cleanup based on feedback
* revert true/false
* Update tests/benches/factor dependencies
* cp: migrate from quick-error to thiserror
fixes: #7916
* Remove quick-error
Now that we have migrated to thiserror, we can remove quick-error
* cp: fix test failures
* cp: fix fmt error
Summary:
Partial fix for https://github.com/uutils/coreutils/issues/6591
The current code declare libstdbuf as a build-dependency of stdbuf as a
workaround to enforce that libstdbuf is compiled before stdbuf. This breaks
cross-compilation, because build-dependencies were compiled for the host
architecture, and not for the target architecture.
The reason this workaround is necessary is that bindeps is available only in nightly at the moment:
https://rust-lang.github.io/rfcs/3028-cargo-binary-dependencies.html
This commit replaces the "build-dependency" workaround with another workaround:
calling cargo manually to build libstdbuf in the build.rs of stdbuf, in order to ensure that libstdbuf is built before stdbuf.
Changes:
- Removed cpp/cpp_build dependencies:
The cpp, cpp_build, and related dependencies were removed because they made cross-compilation in a build.rs file very complex, since you need
to pass proper CXX env variables for cross-compilation, whereas cross-compiling rust code using cargo is quite simple.
Provided Rust implementations for getting stdin, stdout, and stderr pointers.
Switched from C++/cpp macro-based initialization to using the Rust ctor crate for library initialization.
- Remove "feat_require_crate_cpp" which is not needed any more, since stdbuf was the only utility using the cpp crate.
Tests:
This commit fixes e.g. this test:
cross test --target aarch64-unknown-linux-gnu --features stdbuf test_stdbuf::test_libstdbuf_preload -- --nocapture
- The "i686" build of stdbuf was also broken (stdbuf 32 bits, but libstdbuf 64 bits) and test_stdbuf::test_libstdbuf_preload of the i686 builds in github CI serves as regression
test for this issue, no need to add a cross-rs test for aarch64.
- The x86_64 musl build of stdbuf was also broken and was passing tests in CI only because it was compiled with the wrong libc (glibc instead of musl)
Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com>