Skip to content

Commit 5faf25b

Browse files
committed
Check for non-zero return value from posix_spawn functions
The cvt function compares the argument with -1 and when equal returns a new io::Error constructed from errno. It is used together posix_spawn_* functions. This is incorrect. Those functions do not set errno. Instead they return non-zero error code directly. Check for non-zero return code and use it to construct a new io::Error.
1 parent 6b8d791 commit 5faf25b

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

library/std/src/sys/unix/process/process_unix.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ impl Command {
339339
}
340340
}
341341

342+
fn cvt_nz(error: libc::c_int) -> io::Result<()> {
343+
if error == 0 { Ok(()) } else { Err(io::Error::from_raw_os_error(error)) }
344+
}
345+
342346
unsafe {
343347
let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit());
344348
let mut attrs = PosixSpawnattr(MaybeUninit::uninit());
@@ -347,51 +351,51 @@ impl Command {
347351
libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr());
348352

349353
if let Some(fd) = stdio.stdin.fd() {
350-
cvt(libc::posix_spawn_file_actions_adddup2(
354+
cvt_nz(libc::posix_spawn_file_actions_adddup2(
351355
file_actions.0.as_mut_ptr(),
352356
fd,
353357
libc::STDIN_FILENO,
354358
))?;
355359
}
356360
if let Some(fd) = stdio.stdout.fd() {
357-
cvt(libc::posix_spawn_file_actions_adddup2(
361+
cvt_nz(libc::posix_spawn_file_actions_adddup2(
358362
file_actions.0.as_mut_ptr(),
359363
fd,
360364
libc::STDOUT_FILENO,
361365
))?;
362366
}
363367
if let Some(fd) = stdio.stderr.fd() {
364-
cvt(libc::posix_spawn_file_actions_adddup2(
368+
cvt_nz(libc::posix_spawn_file_actions_adddup2(
365369
file_actions.0.as_mut_ptr(),
366370
fd,
367371
libc::STDERR_FILENO,
368372
))?;
369373
}
370374
if let Some((f, cwd)) = addchdir {
371-
cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
375+
cvt_nz(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
372376
}
373377

374378
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
375379
cvt(sigemptyset(set.as_mut_ptr()))?;
376-
cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?;
380+
cvt_nz(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?;
377381
cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
378-
cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?;
382+
cvt_nz(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?;
379383

380384
let flags = libc::POSIX_SPAWN_SETSIGDEF | libc::POSIX_SPAWN_SETSIGMASK;
381-
cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;
385+
cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;
382386

383387
// Make sure we synchronize access to the global `environ` resource
384388
let _env_lock = sys::os::env_lock();
385389
let envp = envp.map(|c| c.as_ptr()).unwrap_or_else(|| *sys::os::environ() as *const _);
386-
let ret = libc::posix_spawnp(
390+
cvt_nz(libc::posix_spawnp(
387391
&mut p.pid,
388392
self.get_program_cstr().as_ptr(),
389393
file_actions.0.as_ptr(),
390394
attrs.0.as_ptr(),
391395
self.get_argv().as_ptr() as *const _,
392396
envp as *const _,
393-
);
394-
if ret == 0 { Ok(Some(p)) } else { Err(io::Error::from_raw_os_error(ret)) }
397+
))?;
398+
Ok(Some(p))
395399
}
396400
}
397401
}

0 commit comments

Comments
 (0)