1 use {Errno, Result, NixPath}
;
2 use libc
::{self, c_int, c_uint}
;
4 use std
::os
::unix
::io
::RawFd
;
6 #[cfg(any(target_os = "linux", target_os = "android"))]
7 use sys
::uio
::IoVec
; // For vmsplice
9 pub use self::consts
::*;
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.
17 pub const F_ADD_SEALS
: c_int
= 1033;
18 pub const F_GET_SEALS
: c_int
= 1034;
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) }
29 pub enum FcntlArg
<'a
> {
31 F_DUPFD_CLOEXEC(RawFd
),
33 F_SETFD(FdFlag
), // FD_FLAGS
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")]
49 #[cfg(any(target_os = "macos", target_os = "ios"))]
51 #[cfg(any(target_os = "linux", target_os = "android"))]
53 #[cfg(any(target_os = "linux", target_os = "android"))]
54 F_SETPIPE_SZ(libc
::c_int
),
56 // TODO: Rest of flags
58 pub use self::FcntlArg
::*;
60 // TODO: Figure out how to handle value fcntl returns
61 pub fn fcntl(fd
: RawFd
, arg
: FcntlArg
) -> Result
<c_int
> {
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"))]
96 LockExclusiveNonblock
,
100 pub fn flock(fd
: RawFd
, arg
: FlockArg
) -> Result
<()> {
101 use self::FlockArg
::*;
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
),
114 Errno
::result(res
).map(drop
)
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> {
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());
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)
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)
135 #[cfg(any(target_os = "linux", target_os = "android"))]
136 pub fn vmsplice(fd
: RawFd
, iov
: &[IoVec
<&[u8]>], flags
: SpliceFFlags
) -> Result
<usize> {
138 libc
::vmsplice(fd
, iov
.as_ptr() as *const libc
::iovec
, iov
.len(), flags
.bits())
140 Errno
::result(ret
).map(|r
| r
as usize)
143 #[cfg(any(target_os = "linux", target_os = "android"))]
145 use libc
::{self, c_int, c_uint}
;
148 pub flags SpliceFFlags
: c_uint
{
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
,
183 pub flags FdFlag
: c_int
{
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,
199 #[cfg(any(target_os = "macos", target_os = "ios"))]
201 use libc
::{self, c_int}
;
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
,
226 pub flags FdFlag
: c_int
{
232 #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
234 use libc
::{self, c_int}
;
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
263 pub flags FdFlag
: c_int
{
269 #[cfg(target_os = "netbsd")]
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
,
304 pub flags FdFlag
: c_int
{
310 #[cfg(target_os = "dragonfly")]
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,
339 pub flags FdFlag
: c_int
{