Skip to content

Commit c8fe26b

Browse files
authored
Fix fcntl_setpipe_size return value (#1163) (#1164)
`fcntl` man page says that: > F_SETPIPE_SZ ... The actual capacity (in bytes) that is set is > returned as the function result. But the current `fcntl_setpipe_size` function assumes that the return value is 0 (success) or negative (failure). This makes the function panic due to `debug_assert!` in debug mode, and it returns `Err` on success in release mode. This commit fixes the return value type and its checking, and adds a test for it.
1 parent f6f19e0 commit c8fe26b

File tree

5 files changed

+38
-6
lines changed

5 files changed

+38
-6
lines changed

src/backend/libc/pipe/syscalls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> {
118118

119119
#[cfg(linux_kernel)]
120120
#[inline]
121-
pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> {
121+
pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<usize> {
122122
let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?;
123123

124-
unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)) }
124+
unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)).map(|size| size as usize) }
125125
}

src/backend/linux_raw/pipe/syscalls.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> {
111111
}
112112

113113
#[inline]
114-
pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> {
114+
pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<usize> {
115115
let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?;
116116

117117
#[cfg(target_pointer_width = "32")]
118118
unsafe {
119-
ret(syscall_readonly!(
119+
ret_usize(syscall_readonly!(
120120
__NR_fcntl64,
121121
fd,
122122
c_uint(F_SETPIPE_SZ),
@@ -125,7 +125,7 @@ pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()
125125
}
126126
#[cfg(target_pointer_width = "64")]
127127
unsafe {
128-
ret(syscall_readonly!(
128+
ret_usize(syscall_readonly!(
129129
__NR_fcntl,
130130
fd,
131131
c_uint(F_SETPIPE_SZ),

src/pipe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,6 @@ pub fn fcntl_getpipe_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> {
215215
/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
216216
#[cfg(linux_kernel)]
217217
#[inline]
218-
pub fn fcntl_setpipe_size<Fd: AsFd>(fd: Fd, size: usize) -> io::Result<()> {
218+
pub fn fcntl_setpipe_size<Fd: AsFd>(fd: Fd, size: usize) -> io::Result<usize> {
219219
backend::pipe::syscalls::fcntl_setpipe_sz(fd.as_fd(), size)
220220
}

tests/pipe/fcntl.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#[cfg(linux_kernel)]
2+
#[test]
3+
fn test_fcntl_getpipe_size() {
4+
use rustix::pipe::fcntl_getpipe_size;
5+
6+
let (reader, writer) = rustix::pipe::pipe().unwrap();
7+
8+
let reader_size = fcntl_getpipe_size(&reader).unwrap();
9+
let writer_size = fcntl_getpipe_size(&writer).unwrap();
10+
assert_eq!(reader_size, writer_size);
11+
}
12+
13+
#[cfg(linux_kernel)]
14+
#[test]
15+
fn test_fcntl_setpipe_size() {
16+
use rustix::pipe::{fcntl_getpipe_size, fcntl_setpipe_size};
17+
18+
let (reader, writer) = rustix::pipe::pipe().unwrap();
19+
20+
let new_size = 4096 * 2;
21+
let reader_size = fcntl_setpipe_size(&reader, new_size).unwrap();
22+
let writer_size = fcntl_getpipe_size(&writer).unwrap();
23+
assert_eq!(reader_size, new_size);
24+
assert_eq!(reader_size, writer_size);
25+
26+
let new_size = 4096 * 16;
27+
let reader_size = fcntl_setpipe_size(&reader, new_size).unwrap();
28+
let writer_size = fcntl_getpipe_size(&writer).unwrap();
29+
assert_eq!(reader_size, new_size);
30+
assert_eq!(reader_size, writer_size);
31+
}

tests/pipe/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
#![cfg(not(windows))]
55

66
mod basic;
7+
mod fcntl;
78
mod splice;
89
mod tee;

0 commit comments

Comments
 (0)