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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//! Orphan-entry cleanup. See [`cleanup_orphans`].
//!
//! Companion module to [`crate::TempDir`] and [`crate::NamedTempFile`].
//! Provides a single free function that scans the OS temp dir for
//! default-prefix entries this crate could have created and removes
//! those whose owning processes are no longer alive.
use io;
use ;
/// Sweep the OS temp directory for default-prefix entries this crate
/// could have created and remove those that look orphaned.
///
/// An entry is removed when **both** of these hold:
///
/// 1. **The owning process is not alive.** Each default-prefix entry
/// carries the originating process's PID in its basename
/// (`.tmp-{pid}-{name}` for [`crate::TempDir`],
/// `.tmpfile-{pid}-{name}` for [`crate::NamedTempFile`]). On Linux
/// liveness is checked via the presence of `/proc/{pid}`. On
/// macOS and Windows the liveness check is treated as "process is
/// dead" (since cross-platform process introspection without
/// platform deps is not available); the age check carries the
/// safety burden alone on those platforms.
/// 2. **The entry's mtime is at least `max_age_hours` old.** This is
/// the load-bearing safety guard on macOS and Windows: pick a
/// threshold larger than any process you expect to legitimately
/// hold temp paths.
///
/// Entries that do not match the crate's default prefix patterns,
/// including any caller-supplied `with_prefix(...)` paths, are never
/// touched. Likewise, legacy entries from `0.9.0` and `0.9.1` that
/// predate the PID-in-basename format are ignored: they have no
/// PID segment to parse and are not eligible for cleanup.
///
/// # Errors
///
/// Returns the underlying [`io::Error`] only if reading the OS temp
/// directory itself fails. Per-entry failures (permission denied,
/// entry disappeared between scan and removal, Windows handle still
/// open, etc.) are intentionally silent and not counted in the
/// return value. This matches the silent-Drop ethos for the rest of
/// the crate.
///
/// # Returns
///
/// The number of entries successfully removed.
///
/// # Example
///
/// ```no_run
/// use mod_tempdir::cleanup_orphans;
///
/// // At program startup, sweep anything older than 24 hours left
/// // behind by crashed earlier runs.
/// let removed = cleanup_orphans(24).unwrap_or(0);
/// eprintln!("cleanup_orphans removed {removed} orphaned entries");
/// ```
/// Returns `true` iff `entry` was successfully removed.
///
/// All non-fatal conditions (wrong prefix, malformed PID, live
/// process, too recent, removal error) return `false` quietly.
/// Returns `true` if process `pid` is alive on this host.
///
/// Linux: checks `/proc/{pid}` for existence.
///
/// macOS, Windows: returns `false` unconditionally. Cross-platform
/// process introspection without `libc` / `windows-sys` is not
/// available; the age check is the sole safety gate on those
/// platforms. Returning `false` here lets the AND condition in
/// [`cleanup_orphans`] degrade to age-only.