hyperhive/hive-forge/Cargo.toml
atlas e0c2f1aeaa hive-forge: die by SIGPIPE like every other CLI in a pipeline
Rust's runtime sets SIGPIPE to SIG_IGN at startup, so writing to a pipe
whose reader has gone away returns EPIPE and println! panics. `hive-forge
<verb> | head` printed a panic and exited 101 where cat, grep and every
other pipeline member exit quietly.

101 is not cosmetic: to a caller running `set -o pipefail` it is a real
failure, so a shell script that pipes our output stops on a condition
that is not an error.

Restore SIG_DFL first thing in main, before any output. Measured against
the same command: piped to head, 141 (killed by the signal) with empty
stderr; unpiped, 0; the pre-change binary, 101 with a panic.

Closes #3972
2026-09-02 18:40:33 +02:00

46 lines
1.6 KiB
TOML

[package]
name = "hive-forge"
edition.workspace = true
version.workspace = true
readme = "README.md"
[[bin]]
name = "hive-forge"
path = "src/main.rs"
[dependencies]
anyhow = { workspace = true }
clap = { workspace = true }
# `sync` = blocking client (hive-forge is a blocking CLI). TLS backend comes
# from feature unification on reqwest — which only works because forgejo-api
# and this crate now resolve to the SAME reqwest version; cargo unifies
# features per (crate, version), so the claim is a fact about the lockfile,
# not about the workspace. See the pin note on `forgejo-api` in the root
# `Cargo.toml`.
forgejo-api = { workspace = true, features = ["sync"] }
url.workspace = true
time.workspace = true
reqwest = { workspace = true, features = [
"json",
# `rustls` carries the platform verifier, which reads the OS trust store
# (and honours `SSL_CERT_FILE`), so hive-forge validates the hive
# gateway's self-signed leaf once the hive CA is in the agent's trust
# store — embedded into agent flakes via `security.pki.certificateFiles`
# — while public CAs still validate.
#
# The separate `rustls-native-certs` / `webpki-roots` features this entry
# used to name were 0.13.1-era and no longer exist; naming a feature that
# is gone is a hard resolution error, not a silent no-op, so this list has
# to move with the pin.
"rustls",
"blocking",
"multipart",
] }
serde = { workspace = true }
serde_json = { workspace = true }
# Only for restoring the default SIGPIPE disposition at startup — see
# `restore_sigpipe` in src/main.rs. std has no safe API for it.
libc = { workspace = true }
[lints]
workspace = true