| 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 | |