Skip to content

Commit 7b71357

Browse files
authored
Add waitpid (#334)
1 parent db40491 commit 7b71357

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

io-uring-test/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ fn test<S: squeue::EntryMarker, C: cqueue::EntryMarker>(
156156
tests::futex::test_futex_wake(&mut ring, &test)?;
157157
tests::futex::test_futex_waitv(&mut ring, &test)?;
158158

159+
// os (process)
160+
tests::os::test_waitid(&mut ring, &test)?;
161+
159162
// regression test
160163
tests::regression::test_issue154(&mut ring, &test)?;
161164

io-uring-test/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod cancel;
22
pub mod fs;
33
pub mod futex;
44
pub mod net;
5+
pub mod os;
56
pub mod poll;
67
pub mod queue;
78
pub mod register;

io-uring-test/src/tests/os.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use crate::Test;
2+
use io_uring::{cqueue, opcode, squeue, IoUring};
3+
use std::process::{Command, Stdio};
4+
use std::thread;
5+
use std::time::Duration;
6+
7+
pub fn test_waitid<S: squeue::EntryMarker, C: cqueue::EntryMarker>(
8+
ring: &mut IoUring<S, C>,
9+
test: &Test,
10+
) -> anyhow::Result<()> {
11+
require!(
12+
test;
13+
test.probe.is_supported(opcode::WaitId::CODE);
14+
);
15+
16+
let mut child = Command::new("cat")
17+
.stdin(Stdio::piped())
18+
.stdout(Stdio::piped())
19+
.stderr(Stdio::null())
20+
.spawn()?;
21+
22+
let waitid_e = opcode::WaitId::new(libc::P_PID, child.id(), libc::WEXITED);
23+
24+
unsafe {
25+
let mut sq = ring.submission();
26+
sq.push(&waitid_e.build().user_data(0x110).into())
27+
.expect("queue is full");
28+
}
29+
30+
ring.submit()?;
31+
thread::sleep(Duration::from_millis(100));
32+
assert_eq!(ring.completion().len(), 0);
33+
34+
// close cat
35+
child.stdin = None;
36+
child.stdout = None;
37+
38+
ring.submit_and_wait(1)?;
39+
let cqes: Vec<cqueue::Entry> = ring.completion().map(Into::into).collect();
40+
41+
assert_eq!(cqes.len(), 1);
42+
assert_eq!(cqes[0].user_data(), 0x110);
43+
assert_eq!(cqes[0].result(), 0);
44+
45+
Ok(())
46+
}

src/opcode.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,34 @@ opcode! {
18791879
}
18801880
}
18811881

1882+
opcode! {
1883+
/// Issue the equivalent of a `waitid(2)` system call.
1884+
///
1885+
/// Available since kernel 6.7.
1886+
#[derive(Debug)]
1887+
pub struct WaitId {
1888+
idtype: { libc::idtype_t },
1889+
id: { libc::id_t },
1890+
options: { libc::c_int },
1891+
;;
1892+
infop: *const libc::siginfo_t = std::ptr::null(),
1893+
flags: libc::c_uint = 0,
1894+
}
1895+
1896+
pub const CODE = sys::IORING_OP_WAITID;
1897+
1898+
pub fn build(self) -> Entry {
1899+
let mut sqe = sqe_zeroed();
1900+
sqe.opcode = Self::CODE;
1901+
sqe.fd = self.id as _;
1902+
sqe.len = self.idtype as _;
1903+
sqe.__bindgen_anon_3.waitid_flags = self.flags;
1904+
sqe.__bindgen_anon_5.file_index = self.options as _;
1905+
sqe.__bindgen_anon_1.addr2 = self.infop as _;
1906+
Entry(sqe)
1907+
}
1908+
}
1909+
18821910
// === 6.8 ===
18831911

18841912
opcode! {

0 commit comments

Comments
 (0)