shutdown_hooks_rs
A minimal Rust wrapper around the C standard library's atexit function for registering shutdown hooks.
Repository Health
Technical Analysis
shutdown_hooks is a small Rust crate that provides a thin wrapper around the C standard library’s atexit function, letting Rust programs register callback functions to run automatically when the process exits. The crate exposes a single public function, add_shutdown_hook, which accepts an extern fn() and registers it via an unsafe FFI call to atexit, returning a boolean that indicates whether registration succeeded.
Because it delegates directly to the platform’s C runtime rather than a Unix-specific API, the crate works anywhere Rust can link against a C standard library, including Windows, where the author notes manually testing an eight-second-long shutdown hook. The API surface is intentionally minimal — there is currently no way to remove a registered hook, though the README notes that capability is planned for a future release.
What You Get
- A single exported function -
add_shutdown_hooktakes anextern fn()callback and registers it for execution at process exit. - Direct atexit FFI binding - the crate declares and calls the C
atexitfunction directly via anexternblock, with no intermediate abstraction layer. - Cross-platform behavior - because it relies on the platform’s C runtime rather than a Unix-specific API, registered hooks run consistently on both Unix-like systems and Windows.
- Boolean success signal -
add_shutdown_hookreturnstrueorfalsebased on the underlyingatexitcall’s return code, so callers can detect registration failure.
Common Use Cases
- Cleanup on unexpected exit - registering a hook to flush logs or close file handles when a program terminates via
std::process::exitor a C-level exit path that bypasses normal Rust drop semantics. - Legacy FFI interop - Rust code embedded in or linked against a C application that already relies on atexit conventions for shutdown ordering.
- Simple process-exit logging - printing a final diagnostic message or timing summary right before a short-lived CLI tool exits.
Under The Hood
Architecture
The crate is a single file, src/lib.rs, with no internal modules or layering: one public function, add_shutdown_hook, wraps an unsafe call to a C atexit function declared in a bare extern block. There is no state, no error type, and no configuration surface — the entire public API is one function that either succeeds or fails based on the C runtime’s return code. Because the design has no abstractions to change, the only thing that would break callers is a change to the function’s signature itself, which is unlikely given the crate’s stability.
Tech Stack
The crate targets Rust’s raw FFI layer directly: it imports std::os::raw::c_int and declares atexit in an extern block with no libc crate or other dependency — Cargo.toml lists no [dependencies] at all. Build tooling is plain cargo build/cargo test, with a .travis.yml wiring up Travis CI for automated builds. There is no async runtime, no framework, and no database — it is a pure systems-level FFI shim.
Code Quality
A single test module exercises add_shutdown_hook by registering a callback that asserts 1 + 2 == 3 and checking the registration call returns true; there is no broader test suite, and the module is marked #[allow(unused_imports)] to suppress a compiler warning rather than restructuring the code. Error handling is a plain bool rather than Rust’s idiomatic Result type, so callers cannot distinguish failure reasons. No linter or formatter configuration is present beyond what Travis CI’s default cargo test invocation would catch.
API Design
The API is about as small as a crate can be — one function, one argument, one return value — which makes it trivial to learn and use correctly. That simplicity comes at a real ergonomic cost, though: the callback must be a bare extern fn() rather than a closure, so callers cannot capture any surrounding state in their shutdown hook, and the bool return type discards the specific reason a registration might fail. The crate has not been updated since a 2016 commit, so its API reflects Rust 2015-era conventions rather than the Result-based patterns idiomatic Rust has since standardized on.
Used by 2 apps in this directory
ParadeDB
Search · Databases · Analytics
Born out of Y Combinator's S2023 batch, ParadeDB is a Postgres extension that delivers Elasticsearch-quality BM25 search and real-time analytics without a separate search cluster to manage.
RustDesk
Networking
Open-source, self-hosted remote desktop built in Rust — your data, your infrastructure, no third-party cloud.