diff options
Diffstat (limited to 'src/fcntl.rs')
-rw-r--r-- | src/fcntl.rs | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs index ccaee9bc..80290aec 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -4,11 +4,66 @@ use libc::{c_int, mode_t}; use errno::{SysResult, SysError}; pub use self::consts::*; +pub use self::ffi::flock; pub type Fd = c_int; mod ffi { - pub use libc::open; + pub use libc::{open, fcntl}; + pub use self::os::*; + + #[cfg(target_os = "linux")] + mod os { + use libc::{c_int, c_short, off_t, pid_t}; + + pub struct flock { + pub l_type: c_short, + pub l_whence: c_short, + pub l_start: off_t, + pub l_len: off_t, + pub l_pid: pid_t, + + // not actually here, but brings in line with freebsd + pub l_sysid: c_int, + } + + pub static F_DUPFD: c_int = 0; + pub static F_DUPFD_CLOEXEC: c_int = 1030; + pub static F_GETFD: c_int = 1; + pub static F_SETFD: c_int = 2; + pub static F_GETFL: c_int = 3; + pub static F_SETFL: c_int = 4; + pub static F_SETLK: c_int = 6; + pub static F_SETLKW: c_int = 7; + pub static F_GETLK: c_int = 5; + } + + #[cfg(target_os = "macos")] + #[cfg(target_os = "ios")] + mod os { + use libc::{c_int, c_short, off_t, pid_t}; + + pub struct flock { + pub l_start: off_t, + pub l_len: off_t, + pub l_pid: pid_t, + pub l_type: c_short, + pub l_whence: c_short, + + // not actually here, but brings in line with freebsd + pub l_sysid: c_int, + } + + pub static F_DUPFD: c_int = 0; + pub static F_DUPFD_CLOEXEC: c_int = 67; + pub static F_GETFD: c_int = 1; + pub static F_SETFD: c_int = 2; + pub static F_GETFL: c_int = 3; + pub static F_SETFL: c_int = 4; + pub static F_SETLK: c_int = 8; + pub static F_SETLKW: c_int = 9; + pub static F_GETLK: c_int = 7; + } } pub fn open(path: &Path, oflag: OFlag, mode: FilePermission) -> SysResult<Fd> { @@ -21,6 +76,43 @@ pub fn open(path: &Path, oflag: OFlag, mode: FilePermission) -> SysResult<Fd> { Ok(fd) } +pub enum FcntlArg<'a> { + F_DUPFD(Fd), + F_DUPFD_CLOEXEC(Fd), + F_GETFD, + F_SETFD(FdFlag), // FD_FLAGS + F_GETFL, + F_SETFL(OFlag), // O_NONBLOCK + F_SETLK(&'a flock), + F_SETLKW(&'a flock), + F_GETLK(&'a mut flock), + #[cfg(target_os = "linux")] + F_OFD_SETLK(&'a flock), + #[cfg(target_os = "linux")] + F_OFD_SETLKW(&'a flock), + #[cfg(target_os = "linux")] + F_OFD_GETLK(&'a mut flock) + + // TODO: Rest of flags +} + +// TODO: Figure out how to handle value fcntl returns +pub fn fcntl(fd: Fd, arg: FcntlArg) -> SysResult<()> { + let res = unsafe { + match arg { + F_SETFD(flag) => ffi::fcntl(fd, ffi::F_SETFD, flag.bits()), + F_SETFL(flag) => ffi::fcntl(fd, ffi::F_SETFL, flag.bits()), + _ => unimplemented!() + } + }; + + if res < 0 { + return Err(SysError::last()); + } + + Ok(()) +} + #[cfg(target_os = "linux")] mod consts { use libc::c_int; @@ -50,6 +142,12 @@ mod consts { static O_NDELAY = O_NONBLOCK.bits } ) + + bitflags!( + flags FdFlag: c_int { + static FD_CLOEXEC = 1 + } + ) } #[cfg(target_os = "macos")] @@ -82,4 +180,10 @@ mod consts { static O_NDELAY = O_NONBLOCK.bits } ) + + bitflags!( + flags FdFlag: c_int { + static FD_CLOEXEC = 1 + } + ) } |