Coverage Report

Created: 2026-09-01 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/xattr-1.6.1/src/util.rs
Line
Count
Source
1
use std::io;
2
use std::mem::MaybeUninit;
3
4
0
pub fn extract_noattr(result: io::Result<Vec<u8>>) -> io::Result<Option<Vec<u8>>> {
5
0
    result.map(Some).or_else(|e| {
6
0
        if e.raw_os_error() == Some(crate::sys::ENOATTR) {
7
0
            Ok(None)
8
        } else {
9
0
            Err(e)
10
        }
11
0
    })
12
0
}
13
14
/// Calls `get_value` to with a buffer and `get_size` to estimate the size of the buffer if/when
15
/// `get_value` returns ERANGE.
16
#[allow(dead_code)]
17
0
pub fn allocate_loop<F, S>(mut get_value: F, mut get_size: S) -> io::Result<Vec<u8>>
18
0
where
19
0
    F: for<'a> FnMut(&'a mut [MaybeUninit<u8>]) -> io::Result<&'a mut [u8]>,
20
0
    S: FnMut() -> io::Result<usize>,
21
{
22
    // Start by assuming the return value is <= 4KiB. If it is, we can do this in one syscall.
23
    const INITIAL_BUFFER_SIZE: usize = 4096;
24
0
    match get_value(&mut [MaybeUninit::<u8>::uninit(); INITIAL_BUFFER_SIZE]) {
25
0
        Ok(val) => return Ok(val.to_vec()),
26
0
        Err(e) if e.raw_os_error() != Some(crate::sys::ERANGE) => return Err(e),
27
0
        _ => {}
28
    }
29
30
    // If that fails, we ask for the size and try again with a buffer of the correct size.
31
0
    let mut vec: Vec<u8> = Vec::new();
32
    loop {
33
0
        vec.reserve_exact(get_size()?);
34
0
        match get_value(vec.spare_capacity_mut()) {
35
0
            Ok(initialized) => {
36
                unsafe {
37
0
                    let len = initialized.len();
38
0
                    assert_eq!(
39
0
                        initialized.as_ptr(),
40
0
                        vec.as_ptr(),
41
0
                        "expected the same buffer"
42
                    );
43
0
                    vec.set_len(len);
44
                }
45
                // Only shrink to fit if we've over-allocated by MORE than one byte. Unfortunately,
46
                // on FreeBSD, we have to over-allocate by one byte to determine if we've read all
47
                // the attributes.
48
0
                if vec.capacity() > vec.len() + 1 {
49
0
                    vec.shrink_to_fit();
50
0
                }
51
0
                return Ok(vec);
52
            }
53
0
            Err(e) if e.raw_os_error() != Some(crate::sys::ERANGE) => return Err(e),
54
0
            _ => {} // try again
55
        }
56
    }
57
0
}
Unexecuted instantiation: xattr::util::allocate_loop::<xattr::sys::linux_macos::get_fd::{closure#0}, xattr::sys::linux_macos::get_fd::{closure#1}>
Unexecuted instantiation: xattr::util::allocate_loop::<xattr::sys::linux_macos::list_fd::{closure#0}, xattr::sys::linux_macos::list_fd::{closure#1}>
Unexecuted instantiation: xattr::util::allocate_loop::<xattr::sys::linux_macos::get_path::{closure#0}, xattr::sys::linux_macos::get_path::{closure#1}>
Unexecuted instantiation: xattr::util::allocate_loop::<xattr::sys::linux_macos::get_path::{closure#2}, xattr::sys::linux_macos::get_path::{closure#3}>
Unexecuted instantiation: xattr::util::allocate_loop::<xattr::sys::linux_macos::list_path::{closure#0}, xattr::sys::linux_macos::list_path::{closure#1}>
Unexecuted instantiation: xattr::util::allocate_loop::<xattr::sys::linux_macos::list_path::{closure#2}, xattr::sys::linux_macos::list_path::{closure#3}>