stdbuf: fix cross-compilation

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>
This commit is contained in:
Etienne Cordonnier 2025-05-07 20:01:49 +02:00
parent 2e8b6fabcc
commit 35634b46a0
11 changed files with 476 additions and 267 deletions

View file

@ -3,3 +3,8 @@ linker = "x86_64-unknown-redox-gcc"
[env]
PROJECT_NAME_FOR_VERSION_STRING = "uutils coreutils"
# libstdbuf must be a shared library, so musl libc can't be linked statically
# https://github.com/rust-lang/rust/issues/82193
[build]
rustflags = [ "-C", "target-feature=-crt-static" ]

379
Cargo.lock generated
View file

@ -88,12 +88,12 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
version = "3.0.7"
version = "3.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
dependencies = [
"anstyle",
"once_cell",
"once_cell_polyfill",
"windows-sys 0.59.0",
]
@ -172,7 +172,7 @@ version = "0.71.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"cexpr",
"clang-sys",
"itertools 0.13.0",
@ -194,9 +194,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.0"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bitvec"
@ -274,9 +274,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.2.16"
version = "1.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951"
dependencies = [
"shlex",
]
@ -412,7 +412,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom 0.2.15",
"getrandom 0.2.16",
"once_cell",
"tiny-keccak",
]
@ -579,56 +579,6 @@ dependencies = [
"zip",
]
[[package]]
name = "cpp"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bcac3d8234c1fb813358e83d1bb6b0290a3d2b3b5efc6b88bfeaf9d8eec17"
dependencies = [
"cpp_macros",
]
[[package]]
name = "cpp_build"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27f8638c97fbd79cc6fc80b616e0e74b49bac21014faed590bbc89b7e2676c90"
dependencies = [
"cc",
"cpp_common",
"lazy_static",
"proc-macro2",
"regex",
"syn",
"unicode-xid",
]
[[package]]
name = "cpp_common"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25fcfea2ee05889597d35e986c2ad0169694320ae5cc8f6d2640a4bb8a884560"
dependencies = [
"lazy_static",
"proc-macro2",
"syn",
]
[[package]]
name = "cpp_macros"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d156158fe86e274820f5a53bc9edb0885a6e7113909497aa8d883b69dd171871"
dependencies = [
"aho-corasick",
"byteorder",
"cpp_common",
"lazy_static",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
@ -678,7 +628,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"crossterm_winapi",
"derive_more",
"document-features",
@ -907,9 +857,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.10"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
dependencies = [
"libc",
"windows-sys 0.59.0",
@ -921,7 +871,7 @@ version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22be12de19decddab85d09f251ec8363f060ccb22ec9c81bc157c0c8433946d8"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"log",
"scopeguard",
"uuid",
@ -1026,9 +976,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "fs_extra"
@ -1122,9 +1072,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
@ -1133,14 +1083,14 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.3.1"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets 0.52.6",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
@ -1167,9 +1117,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.2"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
dependencies = [
"allocator-api2",
"equivalent",
@ -1225,12 +1175,12 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.7.1"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
"hashbrown 0.15.3",
]
[[package]]
@ -1252,7 +1202,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"inotify-sys",
"libc",
]
@ -1317,9 +1267,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
version = "0.2.11"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27e77966151130221b079bcec80f1f34a9e414fa489d99152a201c07fd2182bc"
checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
@ -1332,9 +1282,9 @@ dependencies = [
[[package]]
name = "jiff-static"
version = "0.2.11"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97265751f8a9a4228476f2fc17874a9e7e70e96b893368e42619880fe143b48a"
checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442"
dependencies = [
"proc-macro2",
"quote",
@ -1377,9 +1327,9 @@ dependencies = [
[[package]]
name = "kqueue"
version = "1.0.8"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a"
dependencies = [
"kqueue-sys",
"libc",
@ -1395,12 +1345,6 @@ dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.172"
@ -1409,19 +1353,19 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libloading"
version = "0.8.6"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.53.0",
]
[[package]]
name = "libm"
version = "0.2.11"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "libredox"
@ -1429,7 +1373,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"libc",
"redox_syscall",
]
@ -1457,25 +1401,19 @@ checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
[[package]]
name = "lock_api"
version = "0.4.12"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "lockfree-object-pool"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e"
[[package]]
name = "log"
version = "0.4.26"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "lru"
@ -1483,7 +1421,7 @@ version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
dependencies = [
"hashbrown 0.15.2",
"hashbrown 0.15.3",
]
[[package]]
@ -1529,23 +1467,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.5"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
dependencies = [
"adler2",
]
[[package]]
name = "mio"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@ -1554,7 +1492,7 @@ version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"cfg-if",
"cfg_aliases",
"libc",
@ -1585,7 +1523,7 @@ version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"filetime",
"fsevent-sys",
"inotify",
@ -1692,9 +1630,15 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.20.3"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "onig"
@ -1702,7 +1646,7 @@ version = "6.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"libc",
"once_cell",
"onig_sys",
@ -1739,9 +1683,9 @@ dependencies = [
[[package]]
name = "parking_lot"
version = "0.12.3"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [
"lock_api",
"parking_lot_core",
@ -1749,9 +1693,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.9.10"
version = "0.9.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
dependencies = [
"cfg-if",
"libc",
@ -1860,11 +1804,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.20"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
"zerocopy 0.8.25",
]
[[package]]
@ -1879,9 +1823,9 @@ dependencies = [
[[package]]
name = "prettyplease"
version = "0.2.30"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1ccf34da56fc294e7d4ccf69a85992b7dfb826b7cf57bac6a70bba3494cc08a"
checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d"
dependencies = [
"proc-macro2",
"syn",
@ -1920,6 +1864,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "radium"
version = "0.7.0"
@ -1973,7 +1923,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.15",
"getrandom 0.2.16",
]
[[package]]
@ -1982,7 +1932,7 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.1",
"getrandom 0.3.3",
]
[[package]]
@ -2007,11 +1957,11 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.10"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
]
[[package]]
@ -2122,11 +2072,11 @@ dependencies = [
[[package]]
name = "rustix"
version = "1.0.1"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dade4812df5c384711475be5fcd8c162555352945401aed22a35bffeab61f657"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"errno",
"libc",
"linux-raw-sys",
@ -2135,9 +2085,9 @@ dependencies = [
[[package]]
name = "rustversion"
version = "1.0.20"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
[[package]]
name = "same-file"
@ -2166,7 +2116,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e37f432dfe840521abd9a72fefdf88ed7ad0f43bbea7d9d1d3d80383e9f4ad13"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
"libc",
"once_cell",
"parking_lot",
@ -2282,9 +2232,9 @@ dependencies = [
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
dependencies = [
"libc",
]
@ -2333,9 +2283,9 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "socket2"
version = "0.5.8"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
@ -2349,9 +2299,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.99"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
@ -2371,7 +2321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.1",
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.59.0",
@ -2577,12 +2527,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "unindent"
version = "0.2.4"
@ -2612,7 +2556,7 @@ dependencies = [
"thiserror 1.0.69",
"time",
"utmp-classic-raw",
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
@ -2622,7 +2566,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22c226537a3d6e01c440c1926ca0256dbee2d19b2229ede6fc4863a6493dd831"
dependencies = [
"cfg-if",
"zerocopy",
"zerocopy 0.7.35",
]
[[package]]
@ -3399,8 +3343,7 @@ dependencies = [
name = "uu_stdbuf_libstdbuf"
version = "0.1.0"
dependencies = [
"cpp",
"cpp_build",
"ctor",
"libc",
]
@ -3709,9 +3652,13 @@ version = "0.1.0"
[[package]]
name = "uuid"
version = "1.15.1"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "uutests"
@ -3770,9 +3717,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
@ -3876,7 +3823,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]
@ -3887,9 +3834,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.60.1"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
@ -3900,9 +3847,9 @@ dependencies = [
[[package]]
name = "windows-implement"
version = "0.59.0"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
@ -3928,18 +3875,18 @@ checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-result"
version = "0.3.1"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.3.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link",
]
@ -3995,13 +3942,29 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
dependencies = [
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
"windows_i686_gnullvm 0.53.0",
"windows_i686_msvc 0.53.0",
"windows_x86_64_gnu 0.53.0",
"windows_x86_64_gnullvm 0.53.0",
"windows_x86_64_msvc 0.53.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
@ -4014,6 +3977,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@ -4026,6 +3995,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@ -4038,12 +4013,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@ -4056,6 +4043,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@ -4068,6 +4061,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@ -4080,6 +4079,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
@ -4092,6 +4097,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.10"
@ -4103,11 +4114,11 @@ dependencies = [
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.0",
"bitflags 2.9.1",
]
[[package]]
@ -4148,7 +4159,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
"zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive 0.8.25",
]
[[package]]
@ -4162,6 +4182,17 @@ dependencies = [
"syn",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zerofrom"
version = "0.1.6"
@ -4199,14 +4230,12 @@ checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8"
[[package]]
name = "zopfli"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946"
checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7"
dependencies = [
"bumpalo",
"crc32fast",
"lockfree-object-pool",
"log",
"once_cell",
"simd-adler32",
]

View file

@ -158,7 +158,6 @@ feat_os_macos = [
feat_os_unix = [
"feat_Tier1",
#
"feat_require_crate_cpp",
"feat_require_unix",
"feat_require_unix_utmpx",
"feat_require_unix_hostid",
@ -185,9 +184,7 @@ feat_os_unix_android = [
#
# ** NOTE: these `feat_require_...` sets should be minimized as much as possible to encourage cross-platform availability of utilities
#
# "feat_require_crate_cpp" == set of utilities requiring the `cpp` crate (which fail to compile on several platforms; as of 2020-04-23)
feat_require_crate_cpp = ["stdbuf"]
# "feat_require_unix" == set of utilities requiring support which is only available on unix platforms (as of 2020-04-23)
# "feat_require_unix" == set of utilities requiring support which is only available on unix platforms
feat_require_unix = [
"chgrp",
"chmod",
@ -204,6 +201,7 @@ feat_require_unix = [
"nohup",
"pathchk",
"stat",
"stdbuf",
"stty",
"timeout",
"tty",
@ -220,8 +218,6 @@ feat_require_selinux = ["chcon", "runcon"]
feat_os_unix_fuchsia = [
"feat_common_core",
#
"feat_require_crate_cpp",
#
"chgrp",
"chmod",
"chown",
@ -287,6 +283,7 @@ clap_complete = "4.4"
clap_mangen = "0.2"
compare = "0.1.0"
crossterm = "0.29.0"
ctor = "0.4.1"
ctrlc = { version = "3.4.7", features = ["termination"] }
dns-lookup = { version = "2.0.4" }
exacl = "0.12.0"
@ -502,6 +499,7 @@ yes = { optional = true, version = "0.1.0", package = "uu_yes", path = "src/uu/y
[dev-dependencies]
chrono = { workspace = true }
ctor = { workspace = true }
filetime = { workspace = true }
glob = { workspace = true }
libc = { workspace = true }
@ -524,7 +522,6 @@ uucore = { workspace = true, features = [
walkdir = { workspace = true }
hex-literal = "1.0.0"
rstest = { workspace = true }
ctor = "0.4.1"
[target.'cfg(unix)'.dev-dependencies]
nix = { workspace = true, features = ["process", "signal", "user", "term"] }

View file

@ -58,22 +58,42 @@ skip = [
{ name = "windows-sys", version = "0.48.0" },
# mio, nu-ansi-term, socket2
{ name = "windows-sys", version = "0.52.0" },
# anstyle-query
{ name = "windows-sys", version = "0.59.0" },
# windows-sys
{ name = "windows-targets", version = "0.48.0" },
{ name = "windows-targets", version = "0.48.5" },
# parking_lot_core
{ name = "windows-targets", version = "0.52.6" },
# windows-targets
{ name = "windows_aarch64_gnullvm", version = "0.48.0" },
{ name = "windows_aarch64_gnullvm", version = "0.48.5" },
# windows-targets
{ name = "windows_aarch64_msvc", version = "0.48.0" },
{ name = "windows_aarch64_gnullvm", version = "0.52.6" },
# windows-targets
{ name = "windows_i686_gnu", version = "0.48.0" },
{ name = "windows_aarch64_msvc", version = "0.48.5" },
# windows-targets
{ name = "windows_i686_msvc", version = "0.48.0" },
{ name = "windows_aarch64_msvc", version = "0.52.6" },
# windows-targets
{ name = "windows_x86_64_gnu", version = "0.48.0" },
{ name = "windows_i686_gnu", version = "0.48.5" },
# windows-targets
{ name = "windows_x86_64_gnullvm", version = "0.48.0" },
{ name = "windows_i686_gnu", version = "0.52.6" },
# windows-targets
{ name = "windows_x86_64_msvc", version = "0.48.0" },
{ name = "windows_i686_gnullvm", version = "0.52.6" },
# windows-targets
{ name = "windows_i686_msvc", version = "0.48.5" },
# windows-targets
{ name = "windows_i686_msvc", version = "0.52.6" },
# windows-targets
{ name = "windows_x86_64_gnu", version = "0.48.5" },
# windows-targets
{ name = "windows_x86_64_gnu", version = "0.52.6" },
# windows-targets
{ name = "windows_x86_64_gnullvm", version = "0.48.5" },
# windows-targets
{ name = "windows_x86_64_gnullvm", version = "0.52.6" },
# windows-targets
{ name = "windows_x86_64_msvc", version = "0.48.5" },
# windows-targets
{ name = "windows_x86_64_msvc", version = "0.52.6" },
# kqueue-sys, onig
{ name = "bitflags", version = "1.3.2" },
# ansi-width
@ -98,6 +118,8 @@ skip = [
{ name = "rand_chacha", version = "0.3.1" },
# rand
{ name = "rand_core", version = "0.6.4" },
# utmp-classic
{ name = "zerocopy", version = "0.7.35" },
]
# spell-checker: enable

View file

@ -19,12 +19,10 @@ path = "src/stdbuf.rs"
[dependencies]
clap = { workspace = true }
libstdbuf = { package = "uu_stdbuf_libstdbuf", path = "src/libstdbuf" }
tempfile = { workspace = true }
uucore = { workspace = true, features = ["parser"] }
[build-dependencies]
libstdbuf = { version = "0.1.0", package = "uu_stdbuf_libstdbuf", path = "src/libstdbuf" }
[[bin]]
name = "stdbuf"
path = "src/main.rs"

View file

@ -2,14 +2,20 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) dylib libstdbuf deps liblibstdbuf
// spell-checker:ignore (ToDO) bindeps dylib libstdbuf deps liblibstdbuf
use std::env;
use std::env::current_exe;
use std::fs;
use std::path::Path;
use std::process::Command;
#[cfg(not(any(target_vendor = "apple", target_os = "windows")))]
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
mod platform {
pub const DYLIB_EXT: &str = ".so";
}
@ -19,31 +25,83 @@ mod platform {
pub const DYLIB_EXT: &str = ".dylib";
}
#[cfg(target_os = "windows")]
mod platform {
pub const DYLIB_EXT: &str = ".dll";
}
fn main() {
let current_exe = current_exe().unwrap();
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/libstdbuf/src/libstdbuf.rs");
let out_dir_string = env::var("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir_string);
let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set");
let target = env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
let deps_dir = current_exe.ancestors().nth(3).unwrap().join("deps");
dbg!(&deps_dir);
// Create a separate build directory for libstdbuf to avoid conflicts
let build_dir = Path::new(&out_dir).join("libstdbuf-build");
fs::create_dir_all(&build_dir).expect("Failed to create build directory");
let libstdbuf = deps_dir
.read_dir()
.unwrap()
.flatten()
.find(|entry| {
let n = entry.file_name();
let name = n.to_string_lossy();
// Get the cargo executable
let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
name.starts_with("liblibstdbuf") && name.ends_with(platform::DYLIB_EXT)
})
.expect("unable to find libstdbuf");
// This manual cargo call ensures that libstdbuf is built before stdbuf.rs is compiled, which is necessary
// for include_bytes!(..."/libstdbuf.so") to work.
// In the future, "bindeps" should be used to simplify the code and avoid the manual cargo call,
// however this is available only in cargo nightly at the moment.
// See the tracking issue: https://github.com/rust-lang/cargo/issues/9096
let mut cmd = Command::new(&cargo);
cmd.env_clear().envs(env::vars());
cmd.current_dir(Path::new("src/libstdbuf")).args([
"build",
"--target-dir",
build_dir.to_str().unwrap(),
]);
fs::copy(libstdbuf.path(), out_dir.join("libstdbuf.so")).unwrap();
// Get the current profile
let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
// Pass the release flag if we're in release mode
if profile == "release" || profile == "bench" {
cmd.arg("--release");
}
// Pass the target architecture if we're cross-compiling
if !target.is_empty() && target != "unknown" {
cmd.arg("--target").arg(&target);
}
let status = cmd.status().expect("Failed to build libstdbuf");
assert!(status.success(), "Failed to build libstdbuf");
// Copy the built library to OUT_DIR for include_bytes! to find
let lib_name = format!("liblibstdbuf{}", platform::DYLIB_EXT);
let dest_path = Path::new(&out_dir).join(format!("libstdbuf{}", platform::DYLIB_EXT));
// Check multiple possible locations for the built library
let possible_paths = if !target.is_empty() && target != "unknown" {
vec![
build_dir.join(&target).join(&profile).join(&lib_name),
build_dir
.join(&target)
.join(&profile)
.join("deps")
.join(&lib_name),
]
} else {
vec![
build_dir.join(&profile).join(&lib_name),
build_dir.join(&profile).join("deps").join(&lib_name),
]
};
// Try to find the library in any of the possible locations
let mut found = false;
for source_path in &possible_paths {
if source_path.exists() {
fs::copy(source_path, &dest_path).expect("Failed to copy libstdbuf library");
found = true;
break;
}
}
assert!(
found,
"Could not find built libstdbuf library. Searched in: {:?}.",
possible_paths
);
}

View file

@ -13,14 +13,8 @@ edition.workspace = true
[lib]
name = "libstdbuf"
path = "src/libstdbuf.rs"
crate-type = [
"cdylib",
"rlib",
] # XXX: note: the rlib is just to prevent Cargo from spitting out a warning
crate-type = ["cdylib"]
[dependencies]
cpp = "0.5.10"
ctor = { workspace = true }
libc = { workspace = true }
[build-dependencies]
cpp_build = "0.5.10"

View file

@ -4,8 +4,18 @@
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) libstdbuf
use cpp_build::Config;
use std::env;
fn main() {
Config::new().pic(true).build("src/libstdbuf.rs");
// Make sure we're building position-independent code for use with LD_PRELOAD
println!("cargo:rustc-link-arg=-fPIC");
let target = env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
// Ensure the library doesn't have any undefined symbols (-z flag not supported on macOS)
if !target.contains("apple-darwin") {
println!("cargo:rustc-link-arg=-z");
println!("cargo:rustc-link-arg=defs");
}
println!("cargo:rerun-if-changed=src/libstdbuf.rs");
}

View file

@ -2,34 +2,80 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) IOFBF IOLBF IONBF cstdio setvbuf
// spell-checker:ignore (ToDO) IOFBF IOLBF IONBF setvbuf stderrp stdinp stdoutp
use cpp::cpp;
use ctor::ctor;
use libc::{_IOFBF, _IOLBF, _IONBF, FILE, c_char, c_int, fileno, size_t};
use std::env;
use std::ptr;
cpp! {{
#include <cstdio>
// This runs automatically when the library is loaded via LD_PRELOAD
#[ctor]
fn init() {
unsafe { __stdbuf() };
}
extern "C" {
void __stdbuf(void);
void __attribute((constructor))
__stdbuf_init(void) {
__stdbuf();
/// # Safety
/// This function is unsafe because it calls a C API
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __stdbuf_get_stdin() -> *mut FILE {
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
{
unsafe extern "C" {
fn __stdinp() -> *mut FILE;
}
FILE *__stdbuf_get_stdin() { return stdin; }
FILE *__stdbuf_get_stdout() { return stdout; }
FILE *__stdbuf_get_stderr() { return stderr; }
unsafe { __stdinp() }
}
}}
unsafe extern "C" {
fn __stdbuf_get_stdin() -> *mut FILE;
fn __stdbuf_get_stdout() -> *mut FILE;
fn __stdbuf_get_stderr() -> *mut FILE;
#[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
{
unsafe extern "C" {
static mut stdin: *mut FILE;
}
unsafe { stdin }
}
}
/// # Safety
/// This function is unsafe because it calls a C API
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __stdbuf_get_stdout() -> *mut FILE {
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
{
unsafe extern "C" {
fn __stdoutp() -> *mut FILE;
}
unsafe { __stdoutp() }
}
#[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
{
unsafe extern "C" {
static mut stdout: *mut FILE;
}
unsafe { stdout }
}
}
/// # Safety
/// This function is unsafe because it calls a C API
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __stdbuf_get_stderr() -> *mut FILE {
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
{
unsafe extern "C" {
fn __stderrp() -> *mut FILE;
}
unsafe { __stderrp() }
}
#[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
{
unsafe extern "C" {
static mut stderr: *mut FILE;
}
unsafe { stderr }
}
}
fn set_buffer(stream: *mut FILE, value: &str) {
@ -61,7 +107,9 @@ fn set_buffer(stream: *mut FILE, value: &str) {
}
/// # Safety
/// ToDO ... (safety note)
/// This function is intended to be called automatically when the library is loaded via LD_PRELOAD.
/// It assumes that the standard streams are valid and that calling setvbuf on them is safe.
/// The caller must ensure this function is only called in a compatible runtime environment.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __stdbuf() {
if let Ok(val) = env::var("_STDBUF_E") {

View file

@ -31,8 +31,18 @@ mod options {
pub const COMMAND: &str = "command";
}
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
const STDBUF_INJECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/libstdbuf.so"));
#[cfg(target_vendor = "apple")]
const STDBUF_INJECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/libstdbuf.dylib"));
enum BufferType {
Default,
Line,

View file

@ -3,12 +3,6 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore dyld dylib setvbuf
#[cfg(all(
not(target_os = "windows"),
not(target_os = "openbsd"),
not(target_os = "macos")
))]
use std::process::Command;
use uutests::new_ucmd;
#[cfg(not(target_os = "windows"))]
use uutests::util::TestScenario;
@ -37,7 +31,15 @@ fn test_no_such() {
.stderr_contains("No such file or directory");
}
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
// does not provide musl-compiled system utilities (like head), leading to dynamic linker errors
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
#[cfg(all(
not(target_os = "windows"),
not(target_os = "freebsd"),
not(target_os = "openbsd"),
not(all(target_arch = "x86_64", target_env = "musl"))
))]
#[test]
fn test_stdbuf_unbuffered_stdout() {
// This is a basic smoke test
@ -51,7 +53,15 @@ fn test_stdbuf_unbuffered_stdout() {
.stdout_is("The quick brown fox jumps over the lazy dog.");
}
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
// does not provide musl-compiled system utilities (like head), leading to dynamic linker errors
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
#[cfg(all(
not(target_os = "windows"),
not(target_os = "freebsd"),
not(target_os = "openbsd"),
not(all(target_arch = "x86_64", target_env = "musl"))
))]
#[test]
fn test_stdbuf_line_buffered_stdout() {
// Note: This test only verifies that stdbuf does not crash and that output is passed through as expected
@ -75,7 +85,15 @@ fn test_stdbuf_no_buffer_option_fails() {
.stderr_contains("the following required arguments were not provided:");
}
#[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))]
// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
// does not provide musl-compiled system utilities (like tail), leading to dynamic linker errors
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
#[cfg(all(
not(target_os = "windows"),
not(target_os = "freebsd"),
not(target_os = "openbsd"),
not(all(target_arch = "x86_64", target_env = "musl"))
))]
#[test]
fn test_stdbuf_trailing_var_arg() {
new_ucmd!()
@ -119,16 +137,25 @@ fn test_stdbuf_invalid_mode_fails() {
}
}
// macos uses DYLD_PRINT_LIBRARIES, not LD_DEBUG, so disable on macos at the moment
// macos uses DYLD_PRINT_LIBRARIES, not LD_DEBUG, so disable on macos at the moment.
// On modern Android (Bionic, API 37+), LD_DEBUG is supported and behaves similarly to glibc.
// On older Android versions (Bionic, API < 37), LD_DEBUG uses integer values instead of strings
// and is sometimes disabled. Disable test on Android for now.
// musl libc dynamic loader does not support LD_DEBUG, so disable on musl targets as well.
#[cfg(all(
not(target_os = "windows"),
not(target_os = "openbsd"),
not(target_os = "macos")
not(target_os = "macos"),
not(target_os = "android"),
not(target_env = "musl")
))]
#[test]
fn test_setvbuf_resolution() {
// Run a simple program with LD_DEBUG=symbols to see which setvbuf is being used
// Written in a way that it can run with cross-rs and be used as regression test
fn test_libstdbuf_preload() {
use std::process::Command;
// Run a simple program with LD_DEBUG=symbols to verify that libstdbuf is loaded correctly
// and that there are no architecture mismatches when preloading the library.
// Note: This does not check which setvbuf implementation is used, as our libstdbuf does not override setvbuf.
// for https://github.com/uutils/coreutils/issues/6591
let scene = TestScenario::new(util_name!());
@ -149,13 +176,24 @@ fn test_setvbuf_resolution() {
let uutils_debug = String::from_utf8_lossy(&uutils_output.stdout);
// Check if libstdbuf.so / libstdbuf.dylib is in the lookup path. The log should contain something like this:
// "symbol=setvbuf; lookup in file=/tmp/.tmp0mfmCg/libstdbuf.so [0]"
let libstdbuf_in_path = uutils_debug.contains("symbol=setvbuf")
&& uutils_debug.contains("lookup in file=")
&& uutils_debug.contains("libstdbuf");
// Check if libstdbuf.so / libstdbuf.dylib is in the lookup path.
// With GLIBC, the log should contain something like:
// "symbol=setvbuf; lookup in file=/tmp/.tmp0mfmCg/libstdbuf.so [0]"
// With FreeBSD dynamic loader, the log should contain something like:
// cspell:disable-next-line
// "calling init function for /tmp/.tmpu11rhP/libstdbuf.so at ..."
let libstdbuf_in_path = if cfg!(target_os = "freebsd") {
uutils_debug
.lines()
.any(|line| line.contains("calling init function") && line.contains("libstdbuf"))
} else {
uutils_debug.contains("symbol=setvbuf")
&& uutils_debug.contains("lookup in file=")
&& uutils_debug.contains("libstdbuf")
};
// Check for lack of architecture mismatch error. The potential error message is:
// Check for lack of architecture mismatch error. The potential error message with GLIBC is:
// cspell:disable-next-line
// "ERROR: ld.so: object '/tmp/.tmpCLq8jl/libstdbuf.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored."
let arch_mismatch_line = uutils_debug
.lines()