Commit e629345
committed
fix(unix): retry EINTR in poll/select/read so unrelated signals don't surface as spurious key events
`read_single_key_impl` blocks in `poll`/`select` on the tty fd. Any
signal that interrupts that syscall — SIGCHLD from a dying child,
SIGWINCH from a terminal resize, etc. — currently propagates as
`io::ErrorKind::Interrupted`, which `read_single_key` then treats as
'the user pressed Ctrl-C' and forwards by calling `libc::raise(SIGINT)`
on the process. With the default SIGINT handler this kills the program
with exit code 130; with cliclack-style consumers it cancels the prompt.
The original intent of `Err(Interrupted)` is to signal a Ctrl-C byte
(`\\x03`) read from the tty, which `read_bytes` synthesizes
explicitly. Real EINTR from a signal is unrelated and should be retried
per the standard idiom.
This patch retries EINTR inside the syscall wrappers (`poll_fd`,
`select_fd`, `read_bytes`) so `Err(Interrupted)` reaching
`read_single_key` unambiguously means a Ctrl-C byte was read, and
unrelated signals are transparent to callers.
Repro before this patch: any program that fork+execs a child and uses
a console-based prompt (cliclack, dialoguer, etc.) shortly after the
child exits will randomly bail at the prompt because SIGCHLD interrupts
`select` mid-prompt.1 parent 586efad commit e629345
1 file changed
Lines changed: 70 additions & 44 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
165 | 172 | | |
166 | 173 | | |
167 | 174 | | |
168 | 175 | | |
169 | 176 | | |
170 | 177 | | |
171 | | - | |
| 178 | + | |
| 179 | + | |
172 | 180 | | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
180 | 190 | | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
197 | 211 | | |
198 | 212 | | |
199 | 213 | | |
| |||
230 | 244 | | |
231 | 245 | | |
232 | 246 | | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
233 | 253 | | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
243 | | - | |
244 | | - | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
249 | 275 | | |
250 | 276 | | |
251 | 277 | | |
| |||
0 commit comments