1 | use crate::{backend, io, path}; |
2 | use backend::c; |
3 | use backend::fd::AsFd; |
4 | use bitflags::bitflags; |
5 | |
6 | bitflags! { |
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/*/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 ] |
31 | pub 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 ] |
50 | pub 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 ] |
68 | pub 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 ] |
84 | pub 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 ] |
104 | pub 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 ] |
123 | pub 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 ] |
140 | pub 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 ] |
152 | pub 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 ] |
164 | pub 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 |
174 | pub 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 |
187 | pub 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 |
200 | pub 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 | |