{"id":16828048,"url":"https://github.com/joshtriplett/async-pidfd","last_synced_at":"2025-04-09T16:19:54.727Z","repository":{"id":48307697,"uuid":"286650106","full_name":"joshtriplett/async-pidfd","owner":"joshtriplett","description":"Rust crate to use process file descriptors (pidfd) for Linux","archived":false,"fork":false,"pushed_at":"2024-03-31T07:07:36.000Z","size":14,"stargazers_count":46,"open_issues_count":3,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T16:19:50.894Z","etag":null,"topics":["asynchronous","pidfd","process"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joshtriplett.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-11T05:02:35.000Z","updated_at":"2025-02-12T06:24:24.000Z","dependencies_parsed_at":"2024-10-26T21:14:25.702Z","dependency_job_id":"655beda6-503f-4b61-b663-0e89e1d7a4b6","html_url":"https://github.com/joshtriplett/async-pidfd","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshtriplett%2Fasync-pidfd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshtriplett%2Fasync-pidfd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshtriplett%2Fasync-pidfd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshtriplett%2Fasync-pidfd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshtriplett","download_url":"https://codeload.github.com/joshtriplett/async-pidfd/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065281,"owners_count":21041872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous","pidfd","process"],"created_at":"2024-10-13T11:24:22.646Z","updated_at":"2025-04-09T16:19:54.706Z","avatar_url":"https://github.com/joshtriplett.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"Process file descriptors (`pidfd`) for Linux\n============================================\n\nProcess file descriptors (`pidfd`) provide a race-free way to manage processes\non Linux, maintaining a persistent reference to a process using a file\ndescriptor rather than a numeric process ID (PID) that could be reused after\nthe process exits.\n\nThis crate only works on Linux; if you need support for other platforms, or for\nolder Linux kernels, see\n[async-process](https://crates.io/crates/async-process).\n\n`async-pidfd` provides Rust support for pidfd, and supports managing processes\nboth synchronously (via the `PidFd` type) and asynchronously (via the\n`AsyncPidFd` type).\n\nSync - `PidFd`\n--------------\n\nThe `PidFd` type manages processes synchronously.  Use `PidFd::from_pid` to\nconstruct a `PidFd` from a process ID, such as from\n[`Child::id`](https://doc.rust-lang.org/std/process/struct.Child.html#method.id)\nin the standard library. (Note that the portable `Child::id` function returns\nprocess IDs as `u32`, rather than as a `libc::pid_t`, necessitating a cast.)\n\n```rust\nuse std::os::unix::process::ExitStatusExt;\nuse std::process::{Command, ExitStatus};\n\nuse async_pidfd::PidFd;\n\nfn main() -\u003e std::io::Result\u003c()\u003e {\n    let child = Command::new(\"/bin/true\").spawn()?;\n    let pidfd = PidFd::from_pid(child.id() as libc::pid_t)?;\n    let status = pidfd.wait()?.status();\n    assert_eq!(status.code(), Some(0));\n\n    let child = Command::new(\"/bin/sh\").arg(\"-c\").arg(\"kill -9 $$\").spawn()?;\n    let pidfd = PidFd::from_pid(child.id() as libc::pid_t)?;\n    let status = pidfd.wait()?.status();\n    assert_eq!(status.signal(), Some(9));\n\n    Ok(())\n}\n```\n\n`PidFd::wait` returns information about an exited process via the `ExitInfo`\nstructure. `ExitInfo` includes a `libc::siginfo_t` indicating how the process\nexited (including the exit code if it exited normally, or the signal if it was\nkilled by a signal), and a `libc::rusage` describing the resource usage of the\nprocess and its children. `libc::siginfo_t` has complex semantics; to get a\n[`std::process::ExitStatus`](https://doc.rust-lang.org/std/process/struct.ExitStatus.html)\ninstead, you can call `.status()` on an `ExitInfo`.\n\nNote that while opening the PID for an arbitrary process can potentially race\nwith the exit of that process, opening the PID for a child process that you\nhave not yet waited on is safe, as the process ID will not get reused until you\nwait on the process (or block `SIGCHLD`).\n\nIf you only want to use the synchronous `PidFd` type, you can use `async-pidfd`\nwith `default-features = false` in `Cargo.toml` to remove async-related\ndependencies.\n\nAsync - `AsyncPidFd`\n--------------------\n\nThe `AsyncPidFd` type manages processes asynchronously, based on the\n[`async-io`](https://docs.rs/async-io/) crate by Stjepan Glavina. `async-io`\nprovides an `Async` wrapper that makes it easy to turn any synchronous type\nbased on a file descriptor into an asynchronous type; the resulting\nasynchronous code uses `epoll` to wait for all the file descriptors\nconcurrently.\n\n`AsyncPidFd` wraps an `Async\u003cPidFd\u003e` and provides the same API as `PidFd`, but\nwith an `async` version of the `wait` function.\n\n```rust\nuse std::os::unix::process::ExitStatusExt;\nuse std::process::{Command, ExitStatus};\n\nuse async_pidfd::AsyncPidFd;\nuse futures_lite::future;\n\nasync fn async_spawn_and_status(cmd: \u0026mut Command) -\u003e std::io::Result\u003cExitStatus\u003e {\n    let child = cmd.spawn()?;\n    let pidfd = AsyncPidFd::from_pid(child.id() as libc::pid_t)?;\n    Ok(pidfd.wait().await?.status())\n}\n\nfn main() -\u003e std::io::Result\u003c()\u003e {\n    future::block_on(async {\n        let (status1, status2) = future::try_join(\n            async_spawn_and_status(\u0026mut Command::new(\"/bin/true\")),\n            async_spawn_and_status(\u0026mut Command::new(\"/bin/false\")),\n        )\n        .await?;\n        assert_eq!(status1.code(), Some(0));\n        assert_eq!(status2.code(), Some(1));\n        Ok(())\n    })\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshtriplett%2Fasync-pidfd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshtriplett%2Fasync-pidfd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshtriplett%2Fasync-pidfd/lists"}