mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 02:25:23 +00:00
sys_util: Add wait_for_pid.
This adds a safe wrapper for libc::waitforpid that converts the *status field to an enum so the various edgecases can be handled. BUG=None TEST=cargo build Change-Id: Ic518e686b8ea60fa968f849f1cae571ebfe069e8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3199623 Reviewed-by: Mike Frysinger <vapier@chromium.org> Reviewed-by: Chirantan Ekbote <chirantan@chromium.org> Auto-Submit: Allen Webb <allenwebb@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Allen Webb <allenwebb@google.com>
This commit is contained in:
parent
f1cd8d7a66
commit
82316c3b40
1 changed files with 64 additions and 0 deletions
|
@ -89,6 +89,7 @@ pub use crate::signalfd::Error as SignalFdError;
|
||||||
pub use crate::write_zeroes::{PunchHole, WriteZeroes, WriteZeroesAt};
|
pub use crate::write_zeroes::{PunchHole, WriteZeroes, WriteZeroesAt};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fs::{remove_file, File, OpenOptions};
|
use std::fs::{remove_file, File, OpenOptions};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -274,6 +275,69 @@ pub fn fallocate(
|
||||||
syscall!(unsafe { libc::fallocate64(file.as_raw_fd(), mode, offset, len) }).map(|_| ())
|
syscall!(unsafe { libc::fallocate64(file.as_raw_fd(), mode, offset, len) }).map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait used to abstract types that provide a process id that can be operated on.
|
||||||
|
pub trait AsRawPid {
|
||||||
|
fn as_raw_pid(&self) -> Pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRawPid for Pid {
|
||||||
|
fn as_raw_pid(&self) -> Pid {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRawPid for std::process::Child {
|
||||||
|
fn as_raw_pid(&self) -> Pid {
|
||||||
|
self.id() as Pid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A logical set of the values *status can take from libc::wait and libc::waitpid.
|
||||||
|
pub enum WaitStatus {
|
||||||
|
Continued,
|
||||||
|
Exited(u8),
|
||||||
|
Running,
|
||||||
|
Signaled(Signal),
|
||||||
|
Stopped(Signal),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<c_int> for WaitStatus {
|
||||||
|
fn from(status: c_int) -> WaitStatus {
|
||||||
|
use WaitStatus::*;
|
||||||
|
if libc::WIFEXITED(status) {
|
||||||
|
Exited(libc::WEXITSTATUS(status) as u8)
|
||||||
|
} else if libc::WIFSIGNALED(status) {
|
||||||
|
Signaled(Signal::try_from(libc::WTERMSIG(status)).unwrap())
|
||||||
|
} else if libc::WIFSTOPPED(status) {
|
||||||
|
Stopped(Signal::try_from(libc::WSTOPSIG(status)).unwrap())
|
||||||
|
} else if libc::WIFCONTINUED(status) {
|
||||||
|
Continued
|
||||||
|
} else {
|
||||||
|
Running
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A safe wrapper around waitpid.
|
||||||
|
///
|
||||||
|
/// On success if a process was reaped, it will be returned as the first value.
|
||||||
|
/// The second returned value is the WaitStatus from the libc::waitpid() call.
|
||||||
|
///
|
||||||
|
/// Note: this can block if libc::WNOHANG is not set and EINTR is not handled internally.
|
||||||
|
pub fn wait_for_pid<A: AsRawPid>(pid: A, options: c_int) -> Result<(Option<Pid>, WaitStatus)> {
|
||||||
|
let pid = pid.as_raw_pid();
|
||||||
|
let mut status: c_int = 1;
|
||||||
|
// Safe because status is owned and the error is checked.
|
||||||
|
let ret = unsafe { libc::waitpid(pid, &mut status, options) };
|
||||||
|
if ret < 0 {
|
||||||
|
return errno_result();
|
||||||
|
}
|
||||||
|
Ok((
|
||||||
|
if ret == 0 { None } else { Some(ret) },
|
||||||
|
WaitStatus::from(status),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Reaps a child process that has terminated.
|
/// Reaps a child process that has terminated.
|
||||||
///
|
///
|
||||||
/// Returns `Ok(pid)` where `pid` is the process that was reaped or `Ok(0)` if none of the children
|
/// Returns `Ok(pid)` where `pid` is the process that was reaped or `Ok(0)` if none of the children
|
||||||
|
|
Loading…
Reference in a new issue