Skip to content

Commit eb68ba3

Browse files
oxalicasunfishcode
andauthored
Reconsider guarantees of Pid and refactor (#657)
* Reconsider guarantees of `Pid` and refactor 1. `Pid` and `RawPid` use `NonZeroI32` and `i32` now. `Pid` are guaranteed to be in range `1..=i32::MAX`. Notice that pid range should be enforced for all APIs, and negative values are exploited by Linux for different functionalities (eg, kill(2) a process group instead of a process). We should validate that range to prevent accidental misfunction, no matter for `i32` or `u32`. So here we consistently use a wrapped `i32` for both linux_raw and libc backend. Two constructor `Pid::from_raw{,_unchecked}` are provided to either do or bypass the check. These APIs also simplify code a lot. 2. `Pid::from_raw_nonzero` is removed. As mentioned in (1), the range guarantee is stricter now and only the nonzero property cannot help much. This is a breaking change. 3. `Pid::from_raw` is safe now. We are not possible to make any guarantee for an arbitrary non-children pid at all, and an invalid pid causes nothing more than a logic error. But since we use `NonZeroI32` internally, `Pid::from_raw_unchecked` is still unsafe. * Fix typo in doc of `Pid::is_init` * Clean up unnecessary `unsafe` and `unwrap` * Remove `unsafe` for `Pid::from_raw` on FreeBSD and Darwin * Disable debug_assert in `Pid::from_raw_unchecked` due to MSRV * Re-enable `debug_assert!` in a const fn, now that our MSRV is 1.63. * Remove `RawNonZeroPid`. * Make `get_reaper_status`'s `pid` result optional. The documentation for the field is qualified with "if there are any descendants". It appears if there are no descendents, the `rs_pid` field is -1. Check for this case, to avoid trying to convert -1 to a `Pid`. --------- Co-authored-by: Dan Gohman <[email protected]>
1 parent fbd0f2d commit eb68ba3

File tree

15 files changed

+85
-109
lines changed

15 files changed

+85
-109
lines changed

src/backend/libc/pid/syscalls.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
//! libc syscalls for PIDs
22
33
use crate::backend::c;
4-
use crate::pid::{Pid, RawNonZeroPid};
4+
use crate::pid::Pid;
55

66
#[cfg(not(target_os = "wasi"))]
77
#[inline]
88
#[must_use]
99
pub(crate) fn getpid() -> Pid {
1010
unsafe {
1111
let pid = c::getpid();
12-
debug_assert_ne!(pid, 0);
13-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))
12+
Pid::from_raw_unchecked(pid)
1413
}
1514
}

src/backend/libc/process/syscalls.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::process::Uid;
2626
#[cfg(linux_kernel)]
2727
use crate::process::{Cpuid, MembarrierCommand, MembarrierQuery};
2828
#[cfg(not(target_os = "wasi"))]
29-
use crate::process::{Gid, Pid, RawNonZeroPid, RawPid, Signal, WaitOptions, WaitStatus};
29+
use crate::process::{Gid, Pid, RawPid, Signal, WaitOptions, WaitStatus};
3030
#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
3131
use crate::process::{Resource, Rlimit};
3232
#[cfg(not(any(target_os = "redox", target_os = "openbsd", target_os = "wasi")))]
@@ -109,8 +109,7 @@ pub(crate) fn getppid() -> Option<Pid> {
109109
pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> {
110110
unsafe {
111111
let pgid = ret_pid_t(c::getpgid(Pid::as_raw(pid) as _))?;
112-
debug_assert_ne!(pgid, 0);
113-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid)))
112+
Ok(Pid::from_raw_unchecked(pgid))
114113
}
115114
}
116115

@@ -126,8 +125,7 @@ pub(crate) fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> {
126125
pub(crate) fn getpgrp() -> Pid {
127126
unsafe {
128127
let pgid = c::getpgrp();
129-
debug_assert_ne!(pgid, 0);
130-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid))
128+
Pid::from_raw_unchecked(pgid)
131129
}
132130
}
133131

@@ -336,12 +334,7 @@ pub(crate) fn _waitpid(
336334
unsafe {
337335
let mut status: c::c_int = 0;
338336
let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?;
339-
Ok(RawNonZeroPid::new(pid).map(|non_zero| {
340-
(
341-
Pid::from_raw_nonzero(non_zero),
342-
WaitStatus::new(status as _),
343-
)
344-
}))
337+
Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status as _))))
345338
}
346339
}
347340

