]> git.proxmox.com Git - rustc.git/blob - src/vendor/nix/src/fcntl.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / nix / src / fcntl.rs
1 use {Errno, Result, NixPath};
2 use libc::{self, c_int, c_uint};
3 use sys::stat::Mode;
4 use std::os::unix::io::RawFd;
5
6 #[cfg(any(target_os = "linux", target_os = "android"))]
7 use sys::uio::IoVec; // For vmsplice
8
9 pub use self::consts::*;
10
11 // TODO: The remainder of the ffi module should be removed afer work on
12 // https://github.com/rust-lang/libc/issues/235 is resolved.
13 #[allow(dead_code)]
14 mod ffi {
15 use libc::c_int;
16
17 pub const F_ADD_SEALS: c_int = 1033;
18 pub const F_GET_SEALS: c_int = 1034;
19 }
20
21 pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
22 let fd = try!(path.with_nix_path(|cstr| {
23 unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
24 }));
25
26 Errno::result(fd)
27 }
28
29 pub enum FcntlArg<'a> {
30 F_DUPFD(RawFd),
31 F_DUPFD_CLOEXEC(RawFd),
32 F_GETFD,
33 F_SETFD(FdFlag), // FD_FLAGS
34 F_GETFL,
35 F_SETFL(OFlag), // O_NONBLOCK
36 F_SETLK(&'a libc::flock),
37 F_SETLKW(&'a libc::flock),
38 F_GETLK(&'a mut libc::flock),
39 #[cfg(any(target_os = "linux", target_os = "android"))]
40 F_OFD_SETLK(&'a libc::flock),
41 #[cfg(any(target_os = "linux", target_os = "android"))]
42 F_OFD_SETLKW(&'a libc::flock),
43 #[cfg(any(target_os = "linux", target_os = "android"))]
44 F_OFD_GETLK(&'a mut libc::flock),
45 #[cfg(target_os = "linux")]
46 F_ADD_SEALS(SealFlag),
47 #[cfg(target_os = "linux")]
48 F_GET_SEALS,
49 #[cfg(any(target_os = "macos", target_os = "ios"))]
50 F_FULLFSYNC,
51 #[cfg(any(target_os = "linux", target_os = "android"))]
52 F_GETPIPE_SZ,
53 #[cfg(any(target_os = "linux", target_os = "android"))]
54 F_SETPIPE_SZ(libc::c_int),
55
56 // TODO: Rest of flags
57 }
58 pub use self::FcntlArg::*;
59
60 // TODO: Figure out how to handle value fcntl returns
61 pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
62 let res = unsafe {
63 match arg {
64 F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd),
65 F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd),
66 F_GETFD => libc::fcntl(fd, libc::F_GETFD),
67 F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
68 F_GETFL => libc::fcntl(fd, libc::F_GETFL),
69 F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()),
70 F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
71 F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
72 F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
73 #[cfg(target_os = "linux")]
74 F_ADD_SEALS(flag) => libc::fcntl(fd, ffi::F_ADD_SEALS, flag.bits()),
75 #[cfg(target_os = "linux")]
76 F_GET_SEALS => libc::fcntl(fd, ffi::F_GET_SEALS),
77 #[cfg(any(target_os = "macos", target_os = "ios"))]
78 F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
79 #[cfg(any(target_os = "linux", target_os = "android"))]
80 F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
81 #[cfg(any(target_os = "linux", target_os = "android"))]
82 F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
83 #[cfg(any(target_os = "linux", target_os = "android"))]
84 _ => unimplemented!()
85 }
86 };
87
88 Errno::result(res)
89 }
90
91 pub enum FlockArg {
92 LockShared,
93 LockExclusive,
94 Unlock,
95 LockSharedNonblock,
96 LockExclusiveNonblock,
97 UnlockNonblock,
98 }
99
100 pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
101 use self::FlockArg::*;
102
103 let res = unsafe {
104 match arg {
105 LockShared => libc::flock(fd, libc::LOCK_SH),
106 LockExclusive => libc::flock(fd, libc::LOCK_EX),
107 Unlock => libc::flock(fd, libc::LOCK_UN),
108 LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB),
109 LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB),
110 UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
111 }
112 };
113
114 Errno::result(res).map(drop)
115 }
116
117 #[cfg(any(target_os = "linux", target_os = "android"))]
118 pub fn splice(fd_in: RawFd, off_in: Option<&mut libc::loff_t>,
119 fd_out: RawFd, off_out: Option<&mut libc::loff_t>,
120 len: usize, flags: SpliceFFlags) -> Result<usize> {
121 use std::ptr;
122 let off_in = off_in.map(|offset| offset as *mut _).unwrap_or(ptr::null_mut());
123 let off_out = off_out.map(|offset| offset as *mut _).unwrap_or(ptr::null_mut());
124
125 let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) };
126 Errno::result(ret).map(|r| r as usize)
127 }
128
129 #[cfg(any(target_os = "linux", target_os = "android"))]
130 pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> {
131 let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
132 Errno::result(ret).map(|r| r as usize)
133 }
134
135 #[cfg(any(target_os = "linux", target_os = "android"))]
136 pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<usize> {
137 let ret = unsafe {
138 libc::vmsplice(fd, iov.as_ptr() as *const libc::iovec, iov.len(), flags.bits())
139 };
140 Errno::result(ret).map(|r| r as usize)
141 }
142
143 #[cfg(any(target_os = "linux", target_os = "android"))]
144 mod consts {
145 use libc::{self, c_int, c_uint};
146
147 libc_bitflags! {
148 pub flags SpliceFFlags: c_uint {
149 SPLICE_F_MOVE,
150 SPLICE_F_NONBLOCK,
151 SPLICE_F_MORE,
152 SPLICE_F_GIFT,
153 }
154 }
155
156 bitflags!(
157 pub flags OFlag: c_int {
158 const O_ACCMODE = libc::O_ACCMODE,
159 const O_RDONLY = libc::O_RDONLY,
160 const O_WRONLY = libc::O_WRONLY,
161 const O_RDWR = libc::O_RDWR,
162 const O_CREAT = libc::O_CREAT,
163 const O_EXCL = libc::O_EXCL,
164 const O_NOCTTY = libc::O_NOCTTY,
165 const O_TRUNC = libc::O_TRUNC,
166 const O_APPEND = libc::O_APPEND,
167 const O_NONBLOCK = libc::O_NONBLOCK,
168 const O_DSYNC = libc::O_DSYNC,
169 const O_DIRECT = libc::O_DIRECT,
170 const O_LARGEFILE = 0o00100000,
171 const O_DIRECTORY = libc::O_DIRECTORY,
172 const O_NOFOLLOW = libc::O_NOFOLLOW,
173 const O_NOATIME = 0o01000000,
174 const O_CLOEXEC = libc::O_CLOEXEC,
175 const O_SYNC = libc::O_SYNC,
176 const O_PATH = 0o10000000,
177 const O_TMPFILE = libc::O_TMPFILE,
178 const O_NDELAY = libc::O_NDELAY,
179 }
180 );
181
182 bitflags!(
183 pub flags FdFlag: c_int {
184 const FD_CLOEXEC = 1
185 }
186 );
187
188 bitflags!(
189 pub flags SealFlag: c_int {
190 const F_SEAL_SEAL = 1,
191 const F_SEAL_SHRINK = 2,
192 const F_SEAL_GROW = 4,
193 const F_SEAL_WRITE = 8,
194 }
195 );
196
197 }
198
199 #[cfg(any(target_os = "macos", target_os = "ios"))]
200 mod consts {
201 use libc::{self, c_int};
202
203 bitflags!(
204 pub flags OFlag: c_int {
205 const O_ACCMODE = libc::O_ACCMODE,
206 const O_RDONLY = libc::O_RDONLY,
207 const O_WRONLY = libc::O_WRONLY,
208 const O_RDWR = libc::O_RDWR,
209 const O_CREAT = libc::O_CREAT,
210 const O_EXCL = libc::O_EXCL,
211 const O_NOCTTY = libc::O_NOCTTY,
212 const O_TRUNC = libc::O_TRUNC,
213 const O_APPEND = libc::O_APPEND,
214 const O_NONBLOCK = libc::O_NONBLOCK,
215 const O_DSYNC = libc::O_DSYNC,
216 const O_DIRECTORY = libc::O_DIRECTORY,
217 const O_NOFOLLOW = libc::O_NOFOLLOW,
218 const O_CLOEXEC = libc::O_CLOEXEC,
219 const O_SYNC = libc::O_SYNC,
220 const O_NDELAY = O_NONBLOCK.bits,
221 const O_FSYNC = libc::O_FSYNC,
222 }
223 );
224
225 bitflags!(
226 pub flags FdFlag: c_int {
227 const FD_CLOEXEC = 1
228 }
229 );
230 }
231
232 #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
233 mod consts {
234 use libc::{self, c_int};
235
236 bitflags!(
237 pub flags OFlag: c_int {
238 const O_ACCMODE = libc::O_ACCMODE,
239 const O_RDONLY = libc::O_RDONLY,
240 const O_WRONLY = libc::O_WRONLY,
241 const O_RDWR = libc::O_RDWR,
242 const O_CREAT = libc::O_CREAT,
243 const O_EXCL = libc::O_EXCL,
244 const O_NOCTTY = libc::O_NOCTTY,
245 const O_TRUNC = libc::O_TRUNC,
246 const O_APPEND = libc::O_APPEND,
247 const O_NONBLOCK = libc::O_NONBLOCK,
248 const O_DIRECTORY = 0x0020000,
249 const O_NOFOLLOW = libc::O_NOFOLLOW,
250 const O_CLOEXEC = libc::O_CLOEXEC,
251 const O_SYNC = libc::O_SYNC,
252 const O_NDELAY = libc::O_NDELAY,
253 const O_FSYNC = libc::O_FSYNC,
254 const O_SHLOCK = 0x0000080,
255 const O_EXLOCK = 0x0000020,
256 const O_DIRECT = 0x0010000,
257 const O_EXEC = 0x0040000,
258 const O_TTY_INIT = 0x0080000
259 }
260 );
261
262 bitflags!(
263 pub flags FdFlag: c_int {
264 const FD_CLOEXEC = 1
265 }
266 );
267 }
268
269 #[cfg(target_os = "netbsd")]
270 mod consts {
271 use libc::c_int;
272
273 bitflags!(
274 pub flags OFlag: c_int {
275 const O_ACCMODE = 0x0000003,
276 const O_RDONLY = 0x0000000,
277 const O_WRONLY = 0x0000001,
278 const O_RDWR = 0x0000002,
279 const O_NONBLOCK = 0x0000004,
280 const O_APPEND = 0x0000008,
281 const O_SHLOCK = 0x0000010,
282 const O_EXLOCK = 0x0000020,
283 const O_ASYNC = 0x0000040,
284 const O_SYNC = 0x0000080,
285 const O_NOFOLLOW = 0x0000100,
286 const O_CREAT = 0x0000200,
287 const O_TRUNC = 0x0000400,
288 const O_EXCL = 0x0000800,
289 const O_NOCTTY = 0x0008000,
290 const O_DSYNC = 0x0010000,
291 const O_RSYNC = 0x0020000,
292 const O_ALT_IO = 0x0040000,
293 const O_DIRECT = 0x0080000,
294 const O_NOSIGPIPE = 0x0100000,
295 const O_DIRECTORY = 0x0200000,
296 const O_CLOEXEC = 0x0400000,
297 const O_SEARCH = 0x0800000,
298 const O_FSYNC = O_SYNC.bits,
299 const O_NDELAY = O_NONBLOCK.bits,
300 }
301 );
302
303 bitflags!(
304 pub flags FdFlag: c_int {
305 const FD_CLOEXEC = 1
306 }
307 );
308 }
309
310 #[cfg(target_os = "dragonfly")]
311 mod consts {
312 use libc::c_int;
313
314 bitflags!(
315 pub flags OFlag: c_int {
316 const O_ACCMODE = 0x0000003,
317 const O_RDONLY = 0x0000000,
318 const O_WRONLY = 0x0000001,
319 const O_RDWR = 0x0000002,
320 const O_CREAT = 0x0000200,
321 const O_EXCL = 0x0000800,
322 const O_NOCTTY = 0x0008000,
323 const O_TRUNC = 0x0000400,
324 const O_APPEND = 0x0000008,
325 const O_NONBLOCK = 0x0000004,
326 const O_DIRECTORY = 0x8000000, // different from FreeBSD!
327 const O_NOFOLLOW = 0x0000100,
328 const O_CLOEXEC = 0x0020000, // different from FreeBSD!
329 const O_SYNC = 0x0000080,
330 const O_NDELAY = O_NONBLOCK.bits,
331 const O_FSYNC = O_SYNC.bits,
332 const O_SHLOCK = 0x0000010, // different from FreeBSD!
333 const O_EXLOCK = 0x0000020,
334 const O_DIRECT = 0x0010000,
335 }
336 );
337
338 bitflags!(
339 pub flags FdFlag: c_int {
340 const FD_CLOEXEC = 1
341 }
342 );
343 }