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