1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Child process launch for `prk run`.
//!
//! # Module layout
//!
//! | Module | Responsibility |
//! |---|---|
//! | [`guard`] | Refusing loader-controlling variables unless opted in |
//! | [`launch`] | Resolving the program, building the environment, starting the child |
//! | [`signal`] | Exit codes, signal dispositions and job control |
//! | [`cmdline`] | Escaping arguments for a Windows batch shim |
//! | [`error`] | Why a launch did not happen, and what a shell would have exited with |
//! | `winjob` | Windows job objects and console control handling |
//! | `winsec` | Restricting a file to the current user, for `prick-auth` |
//!
//! # Why this crate can be small
//!
//! Argv is carried as `Vec<OsString>` from `clap`'s `trailing_var_arg` all the
//! way to `Command::args()`, which passes it to `execvp` as a vector. **There
//! is never a command string**, so there is nothing to quote and nothing to
//! escape -- the entire class of shell-quoting bugs is structurally absent
//! rather than defended against, and non-UTF-8 arguments survive byte for byte.
//!
//! The single exception is a Windows `.cmd` shim, where `cmd.exe` genuinely
//! does interpose a string. [`cmdline`] is that exception, it is confined to
//! one module, and it has more tests than anything else here.
//!
//! # The `unsafe` in this crate
//!
//! `prick-core` is `#![forbid(unsafe_code)]` and is the miri target. This crate
//! is the opposite: it is where every `unsafe` in the workspace lives, and it
//! is exactly what miri **cannot** reach, because miri cannot execute a
//! process, a signal handler, or an FFI call.
//!
//! That is stated plainly rather than papered over. The consequences are:
//!
//! - Every `unsafe` block carries a `// SAFETY:` comment naming the invariant
//! it relies on, not merely asserting that one exists.
//! - The surface is kept as small as it can be: three places on Unix (the
//! `pre_exec` hook and the two calls inside it) and the Windows job, console
//! and security bindings.
//! - Verification comes from **real integration tests that start real
//! processes**, in `tests/`. There is no substitute available.
//!
//! # Nothing is written to disk
//!
//! Secrets reach the child through its environment block and nowhere else. This
//! crate creates no temporary file, no fifo and no dotenv, so there is no
//! window in which a secret exists at a path something else could read.
// This crate is the workspace's single home for `unsafe`; see the module docs
// above. `unsafe_code` is `warn` workspace-wide precisely so that lifting it
// has to be deliberate, visible, and in one place.
pub use LaunchError;
pub use ;
pub use ;