Skip to content

Commit 4d89bc6

Browse files
committed
Auto merge of rust-lang#74699 - notriddle:fd-non-negative, r=m-ou-se
Mark `-1` as an available niche for file descriptors Based on discussion from <https://internals.rust-lang.org/t/can-the-standard-library-shrink-option-file/12768>, the file descriptor `-1` is chosen based on the POSIX API designs that use it as a sentinel to report errors. A bigger niche could've been chosen, particularly on Linux, but would not necessarily be portable. This PR also adds a test case to ensure that the -1 niche (which is kind of hacky and has no obvious test case) works correctly. It requires the "upper" bound, which is actually -1, to be expressed in two's complement.
2 parents 1977565 + eaf9ea7 commit 4d89bc6

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

std/src/sys/unix/fd.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ use crate::sys_common::AsInner;
1212
use libc::{c_int, c_void};
1313

1414
#[derive(Debug)]
15+
#[rustc_layout_scalar_valid_range_start(0)]
16+
// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a
17+
// 32-bit c_int. Below is -2, in two's complement, but that only works out
18+
// because c_int is 32 bits.
19+
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
1520
pub struct FileDesc {
1621
fd: c_int,
1722
}
@@ -63,7 +68,9 @@ const fn max_iov() -> usize {
6368

6469
impl FileDesc {
6570
pub fn new(fd: c_int) -> FileDesc {
66-
FileDesc { fd }
71+
assert_ne!(fd, -1i32);
72+
// SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned)
73+
unsafe { FileDesc { fd } }
6774
}
6875

6976
pub fn raw(&self) -> c_int {

std/src/sys/unix/fd/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::mem::ManuallyDrop;
33

44
#[test]
55
fn limit_vector_count() {
6-
let stdout = ManuallyDrop::new(FileDesc { fd: 1 });
6+
let stdout = ManuallyDrop::new(unsafe { FileDesc { fd: 1 } });
77
let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>();
88
assert!(stdout.write_vectored(&bufs).is_ok());
99
}

0 commit comments

Comments
 (0)