c-scape 0.22.3

A libc bottom-half implementation in Rust
Documentation
//! Extended attributes.

use crate::convert_res;
use core::ffi::CStr;
use core::mem::MaybeUninit;
use core::slice;
use libc::{c_char, c_int, c_void, size_t, ssize_t};
use rustix::fd::BorrowedFd;
use rustix::fs::XattrFlags;

#[no_mangle]
unsafe extern "C" fn getxattr(
    path: *const c_char,
    name: *const c_char,
    value: *mut c_void,
    len: size_t,
) -> ssize_t {
    libc!(libc::getxattr(path, name, value, len));

    let path = CStr::from_ptr(path);
    let name = CStr::from_ptr(name);
    let buf = slice::from_raw_parts_mut(value.cast::<MaybeUninit<u8>>(), len);

    match convert_res(rustix::fs::getxattr(path, name, buf)) {
        Some((init, _uninit)) => init.len() as ssize_t,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn lgetxattr(
    path: *const c_char,
    name: *const c_char,
    value: *mut c_void,
    len: size_t,
) -> ssize_t {
    libc!(libc::lgetxattr(path, name, value, len));

    let path = CStr::from_ptr(path);
    let name = CStr::from_ptr(name);
    let buf = slice::from_raw_parts_mut(value.cast::<MaybeUninit<u8>>(), len);

    match convert_res(rustix::fs::lgetxattr(path, name, buf)) {
        Some((init, _uninit)) => init.len() as ssize_t,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn fgetxattr(
    fd: c_int,
    name: *const c_char,
    value: *mut c_void,
    len: size_t,
) -> ssize_t {
    libc!(libc::fgetxattr(fd, name, value, len));

    let fd = BorrowedFd::borrow_raw(fd);
    let name = CStr::from_ptr(name);
    let buf = slice::from_raw_parts_mut(value.cast::<MaybeUninit<u8>>(), len);

    match convert_res(rustix::fs::fgetxattr(fd, name, buf)) {
        Some((init, _uninit)) => init.len() as ssize_t,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn setxattr(
    path: *const c_char,
    name: *const c_char,
    value: *const c_void,
    len: size_t,
    flags: c_int,
) -> c_int {
    libc!(libc::setxattr(path, name, value, len, flags));

    let path = CStr::from_ptr(path);
    let name = CStr::from_ptr(name);
    let value = slice::from_raw_parts(value.cast(), len);
    let flags = XattrFlags::from_bits(flags as _).unwrap();
    match convert_res(rustix::fs::setxattr(path, name, value, flags)) {
        Some(()) => 0,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn lsetxattr(
    path: *const c_char,
    name: *const c_char,
    value: *const c_void,
    len: size_t,
    flags: c_int,
) -> c_int {
    libc!(libc::lsetxattr(path, name, value, len, flags));

    let path = CStr::from_ptr(path);
    let name = CStr::from_ptr(name);
    let value = slice::from_raw_parts(value.cast(), len);
    let flags = XattrFlags::from_bits(flags as _).unwrap();
    match convert_res(rustix::fs::lsetxattr(path, name, value, flags)) {
        Some(()) => 0,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn fsetxattr(
    fd: c_int,
    name: *const c_char,
    value: *const c_void,
    len: size_t,
    flags: c_int,
) -> c_int {
    libc!(libc::fsetxattr(fd, name, value, len, flags));

    let fd = BorrowedFd::borrow_raw(fd);
    let name = CStr::from_ptr(name);
    let value = slice::from_raw_parts(value.cast(), len);
    let flags = XattrFlags::from_bits(flags as _).unwrap();
    match convert_res(rustix::fs::fsetxattr(fd, name, value, flags)) {
        Some(()) => 0,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn listxattr(path: *const c_char, list: *mut c_char, len: size_t) -> ssize_t {
    libc!(libc::listxattr(path, list, len));

    let path = CStr::from_ptr(path);
    let buf = slice::from_raw_parts_mut(list.cast::<MaybeUninit<u8>>(), len);

    match convert_res(rustix::fs::listxattr(path, buf)) {
        Some((init, _uninit)) => init.len() as ssize_t,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn llistxattr(path: *const c_char, list: *mut c_char, len: size_t) -> ssize_t {
    libc!(libc::llistxattr(path, list, len));

    let path = CStr::from_ptr(path);
    let buf = slice::from_raw_parts_mut(list.cast::<MaybeUninit<u8>>(), len);

    match convert_res(rustix::fs::llistxattr(path, buf)) {
        Some((init, _uninit)) => init.len() as ssize_t,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn flistxattr(fd: c_int, list: *mut c_char, len: size_t) -> ssize_t {
    libc!(libc::flistxattr(fd, list, len));

    let fd = BorrowedFd::borrow_raw(fd);
    let buf = slice::from_raw_parts_mut(list.cast::<MaybeUninit<u8>>(), len);

    match convert_res(rustix::fs::flistxattr(fd, buf)) {
        Some((init, _uninit)) => init.len() as ssize_t,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn removexattr(path: *const c_char, name: *const c_char) -> c_int {
    libc!(libc::removexattr(path, name));

    let path = CStr::from_ptr(path);
    let name = CStr::from_ptr(name);
    match convert_res(rustix::fs::removexattr(path, name)) {
        Some(()) => 0,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn lremovexattr(path: *const c_char, name: *const c_char) -> c_int {
    libc!(libc::lremovexattr(path, name));

    let path = CStr::from_ptr(path);
    let name = CStr::from_ptr(name);
    match convert_res(rustix::fs::lremovexattr(path, name)) {
        Some(()) => 0,
        None => -1,
    }
}

#[no_mangle]
unsafe extern "C" fn fremovexattr(fd: c_int, name: *const c_char) -> c_int {
    libc!(libc::fremovexattr(fd, name));

    let fd = BorrowedFd::borrow_raw(fd);
    let name = CStr::from_ptr(name);
    match convert_res(rustix::fs::fremovexattr(fd, name)) {
        Some(()) => 0,
        None => -1,
    }
}