@@ -442,8 +435,7 @@ unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidS
442435
pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> {
443436
unsafe {
444437
let pid = ret_pid_t(c::getsid(Pid::as_raw(pid) as _))?;
445-
debug_assert_ne!(pid, 0);
446-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
438+
Ok(Pid::from_raw_unchecked(pid))
447439
}
448440
}
449441

@@ -452,8 +444,7 @@ pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> {
452444
pub(crate) fn setsid() -> io::Result<Pid> {
453445
unsafe {
454446
let pid = ret_c_int(c::setsid())?;
455-
debug_assert_ne!(pid, 0);
456-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
447+
Ok(Pid::from_raw_unchecked(pid))
457448
}
458449
}
459450

src/backend/libc/termios/syscalls.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use core::mem::MaybeUninit;
1414
#[cfg(not(target_os = "wasi"))]
1515
use {
1616
crate::io,
17-
crate::pid::{Pid, RawNonZeroPid},
17+
crate::pid::Pid,
1818
crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize},
1919
};
2020

@@ -52,8 +52,7 @@ pub(crate) fn tcgetattr2(fd: BorrowedFd<'_>) -> io::Result<crate::termios::Termi
5252
pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> {
5353
unsafe {
5454
let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?;
55-
debug_assert_ne!(pid, 0);
56-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
55+
Ok(Pid::from_raw_unchecked(pid))
5756
}
5857
}
5958

@@ -128,8 +127,7 @@ pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> {
128127
pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result<Pid> {
129128
unsafe {
130129
let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?;
131-
debug_assert_ne!(pid, 0);
132-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
130+
Ok(Pid::from_raw_unchecked(pid))
133131
}
134132
}
135133

src/backend/libc/thread/syscalls.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use core::mem::MaybeUninit;
1515
use {
1616
crate::backend::conv::{borrowed_fd, ret_c_int, syscall_ret},
1717
crate::fd::BorrowedFd,
18-
crate::pid::{Pid, RawNonZeroPid},
18+
crate::pid::Pid,
1919
crate::utils::as_mut_ptr,
2020
};
2121
#[cfg(not(any(
@@ -285,8 +285,7 @@ pub(crate) fn gettid() -> Pid {
285285

286286
unsafe {
287287
let tid = gettid();
288-
debug_assert_ne!(tid, 0);
289-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid))
288+
Pid::from_raw_unchecked(tid)
290289
}
291290
}
292291

src/backend/linux_raw/pid/syscalls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
#![allow(clippy::undocumented_unsafe_blocks)]
88

99
use crate::backend::conv::ret_usize_infallible;
10-
use crate::pid::{Pid, RawNonZeroPid, RawPid};
10+
use crate::pid::{Pid, RawPid};
1111

1212
#[inline]
1313
pub(crate) fn getpid() -> Pid {
1414
unsafe {
1515
let pid = ret_usize_infallible(syscall_readonly!(__NR_getpid)) as RawPid;
1616
debug_assert!(pid > 0);
17-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid as _))
17+
Pid::from_raw_unchecked(pid)
1818
}
1919
}

src/backend/linux_raw/process/syscalls.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::fd::{AsRawFd, BorrowedFd, OwnedFd, RawFd};
1919
#[cfg(feature = "fs")]
2020
use crate::ffi::CStr;
2121
use crate::io;
22-
use crate::pid::{RawNonZeroPid, RawPid};
22+
use crate::pid::RawPid;
2323
use crate::process::{
2424
Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, PidfdFlags, PidfdGetfdFlags, Resource,
2525
Rlimit, Uid, WaitId, WaitOptions, WaitStatus, WaitidOptions, WaitidStatus,
@@ -105,7 +105,7 @@ pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> {
105105
unsafe {
106106
let pgid = ret_c_int(syscall_readonly!(__NR_getpgid, c_int(Pid::as_raw(pid))))?;
107107
debug_assert!(pgid > 0);
108-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid)))
108+
Ok(Pid::from_raw_unchecked(pgid))
109109
}
110110
}
111111

@@ -127,15 +127,15 @@ pub(crate) fn getpgrp() -> Pid {
127127
unsafe {
128128
let pgid = ret_c_int_infallible(syscall_readonly!(__NR_getpgrp));
129129
debug_assert!(pgid > 0);
130-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid))
130+
Pid::from_raw_unchecked(pgid)
131131
}
132132

133133
// Otherwise use `getpgrp` and pass it zero.
134134
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
135135
unsafe {
136136
let pgid = ret_c_int_infallible(syscall_readonly!(__NR_getpgid, c_uint(0)));
137137
debug_assert!(pgid > 0);
138-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid))
138+
Pid::from_raw_unchecked(pgid)
139139
}
140140
}
141141

