Skip to content

Commit

Permalink
Remove READ_BUFFER.
Browse files Browse the repository at this point in the history
`READ_BUFFER` was originally added for `read`, but `read` no longer
needs it now that we can use `rustix::io::read_uninit`. So the only
thing left using `READ_BUFFER` is the xattr functions. It wasn't really
correct for the xattr functions to use a `PIPE_BUF`-sized buffer anyway,
so remove `READ_BUFFER` entirely and just use `Vec`s for their buffers.

This also fixes compile errors with u8/i8 mismatches when `linux-raw-sys/std`
is enabled.

Fixes #132.
  • Loading branch information
sunfishcode committed May 17, 2024
1 parent de6d8e8 commit f140440
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 41 deletions.
57 changes: 21 additions & 36 deletions c-scape/src/fs/xattr.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Extended attributes.

use crate::{convert_res, READ_BUFFER};
use core::cmp::min;
use crate::convert_res;
use alloc::vec;
use core::ffi::CStr;
use core::ptr::{addr_of_mut, copy_nonoverlapping};
use core::ptr::copy_nonoverlapping;
use core::slice;
use libc::{c_char, c_int, c_void, size_t, ssize_t};
use rustix::fd::BorrowedFd;
Expand All @@ -23,15 +23,12 @@ unsafe extern "C" fn getxattr(
// `slice::from_raw_parts_mut` assumes that the memory is initialized,
// which our C API here doesn't guarantee. Since rustix currently requires
// a slice, use a temporary copy.
match convert_res(rustix::fs::getxattr(
path,
name,
&mut *addr_of_mut!(READ_BUFFER[..min(len, READ_BUFFER.len())]),
)) {
let mut buf = vec![0; len];
match convert_res(rustix::fs::getxattr(path, name, &mut buf)) {
Some(size) => {
// If `size` is 0, `value` could be null.
if size != 0 {
copy_nonoverlapping(READ_BUFFER.as_ptr(), value.cast(), size);
copy_nonoverlapping(buf.as_ptr(), value.cast(), size);
}
size as ssize_t
}
Expand All @@ -53,15 +50,12 @@ unsafe extern "C" fn lgetxattr(
// `slice::from_raw_parts_mut` assumes that the memory is initialized,
// which our C API here doesn't guarantee. Since rustix currently requires
// a slice, use a temporary copy.
match convert_res(rustix::fs::lgetxattr(
path,
name,
&mut *addr_of_mut!(READ_BUFFER[..min(len, READ_BUFFER.len())]),
)) {
let mut buf = vec![0; len];
match convert_res(rustix::fs::lgetxattr(path, name, &mut buf)) {
Some(size) => {
// If `size` is 0, `value` could be null.
if size != 0 {
copy_nonoverlapping(READ_BUFFER.as_ptr(), value.cast(), size);
copy_nonoverlapping(buf.as_ptr(), value.cast(), size);
}
size as ssize_t
}
Expand All @@ -83,15 +77,12 @@ unsafe extern "C" fn fgetxattr(
// `slice::from_raw_parts_mut` assumes that the memory is initialized,
// which our C API here doesn't guarantee. Since rustix currently requires
// a slice, use a temporary copy.
match convert_res(rustix::fs::fgetxattr(
fd,
name,
&mut *addr_of_mut!(READ_BUFFER[..min(len, READ_BUFFER.len())]),
)) {
let mut buf = vec![0; len];
match convert_res(rustix::fs::fgetxattr(fd, name, &mut buf)) {
Some(size) => {
// If `size` is 0, `value` could be null.
if size != 0 {
copy_nonoverlapping(READ_BUFFER.as_ptr(), value.cast(), size);
copy_nonoverlapping(buf.as_ptr(), value.cast(), size);
}
size as ssize_t
}
Expand Down Expand Up @@ -167,14 +158,12 @@ unsafe extern "C" fn listxattr(path: *const c_char, list: *mut c_char, len: size
// `slice::from_raw_parts_mut` assumes that the memory is initialized,
// which our C API here doesn't guarantee. Since rustix currently requires
// a slice, use a temporary copy.
match convert_res(rustix::fs::listxattr(
path,
&mut *addr_of_mut!(READ_BUFFER[..min(len, READ_BUFFER.len())]),
)) {
let mut buf = vec![0; len];
match convert_res(rustix::fs::listxattr(path, &mut buf)) {
Some(size) => {
// If `size` is 0, `value` could be null.
if size != 0 {
copy_nonoverlapping(READ_BUFFER.as_ptr(), list.cast(), size);
copy_nonoverlapping(buf.as_ptr(), list.cast(), size);
}
size as ssize_t
}
Expand All @@ -190,14 +179,12 @@ unsafe extern "C" fn llistxattr(path: *const c_char, list: *mut c_char, len: siz
// `slice::from_raw_parts_mut` assumes that the memory is initialized,
// which our C API here doesn't guarantee. Since rustix currently requires
// a slice, use a temporary copy.
match convert_res(rustix::fs::llistxattr(
path,
&mut *addr_of_mut!(READ_BUFFER[..min(len, READ_BUFFER.len())]),
)) {
let mut buf = vec![0; len];
match convert_res(rustix::fs::llistxattr(path, &mut buf)) {
Some(size) => {
// If `size` is 0, `value` could be null.
if size != 0 {
copy_nonoverlapping(READ_BUFFER.as_ptr(), list.cast(), size);
copy_nonoverlapping(buf.as_ptr(), list.cast(), size);
}
size as ssize_t
}
Expand All @@ -213,14 +200,12 @@ unsafe extern "C" fn flistxattr(fd: c_int, list: *mut c_char, len: size_t) -> ss
// `slice::from_raw_parts_mut` assumes that the memory is initialized,
// which our C API here doesn't guarantee. Since rustix currently requires
// a slice, use a temporary copy.
match convert_res(rustix::fs::flistxattr(
fd,
&mut *addr_of_mut!(READ_BUFFER[..min(len, READ_BUFFER.len())]),
)) {
let mut buf = vec![0; len];
match convert_res(rustix::fs::flistxattr(fd, &mut buf)) {
Some(size) => {
// If `size` is 0, `value` could be null.
if size != 0 {
copy_nonoverlapping(READ_BUFFER.as_ptr(), list.cast(), size);
copy_nonoverlapping(buf.as_ptr(), list.cast(), size);
}
size as ssize_t
}
Expand Down
5 changes: 0 additions & 5 deletions c-scape/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,6 @@ fn convert_res<T>(result: Result<T, rustix::io::Errno>) -> Option<T> {
.ok()
}

/// A thread-local buffer for reading into, when the user-supplied buffer
/// may not be initialized.
#[thread_local]
static mut READ_BUFFER: [u8; libc::PIPE_BUF] = [0_u8; libc::PIPE_BUF];

/// A type that implements `lock_api::GetThreadId` for use with
/// `lock_api::RawReentrantMutex`.
#[cfg(feature = "thread")]
Expand Down

0 comments on commit f140440

Please sign in to comment.