Skip to main content

c_scape/fs/
xattr.rs

1//! Extended attributes.
2
3use crate::convert_res;
4use core::ffi::CStr;
5use core::mem::MaybeUninit;
6use core::slice;
7use libc::{c_char, c_int, c_void, size_t, ssize_t};
8use rustix::fd::BorrowedFd;
9use rustix::fs::XattrFlags;
10
11#[no_mangle]
12unsafe extern "C" fn getxattr(
13    path: *const c_char,
14    name: *const c_char,
15    value: *mut c_void,
16    len: size_t,
17) -> ssize_t {
18    libc!(libc::getxattr(path, name, value, len));
19
20    let path = CStr::from_ptr(path);
21    let name = CStr::from_ptr(name);
22    let buf = slice::from_raw_parts_mut(value.cast::<MaybeUninit<u8>>(), len);
23
24    match convert_res(rustix::fs::getxattr(path, name, buf)) {
25        Some((init, _uninit)) => init.len() as ssize_t,
26        None => -1,
27    }
28}
29
30#[no_mangle]
31unsafe extern "C" fn lgetxattr(
32    path: *const c_char,
33    name: *const c_char,
34    value: *mut c_void,
35    len: size_t,
36) -> ssize_t {
37    libc!(libc::lgetxattr(path, name, value, len));
38
39    let path = CStr::from_ptr(path);
40    let name = CStr::from_ptr(name);
41    let buf = slice::from_raw_parts_mut(value.cast::<MaybeUninit<u8>>(), len);
42
43    match convert_res(rustix::fs::lgetxattr(path, name, buf)) {
44        Some((init, _uninit)) => init.len() as ssize_t,
45        None => -1,
46    }
47}
48
49#[no_mangle]
50unsafe extern "C" fn fgetxattr(
51    fd: c_int,
52    name: *const c_char,
53    value: *mut c_void,
54    len: size_t,
55) -> ssize_t {
56    libc!(libc::fgetxattr(fd, name, value, len));
57
58    let fd = BorrowedFd::borrow_raw(fd);
59    let name = CStr::from_ptr(name);
60    let buf = slice::from_raw_parts_mut(value.cast::<MaybeUninit<u8>>(), len);
61
62    match convert_res(rustix::fs::fgetxattr(fd, name, buf)) {
63        Some((init, _uninit)) => init.len() as ssize_t,
64        None => -1,
65    }
66}
67
68#[no_mangle]
69unsafe extern "C" fn setxattr(
70    path: *const c_char,
71    name: *const c_char,
72    value: *const c_void,
73    len: size_t,
74    flags: c_int,
75) -> c_int {
76    libc!(libc::setxattr(path, name, value, len, flags));
77
78    let path = CStr::from_ptr(path);
79    let name = CStr::from_ptr(name);
80    let value = slice::from_raw_parts(value.cast(), len);
81    let flags = XattrFlags::from_bits(flags as _).unwrap();
82    match convert_res(rustix::fs::setxattr(path, name, value, flags)) {
83        Some(()) => 0,
84        None => -1,
85    }
86}
87
88#[no_mangle]
89unsafe extern "C" fn lsetxattr(
90    path: *const c_char,
91    name: *const c_char,
92    value: *const c_void,
93    len: size_t,
94    flags: c_int,
95) -> c_int {
96    libc!(libc::lsetxattr(path, name, value, len, flags));
97
98    let path = CStr::from_ptr(path);
99    let name = CStr::from_ptr(name);
100    let value = slice::from_raw_parts(value.cast(), len);
101    let flags = XattrFlags::from_bits(flags as _).unwrap();
102    match convert_res(rustix::fs::lsetxattr(path, name, value, flags)) {
103        Some(()) => 0,
104        None => -1,
105    }
106}
107
108#[no_mangle]
109unsafe extern "C" fn fsetxattr(
110    fd: c_int,
111    name: *const c_char,
112    value: *const c_void,
113    len: size_t,
114    flags: c_int,
115) -> c_int {
116    libc!(libc::fsetxattr(fd, name, value, len, flags));
117
118    let fd = BorrowedFd::borrow_raw(fd);
119    let name = CStr::from_ptr(name);
120    let value = slice::from_raw_parts(value.cast(), len);
121    let flags = XattrFlags::from_bits(flags as _).unwrap();
122    match convert_res(rustix::fs::fsetxattr(fd, name, value, flags)) {
123        Some(()) => 0,
124        None => -1,
125    }
126}
127
128#[no_mangle]
129unsafe extern "C" fn listxattr(path: *const c_char, list: *mut c_char, len: size_t) -> ssize_t {
130    libc!(libc::listxattr(path, list, len));
131
132    let path = CStr::from_ptr(path);
133    let buf = slice::from_raw_parts_mut(list.cast::<MaybeUninit<u8>>(), len);
134
135    match convert_res(rustix::fs::listxattr(path, buf)) {
136        Some((init, _uninit)) => init.len() as ssize_t,
137        None => -1,
138    }
139}
140
141#[no_mangle]
142unsafe extern "C" fn llistxattr(path: *const c_char, list: *mut c_char, len: size_t) -> ssize_t {
143    libc!(libc::llistxattr(path, list, len));
144
145    let path = CStr::from_ptr(path);
146    let buf = slice::from_raw_parts_mut(list.cast::<MaybeUninit<u8>>(), len);
147
148    match convert_res(rustix::fs::llistxattr(path, buf)) {
149        Some((init, _uninit)) => init.len() as ssize_t,
150        None => -1,
151    }
152}
153
154#[no_mangle]
155unsafe extern "C" fn flistxattr(fd: c_int, list: *mut c_char, len: size_t) -> ssize_t {
156    libc!(libc::flistxattr(fd, list, len));
157
158    let fd = BorrowedFd::borrow_raw(fd);
159    let buf = slice::from_raw_parts_mut(list.cast::<MaybeUninit<u8>>(), len);
160
161    match convert_res(rustix::fs::flistxattr(fd, buf)) {
162        Some((init, _uninit)) => init.len() as ssize_t,
163        None => -1,
164    }
165}
166
167#[no_mangle]
168unsafe extern "C" fn removexattr(path: *const c_char, name: *const c_char) -> c_int {
169    libc!(libc::removexattr(path, name));
170
171    let path = CStr::from_ptr(path);
172    let name = CStr::from_ptr(name);
173    match convert_res(rustix::fs::removexattr(path, name)) {
174        Some(()) => 0,
175        None => -1,
176    }
177}
178
179#[no_mangle]
180unsafe extern "C" fn lremovexattr(path: *const c_char, name: *const c_char) -> c_int {
181    libc!(libc::lremovexattr(path, name));
182
183    let path = CStr::from_ptr(path);
184    let name = CStr::from_ptr(name);
185    match convert_res(rustix::fs::lremovexattr(path, name)) {
186        Some(()) => 0,
187        None => -1,
188    }
189}
190
191#[no_mangle]
192unsafe extern "C" fn fremovexattr(fd: c_int, name: *const c_char) -> c_int {
193    libc!(libc::fremovexattr(fd, name));
194
195    let fd = BorrowedFd::borrow_raw(fd);
196    let name = CStr::from_ptr(name);
197    match convert_res(rustix::fs::fremovexattr(fd, name)) {
198        Some(()) => 0,
199        None => -1,
200    }
201}