Skip to content

Commit 3444d07

Browse files
committed
Use upstream libc definitions for fcntl FFI
1 parent 3b4fb07 commit 3444d07

File tree

2 files changed

+169
-131
lines changed

2 files changed

+169
-131
lines changed

src/fcntl.rs

Lines changed: 165 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,131 @@ use std::os::unix::io::RawFd;
55
use std::ffi::OsStr;
66
use std::os::unix::ffi::OsStrExt;
77

8-
#[cfg(any(target_os = "linux", target_os = "android"))]
8+
#[cfg(any(target_os = "android", target_os = "linux"))]
99
use sys::uio::IoVec; // For vmsplice
1010

11-
pub use self::consts::*;
12-
13-
// TODO: The remainder of the ffi module should be removed afer work on
14-
// https://github.com/rust-lang/libc/issues/235 is resolved.
15-
#[allow(dead_code)]
16-
mod ffi {
17-
use libc::c_int;
18-
19-
pub const F_ADD_SEALS: c_int = 1033;
20-
pub const F_GET_SEALS: c_int = 1034;
21-
}
22-
2311
libc_bitflags!{
2412
pub struct AtFlags: c_int {
2513
AT_SYMLINK_NOFOLLOW;
26-
#[cfg(any(target_os = "linux", target_os = "android"))]
14+
#[cfg(any(target_os = "android", target_os = "linux"))]
2715
AT_NO_AUTOMOUNT;
28-
#[cfg(any(target_os = "linux", target_os = "android"))]
16+
#[cfg(any(target_os = "android", target_os = "linux"))]
2917
AT_EMPTY_PATH;
3018
}
3119
}
3220

