1use crate::{backend, io, path};
2use backend::c;
3use backend::fd::AsFd;
4use bitflags::bitflags;
5
6bitflags! {
7 /// `XATTR_*` constants for use with [`setxattr`], and other `*setxattr`
8 /// functions.
9 pub struct XattrFlags: c::c_uint {
10 /// `XATTR_CREATE`
11 const CREATE = c::XATTR_CREATE as c::c_uint;
12
13 /// `XATTR_REPLACE`
14 const REPLACE = c::XATTR_REPLACE as c::c_uint;
15 }
16}
17
18/// `getxattr(path, name, value.as_ptr(), value.len())`—Get extended
19/// filesystem attributes.
20///
21/// # References
22/// - [Linux]
23///
24/// [Linux]: https://man7.org/linux/man-pages/man2/getxattr.2.html
25#[inline]
26pub fn getxattr<P: path::Arg, Name: path::Arg>(
27 path: P,
28 name: Name,
29 value: &mut [u8],
30) -> io::Result<usize> {
31 path.into_with_c_str(|path: &CStr| {
32 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::getxattr(path, name, value))
33 })
34}
35
36/// `lgetxattr(path, name, value.as_ptr(), value.len())`—Get extended
37/// filesystem attributes, without following symlinks in the last path
38/// component.
39///
40/// # References
41/// - [Linux]
42///
43/// [Linux]: https://man7.org/linux/man-pages/man2/lgetxattr.2.html
44#[inline]
45pub fn lgetxattr<P: path::Arg, Name: path::Arg>(
46 path: P,
47 name: Name,
48 value: &mut [u8],
49) -> io::Result<usize> {
50 path.into_with_c_str(|path: &CStr| {
51 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::lgetxattr(path, name, value))
52 })
53}
54
55/// `fgetxattr(fd, name, value.as_ptr(), value.len())`—Get extended
56/// filesystem attributes on an open file descriptor.
57///
58/// # References
59/// - [Linux]
60///
61/// [Linux]: https://man7.org/linux/man-pages/man2/fgetxattr.2.html
62#[inline]
63pub fn fgetxattr<Fd: AsFd, Name: path::Arg>(
64 fd: Fd,
65 name: Name,
66 value: &mut [u8],
67) -> io::Result<usize> {
68 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::fgetxattr(fd.as_fd(), name, value))
69}
70
71/// `setxattr(path, name, value.as_ptr(), value.len(), flags)`—Set extended
72/// filesystem attributes.
73///
74/// # References
75/// - [Linux]
76///
77/// [Linux]: https://man7.org/linux/man-pages/man2/setxattr.2.html
78#[inline]
79pub fn setxattr<P: path::Arg, Name: path::Arg>(
80 path: P,
81 name: Name,
82 value: &[u8],
83 flags: XattrFlags,
84) -> io::Result<()> {
85 path.into_with_c_str(|path: &CStr| {
86 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::setxattr(path, name, value, flags))
87 })
88}
89
90/// `setxattr(path, name, value.as_ptr(), value.len(), flags)`—Set extended
91/// filesystem attributes, without following symlinks in the last path
92/// component.
93///
94/// # References
95/// - [Linux]
96///
97/// [Linux]: https://man7.org/linux/man-pages/man2/lsetxattr.2.html
98#[inline]
99pub fn lsetxattr<P: path::Arg, Name: path::Arg>(
100 path: P,
101 name: Name,
102 value: &[u8],
103 flags: XattrFlags,
104) -> io::Result<()> {
105 path.into_with_c_str(|path: &CStr| {
106 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::lsetxattr(path, name, value, flags))
107 })
108}
109
110/// `fsetxattr(fd, name, value.as_ptr(), value.len(), flags)`—Set extended
111/// filesystem attributes on an open file descriptor.
112///
113/// # References
114/// - [Linux]
115///
116/// [Linux]: https://man7.org/linux/man-pages/man2/fsetxattr.2.html
117#[inline]
118pub fn fsetxattr<Fd: AsFd, Name: path::Arg>(
119 fd: Fd,
120 name: Name,
121 value: &[u8],
122 flags: XattrFlags,
123) -> io::Result<()> {
124 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::fsetxattr(fd.as_fd(), name, value, flags))
125}
126
127/// `listxattr(path, list.as_ptr(), list.len())`—List extended filesystem
128/// attributes.
129///
130/// # References
131/// - [Linux]
132///
133/// [Linux]: https://man7.org/linux/man-pages/man2/listxattr.2.html
134#[inline]
135pub fn listxattr<P: path::Arg>(path: P, list: &mut [c::c_char]) -> io::Result<usize> {
136 path.into_with_c_str(|path: &CStr| backend::fs::syscalls::listxattr(path, list))
137}
138
139/// `llistxattr(path, list.as_ptr(), list.len())`—List extended filesystem
140/// attributes, without following symlinks in the last path component.
141///
142/// # References
143/// - [Linux]
144///
145/// [Linux]: https://man7.org/linux/man-pages/man2/llistxattr.2.html
146#[inline]
147pub fn llistxattr<P: path::Arg>(path: P, list: &mut [c::c_char]) -> io::Result<usize> {
148 path.into_with_c_str(|path: &CStr| backend::fs::syscalls::llistxattr(path, list))
149}
150
151/// `flistxattr(fd, list.as_ptr(), list.len())`—List extended filesystem
152/// attributes on an open file descriptor.
153///
154/// # References
155/// - [Linux]
156///
157/// [Linux]: https://man7.org/linux/man-pages/man2/flistxattr.2.html
158#[inline]
159pub fn flistxattr<Fd: AsFd>(fd: Fd, list: &mut [c::c_char]) -> io::Result<usize> {
160 backend::fs::syscalls::flistxattr(fd.as_fd(), list)
161}
162
163/// `removexattr(path, name)`—Remove an extended filesystem attribute.
164///
165/// # References
166/// - [Linux]
167///
168/// [Linux]: https://man7.org/linux/man-pages/man2/removexattr.2.html
169pub fn removexattr<P: path::Arg, Name: path::Arg>(path: P, name: Name) -> io::Result<()> {
170 path.into_with_c_str(|path: &CStr| {
171 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::removexattr(path, name))
172 })
173}
174
175/// `lremovexattr(path, name)`—Remove an extended filesystem attribute,
176/// without following symlinks in the last path component.
177///
178/// # References
179/// - [Linux]
180///
181/// [Linux]: https://man7.org/linux/man-pages/man2/lremovexattr.2.html
182pub fn lremovexattr<P: path::Arg, Name: path::Arg>(path: P, name: Name) -> io::Result<()> {
183 path.into_with_c_str(|path: &CStr| {
184 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::lremovexattr(path, name))
185 })
186}
187
188/// `fremovexattr(fd, name)`—Remove an extended filesystem attribute on an
189/// open file descriptor.
190///
191/// # References
192/// - [Linux]
193///
194/// [Linux]: https://man7.org/linux/man-pages/man2/fremovexattr.2.html
195pub fn fremovexattr<Fd: AsFd, Name: path::Arg>(fd: Fd, name: Name) -> io::Result<()> {
196 name.into_with_c_str(|name: &CStr| backend::fs::syscalls::fremovexattr(fd.as_fd(), name))
197}
198