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
//! `apksigner` command-line tool — Rust port of `com.android.apksigner.ApkSignerTool`.
//!
//! The Java tool has its own option grammar (`--name value`, `--name=value`, `-name value`,
//! and repeated per-signer groups delimited by `--next-signer`), so argument parsing is
//! hand-written in `apk_signer_tool` rather than delegated to a general-purpose parser. That
//! keeps the accepted syntax, the messages and the exit codes aligned with the reference.
// signatures mirror the Java reference one-for-one
// types mirror the Java generics
// next() mirrors the Java pull parser API
// index loops mirror the Java loops
// &mut Vec mirrors the Java List parameters
use ExitCode;
/// Restores the default `SIGPIPE` disposition for this process.
///
/// Rust starts every program with `SIGPIPE` ignored, which turns a write to a pipe whose reader
/// has exited into an error rather than a signal. `println!` then panics on that error, so
/// `apksigner verify --verbose app.apk | head -1` used to print
/// `failed printing to stdout: Broken pipe` plus a Rust backtrace note. Java never shows that:
/// its `PrintStream` swallows the `IOException` and the tool finishes normally. Restoring the
/// signal removes the panic and makes the tool die the way other Unix filters do.
///
/// The one remaining difference from Java is the exit status: dying from `SIGPIPE` reports 141
/// to the shell where Java reports its normal status. Neither can be reproduced while also
/// refusing to print a diagnostic, and no diagnostic is the more important half.
/// On non-Unix platforms `SIGPIPE` does not exist.