From ecd98795e4715491b0e104eed818f64f6361cb5a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Sep 2024 11:16:21 -0700 Subject: [PATCH] Add a changelog entry for the `fcntl_setpipe_size` change. (#1165) Also add another test, and make the names of the private implementation functions match the names of the public function. --- CHANGELOG.md | 3 +++ src/backend/libc/pipe/syscalls.rs | 4 ++-- src/backend/linux_raw/pipe/syscalls.rs | 4 ++-- src/pipe.rs | 4 ++-- tests/pipe/fcntl.rs | 30 ++++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcc492c57..9e8709bd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changes from 0.38.x to 1.0 +`rustix::pipe::fcntl_getpipe_size` now returns the new size, which may be +greater than the requested size. + `rustix::thread::FutexOperation` and `rustix::thread::futex` are removed. Use the functions in the `rustix::thread::futex` module instead. diff --git a/src/backend/libc/pipe/syscalls.rs b/src/backend/libc/pipe/syscalls.rs index 54cd2e080..21aec0296 100644 --- a/src/backend/libc/pipe/syscalls.rs +++ b/src/backend/libc/pipe/syscalls.rs @@ -112,13 +112,13 @@ pub(crate) fn tee( #[cfg(linux_kernel)] #[inline] -pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result { +pub(crate) fn fcntl_getpipe_size(fd: BorrowedFd<'_>) -> io::Result { unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETPIPE_SZ)).map(|size| size as usize) } } #[cfg(linux_kernel)] #[inline] -pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result { +pub(crate) fn fcntl_setpipe_size(fd: BorrowedFd<'_>, size: usize) -> io::Result { let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?; unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)).map(|size| size as usize) } diff --git a/src/backend/linux_raw/pipe/syscalls.rs b/src/backend/linux_raw/pipe/syscalls.rs index 367c68bb0..86fe08553 100644 --- a/src/backend/linux_raw/pipe/syscalls.rs +++ b/src/backend/linux_raw/pipe/syscalls.rs @@ -99,7 +99,7 @@ pub(crate) fn tee( } #[inline] -pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result { +pub(crate) fn fcntl_getpipe_size(fd: BorrowedFd<'_>) -> io::Result { #[cfg(target_pointer_width = "32")] unsafe { ret_usize(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETPIPE_SZ))) @@ -111,7 +111,7 @@ pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result { } #[inline] -pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result { +pub(crate) fn fcntl_setpipe_size(fd: BorrowedFd<'_>, size: usize) -> io::Result { let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?; #[cfg(target_pointer_width = "32")] diff --git a/src/pipe.rs b/src/pipe.rs index e52f1f9a4..30932323b 100644 --- a/src/pipe.rs +++ b/src/pipe.rs @@ -204,7 +204,7 @@ pub fn tee( #[cfg(linux_kernel)] #[inline] pub fn fcntl_getpipe_size(fd: Fd) -> io::Result { - backend::pipe::syscalls::fcntl_getpipe_sz(fd.as_fd()) + backend::pipe::syscalls::fcntl_getpipe_size(fd.as_fd()) } /// `fnctl(fd, F_SETPIPE_SZ)`—Set the buffer capacity of a pipe. @@ -216,5 +216,5 @@ pub fn fcntl_getpipe_size(fd: Fd) -> io::Result { #[cfg(linux_kernel)] #[inline] pub fn fcntl_setpipe_size(fd: Fd, size: usize) -> io::Result { - backend::pipe::syscalls::fcntl_setpipe_sz(fd.as_fd(), size) + backend::pipe::syscalls::fcntl_setpipe_size(fd.as_fd(), size) } diff --git a/tests/pipe/fcntl.rs b/tests/pipe/fcntl.rs index 2d489e12b..ae173fc7f 100644 --- a/tests/pipe/fcntl.rs +++ b/tests/pipe/fcntl.rs @@ -29,3 +29,33 @@ fn test_fcntl_setpipe_size() { assert_eq!(reader_size, new_size); assert_eq!(reader_size, writer_size); } + +/// Test that we can write up to the pipe buffer size without blocking. +#[cfg(linux_kernel)] +#[test] +fn test_fcntl_pipe_sized_writes() { + use rustix::io::{read, write}; + use rustix::pipe::{fcntl_getpipe_size, fcntl_setpipe_size}; + + let (reader, writer) = rustix::pipe::pipe().unwrap(); + + let size = fcntl_getpipe_size(&reader).unwrap(); + + let ones = vec![1; size]; + assert_eq!(write(&writer, &ones), Ok(size)); + let mut buf = vec![2; size]; + assert_eq!(read(&reader, &mut buf), Ok(size)); + assert_eq!(buf, ones); + + let size = size * 2; + let set_size = fcntl_setpipe_size(&reader, size).unwrap(); + let get_size = fcntl_getpipe_size(&reader).unwrap(); + assert_eq!(size, set_size); + assert_eq!(size, get_size); + + let ones = vec![1; size]; + assert_eq!(write(&writer, &ones), Ok(size)); + let mut buf = vec![2; size]; + assert_eq!(read(&reader, &mut buf), Ok(size)); + assert_eq!(buf, ones); +}