@@ -5,31 +5,138 @@ use std::os::unix::io::RawFd;
55use std:: ffi:: OsStr ;
66use std:: os:: unix:: ffi:: OsStrExt ;
77
8- #[ cfg( any( target_os = "linux " , target_os = "android " ) ) ]
8+ #[ cfg( any( target_os = "android " , target_os = "linux " ) ) ]
99use 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-
2311libc_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+ #[ cfg( any( target_os = "dragonfly" ,
72+ target_os = "freebsd" ,
73+ target_os = "ios" ,
74+ all( target_os = "linux" , not( target_env = "musl" ) ) ,
75+ target_os = "macos" ,
76+ target_os = "netbsd" ,
77+ target_os = "openbsd" ) ) ]
78+ O_FSYNC ;
79+ /// Allow files whose sizes can't be represented in an `off_t` to be opened.
80+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
81+ O_LARGEFILE ;
82+ /// Do not update the file last access time during `read(2)`s.
83+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
84+ O_NOATIME ;
85+ /// Don't attach the device as the process' controlling terminal.
86+ O_NOCTTY ;
87+ /// Same as `O_NONBLOCK`.
88+ O_NDELAY ;
89+ /// `open()` will fail if the given path is a symbolic link.
90+ O_NOFOLLOW ;
91+ /// When possible, open the file in nonblocking mode.
92+ O_NONBLOCK ;
93+ /// Don't deliver `SIGPIPE`.
94+ #[ cfg( target_os = "netbsd" ) ]
95+ O_NOSIGPIPE ;
96+ /// Obtain a file descriptor for low-level access.
97+ ///
98+ /// The file itself is not opened and other file operations will fail.
99+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
100+ O_PATH ;
101+ /// Only allow reading.
102+ ///
103+ /// This should not be combined with `O_WRONLY` or `O_RDWR`.
104+ O_RDONLY ;
105+ /// Allow both reading and writing.
106+ ///
107+ /// This should not be combined with `O_WRONLY` or `O_RDWR`.
108+ O_RDWR ;
109+ /// Similar to `O_DSYNC` but applies to `read`s instead.
110+ #[ cfg( any( target_os = "linux" , target_os = "netbsd" , target_os = "openbsd" ) ) ]
111+ O_RSYNC ;
112+ /// Skip search permission checks.
113+ #[ cfg( target_os = "netbsd" ) ]
114+ O_SEARCH ;
115+ /// Open with a shared file lock.
116+ #[ cfg( any( target_os = "dragonfly" ,
117+ target_os = "freebsd" ,
118+ target_os = "ios" ,
119+ target_os = "macos" ,
120+ target_os = "netbsd" ,
121+ target_os = "openbsd" ) ) ]
122+ O_SHLOCK ;
123+ /// Implicitly follow each `write()` with an `fsync()`.
124+ O_SYNC ;
125+ /// Create an unnamed temporary file.
126+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
127+ O_TMPFILE ;
128+ /// Truncate an existing regular file to 0 length if it allows writing.
129+ O_TRUNC ;
130+ /// Restore default TTY attributes.
131+ #[ cfg( target_os = "freebsd" ) ]
132+ O_TTY_INIT ;
133+ /// Only allow writing.
134+ ///
135+ /// This should not be combined with `O_RDONLY` or `O_RDWR`.
136+ O_WRONLY ;
137+ }
138+ ) ;
139+
33140pub fn open < P : ?Sized + NixPath > ( path : & P , oflag : OFlag , mode : Mode ) -> Result < RawFd > {
34141 let fd = try!( path. with_nix_path ( |cstr| {
35142 unsafe { libc:: open ( cstr. as_ptr ( ) , oflag. bits ( ) , mode. bits ( ) as c_uint ) }
@@ -76,6 +183,29 @@ pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a m
76183 wrap_readlink_result ( buffer, res)
77184}
78185
186+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
187+ libc_bitflags ! (
188+ /// Additional flags for file sealing, which allows for limiting operations on a file.
189+ pub struct SealFlag : c_int {
190+ /// Prevents further calls to `fcntl()` with `F_ADD_SEALS`.
191+ F_SEAL_SEAL ;
192+ /// The file cannot be reduced in size.
193+ F_SEAL_SHRINK ;
194+ /// The size of the file cannot be increased.
195+ F_SEAL_GROW ;
196+ /// The file contents cannot be modified.
197+ F_SEAL_WRITE ;
198+ }
199+ ) ;
200+
201+ libc_bitflags ! (
202+ /// Additional configuration flags for `fcntl`'s `F_SETFD`.
203+ pub struct FdFlag : c_int {
204+ /// The file descriptor will automatically be closed during a successful `execve(2)`.
205+ FD_CLOEXEC ;
206+ }
207+ ) ;
208+
79209pub enum FcntlArg < ' a > {
80210 F_DUPFD ( RawFd ) ,
81211 F_DUPFD_CLOEXEC ( RawFd ) ,
@@ -92,9 +222,9 @@ pub enum FcntlArg<'a> {
92222 F_OFD_SETLKW ( & ' a libc:: flock ) ,
93223 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
94224 F_OFD_GETLK ( & ' a mut libc:: flock ) ,
95- #[ cfg( target_os = "linux" ) ]
225+ #[ cfg( any ( target_os = "android" , target_os = " linux") ) ]
96226 F_ADD_SEALS ( SealFlag ) ,
97- #[ cfg( target_os = "linux" ) ]
227+ #[ cfg( any ( target_os = "android" , target_os = " linux") ) ]
98228 F_GET_SEALS ,
99229 #[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
100230 F_FULLFSYNC ,
@@ -120,10 +250,10 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
120250 F_SETLK ( flock) => libc:: fcntl ( fd, libc:: F_SETLK , flock) ,
121251 F_SETLKW ( flock) => libc:: fcntl ( fd, libc:: F_SETLKW , flock) ,
122252 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 ) ,
253+ #[ cfg( any ( target_os = "android" , target_os = " linux") ) ]
254+ F_ADD_SEALS ( flag) => libc:: fcntl ( fd, libc :: F_ADD_SEALS , flag. bits ( ) ) ,
255+ #[ cfg( any ( target_os = "android" , target_os = " linux") ) ]
256+ F_GET_SEALS => libc:: fcntl ( fd, libc :: F_GET_SEALS ) ,
127257 #[ cfg( any( target_os = "macos" , target_os = "ios" ) ) ]
128258 F_FULLFSYNC => libc:: fcntl ( fd, libc:: F_FULLFSYNC ) ,
129259 #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
@@ -164,6 +294,27 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
164294 Errno :: result ( res) . map ( drop)
165295}
166296
297+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
298+ libc_bitflags ! {
299+ /// Additional flags to `splice` and friends.
300+ pub struct SpliceFFlags : c_uint {
301+ /// Request that pages be moved instead of copied.
302+ ///
303+ /// Not applicable to `vmsplice`.
304+ SPLICE_F_MOVE ;
305+ /// Do not block on I/O.
306+ SPLICE_F_NONBLOCK ;
307+ /// Hint that more data will be coming in a subsequent splice.
308+ ///
309+ /// Not applicable to `vmsplice`.
310+ SPLICE_F_MORE ;
311+ /// Gift the user pages to the kernel.
312+ ///
313+ /// Not applicable to `splice`.
314+ SPLICE_F_GIFT ;
315+ }
316+ }
317+
167318#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
168319pub fn splice ( fd_in : RawFd , off_in : Option < & mut libc:: loff_t > ,
169320 fd_out : RawFd , off_out : Option < & mut libc:: loff_t > ,
@@ -190,111 +341,3 @@ pub fn vmsplice(fd: RawFd, iov: &[IoVec<&[u8]>], flags: SpliceFFlags) -> Result<
190341 Errno :: result ( ret) . map ( |r| r as usize )
191342}
192343
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- }
0 commit comments