Giter VIP home page Giter VIP logo

async-pidfd's Introduction

Process file descriptors (pidfd) for Linux

Process file descriptors (pidfd) provide a race-free way to manage processes on Linux, maintaining a persistent reference to a process using a file descriptor rather than a numeric process ID (PID) that could be reused after the process exits.

async-pidfd provides Rust support for pidfd, and supports managing processes both synchronously (via the PidFd type) and asynchronously (via the AsyncPidFd type).

Sync - PidFd

The PidFd type manages processes synchronously. Use PidFd::from_pid to construct a PidFd from a process ID, such as from Child::id in the standard library. (Note that the portable Child::id function returns process IDs as u32, rather than as a libc::pid_t, necessitating a cast.)

use std::os::unix::process::ExitStatusExt;
use std::process::{Command, ExitStatus};

use async_pidfd::PidFd;

fn main() -> std::io::Result<()> {
    let child = Command::new("/bin/true").spawn()?;
    let pidfd = PidFd::from_pid(child.id() as libc::pid_t)?;
    let status = pidfd.wait()?.status();
    assert_eq!(status.code(), Some(0));

    let child = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn()?;
    let pidfd = PidFd::from_pid(child.id() as libc::pid_t)?;
    let status = pidfd.wait()?.status();
    assert_eq!(status.signal(), Some(9));

    Ok(())
}

PidFd::wait returns information about an exited process via the ExitInfo structure. ExitInfo includes a libc::siginfo_t indicating how the process exited (including the exit code if it exited normally, or the signal if it was killed by a signal), and a libc::rusage describing the resource usage of the process and its children. libc::siginfo_t has complex semantics; to get a std::process::ExitStatus instead, you can call .status() on an ExitInfo.

Note that while opening the PID for an arbitrary process can potentially race with the exit of that process, opening the PID for a child process that you have not yet waited on is safe, as the process ID will not get reused until you wait on the process (or block SIGCHLD).

If you only want to use the synchronous PidFd type, you can use async-pidfd with default-features = false in Cargo.toml to remove async-related dependencies.

Async - AsyncPidFd

The AsyncPidFd type manages processes asynchronously, based on the async-io crate by Stjepan Glavina. async-io provides an Async wrapper that makes it easy to turn any synchronous type based on a file descriptor into an asynchronous type; the resulting asynchronous code uses epoll to wait for all the file descriptors concurrently.

AsyncPidFd wraps an Async<PidFd> and provides the same API as PidFd, but with an async version of the wait function.

use std::os::unix::process::ExitStatusExt;
use std::process::{Command, ExitStatus};

use async_pidfd::AsyncPidFd;
use futures_lite::future;

async fn async_spawn_and_status(cmd: &mut Command) -> std::io::Result<ExitStatus> {
    let child = cmd.spawn()?;
    let pidfd = AsyncPidFd::from_pid(child.id() as libc::pid_t)?;
    Ok(pidfd.wait().await?.status())
}

fn main() -> std::io::Result<()> {
    future::block_on(async {
        let (status1, status2) = future::try_join(
            async_spawn_and_status(&mut Command::new("/bin/true")),
            async_spawn_and_status(&mut Command::new("/bin/false")),
        )
        .await?;
        assert_eq!(status1.code(), Some(0));
        assert_eq!(status2.code(), Some(1));
        Ok(())
    })
}

async-pidfd's People

Contributors

joshtriplett avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.