@@ -453,12 +453,7 @@ pub(crate) fn _waitpid(
453453
c_int(waitopts.bits() as _),
454454
zero()
455455
))?;
456-
Ok(RawNonZeroPid::new(pid).map(|non_zero| {
457-
(
458-
Pid::from_raw_nonzero(non_zero),
459-
WaitStatus::new(status.assume_init()),
460-
)
461-
}))
456+
Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status.assume_init()))))
462457
}
463458
}
464459

@@ -551,7 +546,7 @@ pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> {
551546
unsafe {
552547
let pid = ret_c_int(syscall_readonly!(__NR_getsid, c_int(Pid::as_raw(pid))))?;
553548
debug_assert!(pid > 0);
554-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
549+
Ok(Pid::from_raw_unchecked(pid))
555550
}
556551
}
557552

@@ -560,7 +555,7 @@ pub(crate) fn setsid() -> io::Result<Pid> {
560555
unsafe {
561556
let pid = ret_c_int(syscall_readonly!(__NR_setsid))?;
562557
debug_assert!(pid > 0);
563-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
558+
Ok(Pid::from_raw_unchecked(pid))
564559
}
565560
}
566561

src/backend/linux_raw/runtime/syscalls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::ffi::CStr;
1818
#[cfg(feature = "fs")]
1919
use crate::fs::AtFlags;
2020
use crate::io;
21-
use crate::pid::{Pid, RawNonZeroPid};
21+
use crate::pid::Pid;
2222
use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack};
2323
use crate::signal::Signal;
2424
use crate::timespec::Timespec;
@@ -101,7 +101,7 @@ pub(crate) mod tls {
101101
pub(crate) unsafe fn set_tid_address(data: *mut c::c_void) -> Pid {
102102
let tid: i32 = ret_c_int_infallible(syscall_readonly!(__NR_set_tid_address, data));
103103
debug_assert_ne!(tid, 0);
104-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid))
104+
Pid::from_raw_unchecked(tid)
105105
}
106106

107107
#[inline]

src/backend/linux_raw/termios/syscalls.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::backend::c;
1010
use crate::backend::conv::{by_ref, c_uint, ret};
1111
use crate::fd::BorrowedFd;
1212
use crate::io;
13-
use crate::pid::{Pid, RawNonZeroPid};
13+
use crate::pid::Pid;
1414
#[cfg(feature = "procfs")]
1515
use crate::procfs;
1616
use crate::termios::{
@@ -75,7 +75,7 @@ pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> {
7575
ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGPGRP), &mut result))?;
7676
let pid = result.assume_init();
7777
debug_assert!(pid > 0);
78-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
78+
Ok(Pid::from_raw_unchecked(pid))
7979
}
8080
}
8181

@@ -169,7 +169,7 @@ pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result<Pid> {
169169
ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGSID), &mut result))?;
170170
let pid = result.assume_init();
171171
debug_assert!(pid > 0);
172-
Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
172+
Ok(Pid::from_raw_unchecked(pid))
173173
}
174174
}
175175

src/backend/linux_raw/thread/syscalls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::backend::conv::{
1313
};
1414
use crate::fd::BorrowedFd;
1515
use crate::io;
16-
use crate::pid::{Pid, RawNonZeroPid};
16+
use crate::pid::Pid;
1717
use crate::thread::{ClockId, FutexFlags, FutexOperation, NanosleepRelativeResult, Timespec};
1818
use core::mem::MaybeUninit;
1919
#[cfg(target_pointer_width = "32")]
@@ -201,7 +201,7 @@ pub(crate) fn gettid() -> Pid {
201201
unsafe {
202202
let tid = ret_c_int_infallible(syscall_readonly!(__NR_gettid));
203203
debug_assert_ne!(tid, 0);
204-
Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid))
204+
Pid::from_raw_unchecked(tid)
205205
}
206206
}
207207

src/event/kqueue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl Event {
113113
flags: VnodeEvents::from_bits_truncate(self.inner.fflags),
114114
},
115115
c::EVFILT_PROC => EventFilter::Proc {
116-
pid: unsafe { Pid::from_raw(self.inner.ident as _) }.unwrap(),
116+
pid: Pid::from_raw(self.inner.ident as _).unwrap(),
117117
flags: ProcessEvents::from_bits_truncate(self.inner.fflags),
118118
},
119119
c::EVFILT_SIGNAL => EventFilter::Signal {

0 commit comments

Comments
 (0)