summaryrefslogtreecommitdiff
path: root/src/fcntl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/fcntl.rs')
-rw-r--r--src/fcntl.rs106
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
+ }
+ )
}