21+
libc_bitflags!(
22+
/// Configuration options for opened files.
23+
pub struct OFlag: c_int {
24+
/// Mask for the access mode of the file.
25+
O_ACCMODE;
26+
/// Use alternate I/O semantics.
27+
#[cfg(target_os = "netbsd")]
28+
O_ALT_IO;
29+
/// Open the file in append-only mode.
30+
O_APPEND;
31+
/// Generate a signal when input or output becomes possible.
32+
O_ASYNC;
33+
/// Closes the file descriptor once an `execve` call is made.
34+
///
35+
/// Also sets the file offset to the beginning of the file.
36+
O_CLOEXEC;
37+
/// Create the file if it does not exist.
38+
O_CREAT;
39+
/// Try to minimize cache effects of the I/O for this file.
40+
#[cfg(any(target_os = "android",
41+
target_os = "dragonfly",
42+
target_os = "freebsd",
43+
target_os = "linux",
44+
target_os = "netbsd"))]
45+
O_DIRECT;
46+
/// If the specified path isn't a directory, fail.
47+
O_DIRECTORY;
48+
/// Implicitly follow each `write()` with an `fdatasync()`.
49+
#[cfg(any(target_os = "android",
50+
target_os = "dragonfly",
51+
target_os = "ios",
52+
target_os = "linux",
53+
target_os = "macos",
54+
target_os = "netbsd",
55+
target_os = "openbsd"))]
56+
O_DSYNC;
57+
/// Error out if a file was not created.
58+
O_EXCL;
59+
/// Open for execute only.
60+
#[cfg(target_os = "freebsd")]
61+
O_EXEC;
62+
/// Open with an exclusive file lock.
63+
#[cfg(any(target_os = "dragonfly",
64+
target_os = "freebsd",
65+
target_os = "ios",
66+
target_os = "macos",
67+
target_os = "netbsd",
68+
target_os = "openbsd"))]
69+
O_EXLOCK;
70+
/// Same as `O_SYNC`.
71+
O_FSYNC;
72+
/// Allow files whose sizes can't be represented in an `off_t` to be opened.
73+
#[cfg(any(target_os = "android", target_os = "linux"))]
74+
O_LARGEFILE;
75+
/// Do not update the file last access time during `read(2)`s.
76+
#[cfg(any(target_os = "android", target_os = "linux"))]
77+
O_NOATIME;
78+
/// Don't attach the device as the process' controlling terminal.
79+
O_NOCTTY;
80+
/// Same as `O_NONBLOCK`.
81+
O_NDELAY;
82+
/// `open()` will fail if the given path is a symbolic link.
83+
O_NOFOLLOW;
84+
/// When possible, open the file in nonblocking mode.
85+
O_NONBLOCK;
86+
/// Don't deliver `SIGPIPE`.
87+
#[cfg(target_os = "netbsd")]
88+
O_NOSIGPIPE;
89+
/// Obtain a file descriptor for low-level access.
90+
///
91+
/// The file itself is not opened and other file operations will fail.
92+
#[cfg(any(target_os = "android", target_os = "linux"))]
93+
O_PATH;
94+
/// Only allow reading.
95+
///
96+
/// This should not be combined with `O_WRONLY` or `O_RDWR`.
97+
O_RDONLY;
98+
/// Allow both reading and writing.
99+
///
100+
/// This should not be combined with `O_WRONLY` or `O_RDWR`.
101+
O_RDWR;
102+
/// Similar to `O_DSYNC` but applies to `read`s instead.
103+
#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
104+
O_RSYNC;
105+
/// Skip search permission checks.
106+
#[cfg(target_os = "netbsd")]
107+
O_SEARCH;
108+
/// Open with a shared file lock.
109+
#[cfg(any(target_os = "dragonfly",
110+
target_os = "freebsd",
111+
target_os = "ios",
112+
target_os = "macos",
113+
target_os = "netbsd",
114+
target_os = "openbsd"))]
115+
O_SHLOCK;
116+
/// Implicitly follow each `write()` with an `fsync()`.
117+
O_SYNC;
118+
/// Create an unnamed temporary file.
119+
#[cfg(any(target_os = "android", target_os = "linux"))]
120+
O_TMPFILE;
121+
/// Truncate an existing regular file to 0 length if it allows writing.
122+
O_TRUNC;
123+
/// Restore default TTY attributes.
124+
#[cfg(target_os = "freebsd")]
125+
O_TTY_INIT;
126+
/// Only allow writing.
127+
///
128+
/// This should not be combined with `O_RDONLY` or `O_RDWR`.
129+
O_WRONLY;
130+
}
131+
);
132+
33133
pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
34134
let fd = try!(path.with_nix_path(|cstr| {
35135
unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
@@ -76,6 +176,29 @@ pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a m
76176
wrap_readlink_result(buffer, res)
77177
}
78178

179+
#[cfg(any(target_os = "android", target_os = "linux"))]
180+
libc_bitflags!(
181+
/// Additional flags for file sealing, which allows for limiting operations on a file.
182+
pub struct SealFlag: c_int {
183+
/// Prevents further calls to `fcntl()` with `F_ADD_SEALS`.
184+
F_SEAL_SEAL;
185+
/// The file cannot be reduced in size.
186+
F_SEAL_SHRINK;
187+
/// The size of the file cannot be increased.
188+
F_SEAL_GROW;
189+
/// The file contents cannot be modified.
190+
F_SEAL_WRITE;
191+
}
192+
);
193+
194+
libc_bitflags!(
195+
/// Additional configuration flags for `fcntl`'s `F_SETFD`.
196+
pub struct FdFlag: c_int {
197+
/// The file descriptor will automatically be closed during a successful `execve(2)`.
198+
FD_CLOEXEC;
199+
}
200+
);
201+
79202
pub enum FcntlArg<'a> {
80203
F_DUPFD(RawFd),
81204
F_DUPFD_CLOEXEC(RawFd),
@@ -92,9 +215,9 @@ pub enum FcntlArg<'a> {
92215
F_OFD_SETLKW(&'a libc::flock),
93216
#[cfg(any(target_os = "linux", target_os = "android"))]
94217
F_OFD_GETLK(&'a mut libc::flock),
95-
#[cfg(target_os = "linux")]
218+
#[cfg(any(target_os = "android", target_os = "linux"))]
96219
F_ADD_SEALS(SealFlag),
97-
#[cfg(target_os = "linux")]
220+
#[cfg(any(target_os = "android", target_os = "linux"))]
98221
F_GET_SEALS,
99222
#[cfg(any(target_os = "macos", target_os = "ios"))]
100223
F_FULLFSYNC,
@@ -120,10 +243,10 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
120243
F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
121244
F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
122245
F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
123-
#[cfg(target_os = "linux")]
124-
F_ADD_SEALS(flag) => libc::fcntl(fd, ffi::F_ADD_SEALS, flag.bits()),
125-
#[cfg(target_os = "linux")]
126-
F_GET_SEALS => libc::fcntl(fd, ffi::F_GET_SEALS),
246+
#[cfg(any(target_os = "android", target_os = "linux"))]
247+
F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
248+
#[cfg(any(target_os = "android", target_os = "linux"))]
249+
F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
127250
#[cfg(any(target_os = "macos", target_os = "ios"))]
128251
F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
129252
#[cfg(any(target_os = "linux", target_os = "android"))]
@@ -164,6 +287,27 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
164287
Errno::result(res).map(drop)
165288
}
166289

290+
#[cfg(any(target_os = "android", target_os = "linux"))]
291+
libc_bitflags! {
292+
/// Additional flags to `splice` and friends.
293+
pub struct SpliceFFlags: c_uint {
294+
/// Request that pages be moved instead of copied.
295+
///
296+
/// Not applicable to `vmsplice`.
297+
SPLICE_F_MOVE;
298+
/// Do not block on I/O.
299+
SPLICE_F_NONBLOCK;
300+
/// Hint that more data will be coming in a subsequent splice.
301+
///
302+
/// Not applicable to `vmsplice`.
303+
SPLICE_F_MORE;
304+
/// Gift the user pages to the kernel.
305+
///
306+
/// Not applicable to `splice`.
307+
SPLICE_F_GIFT;
308+
}
309+
}
310+
167311
#[cfg(any(target_os = "linux", target_os = "android"))]
168312
pub fn splice(fd_in: RawFd, off_in: Option<&mut libc::loff_t>,
169313
fd_out: RawFd, off_out: Option<&mut libc::loff_t>,
@@ -190,111 +334,3 @@ pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<
190334
Errno::result(ret).map(|r| r as usize)
191335
}
192336

193-
#[cfg(any(target_os = "linux", target_os = "android"))]
194-
mod consts {
195-
use libc::{self, c_int, c_uint};
196-
197-
libc_bitflags! {
198-
pub struct SpliceFFlags: c_uint {
199-
SPLICE_F_MOVE;
200-
SPLICE_F_NONBLOCK;
201-
SPLICE_F_MORE;
202-
SPLICE_F_GIFT;
203-
}
204-
}
205-
206-
bitflags!(
207-
pub struct OFlag: c_int {
208-
const O_ACCMODE = libc::O_ACCMODE;
209-
const O_RDONLY = libc::O_RDONLY;
210-
const O_WRONLY = libc::O_WRONLY;
211-
const O_RDWR = libc::O_RDWR;
212-
const O_CREAT = libc::O_CREAT;
213-
const O_EXCL = libc::O_EXCL;
214-
const O_NOCTTY = libc::O_NOCTTY;
215-
const O_TRUNC = libc::O_TRUNC;
216-
const O_APPEND = libc::O_APPEND;
217-
const O_NONBLOCK = libc::O_NONBLOCK;
218-
const O_DSYNC = libc::O_DSYNC;
219-
const O_DIRECT = libc::O_DIRECT;
220-
const O_LARGEFILE = 0o00100000;
221-
const O_DIRECTORY = libc::O_DIRECTORY;
222-
const O_NOFOLLOW = libc::O_NOFOLLOW;
223-
const O_NOATIME = 0o01000000;
224-
const O_CLOEXEC = libc::O_CLOEXEC;
225-
const O_SYNC = libc::O_SYNC;
226-
const O_PATH = 0o10000000;
227-
const O_TMPFILE = libc::O_TMPFILE;
228-
const O_NDELAY = libc::O_NDELAY;
229-
}
230-
);
231-
232-
libc_bitflags!(
233-
pub struct FdFlag: c_int {
234-
FD_CLOEXEC;
235-
}
236-
);
237-
238-
bitflags!(
239-
pub struct SealFlag: c_int {
240-
const F_SEAL_SEAL = 1;
241-
const F_SEAL_SHRINK = 2;
242-
const F_SEAL_GROW = 4;
243-
const F_SEAL_WRITE = 8;
244-
}
245-
);
246-
247-
}
248-
249-
#[cfg(any(target_os = "netbsd", target_os = "dragonfly", target_os = "openbsd",
250-
target_os = "freebsd", target_os = "macos", target_os = "ios"))]
251-
mod consts {
252-
use libc::{self,c_int};
253-
254-
libc_bitflags!(
255-
pub struct OFlag: c_int {
256-
O_ACCMODE;
257-
O_RDONLY;
258-
O_WRONLY;
259-
O_RDWR;
260-
O_NONBLOCK;
261-
O_APPEND;
262-
O_SHLOCK;
263-
O_EXLOCK;
264-
O_ASYNC;
265-
O_SYNC;
266-
O_NOFOLLOW;
267-
O_CREAT;
268-
O_TRUNC;
269-
O_EXCL;
270-
O_NOCTTY;
271-
O_DIRECTORY;
272-
O_CLOEXEC;
273-
O_FSYNC;
274-
O_NDELAY;
275-
#[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "macos",
276-
target_os = "ios"))]
277-
O_DSYNC;
278-
#[cfg(any(target_os = "netbsd", target_os = "dragonfly", target_os = "freebsd"))]
279-
O_DIRECT;
280-
#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
281-
O_RSYNC;
282-
#[cfg(target_os = "freebsd")]
283-
O_EXEC;
284-
#[cfg(target_os = "freebsd")]
285-
O_TTY_INIT;
286-
#[cfg(target_os = "netbsd")]
287-
O_ALT_IO;
288-
#[cfg(target_os = "netbsd")]
289-
O_NOSIGPIPE;
290-
#[cfg(target_os = "netbsd")]
291-
O_SEARCH;
292-
}
293-
);
294-
295-
libc_bitflags!(
296-
pub struct FdFlag: c_int {
297-
FD_CLOEXEC;
298-
}
299-
);
300-
}

src/unistd.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use errno;
44
use {Errno, Error, Result, NixPath};
5-
use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
5+
use fcntl::{fcntl, OFlag};
66
use fcntl::FcntlArg::F_SETFD;
77
use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t,
88
uid_t, gid_t, mode_t};
@@ -355,6 +355,8 @@ pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
355355

356356
#[inline]
357357
fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
358+
use fcntl::{FD_CLOEXEC, O_CLOEXEC};
359+
358360
if oldfd == newfd {
359361
return Err(Error::Sys(Errno::EINVAL));
360362
}
@@ -857,7 +859,7 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
857859
target_os = "android",
858860
target_os = "emscripten")))]
859861
fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
860-
use fcntl::O_NONBLOCK;
862+
use fcntl::{FD_CLOEXEC, O_CLOEXEC, O_NONBLOCK};
861863
use fcntl::FcntlArg::F_SETFL;
862864

863865
let mut res = Ok(0);

0 commit comments

Comments
 (0)