diff --git a/src/c/fcntl.c b/src/c/fcntl.c index 23c48fa12af16a422e1599ea4816b551a6958b03..cc67e4e60c5df5ac4e9eb44f22fc9efc7c206ee1 100644 --- a/src/c/fcntl.c +++ b/src/c/fcntl.c @@ -14,13 +14,13 @@ int open(const char* filename, int flags, ...) { return sys_open(filename, flags, mode); } -int sys_fcntl(int fildes, int cmd, int args); +int sys_fcntl(int fildes, int cmd, unsigned long long args); int fcntl(int fildes, int cmd, ...) { - int args = 0; + unsigned long long args = 0; va_list ap; va_start(ap, cmd); - args = va_arg(ap, int); + args = va_arg(ap, unsigned long long); va_end(ap); return sys_fcntl(fildes, cmd, args); } diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs index 1e9975c68722f95fa7564a2d6a3aab3ba0c894a9..d428d87fe7f2d3e9408dc6578914390b85fa6fe2 100644 --- a/src/header/fcntl/mod.rs +++ b/src/header/fcntl/mod.rs @@ -28,11 +28,17 @@ pub const F_RDLCK: c_int = 0; pub const F_WRLCK: c_int = 1; pub const F_UNLCK: c_int = 2; +pub const F_ULOCK: c_int = 0; +pub const F_LOCK: c_int = 1; +pub const F_TLOCK: c_int = 2; +pub const F_TEST: c_int = 3; + #[no_mangle] pub unsafe extern "C" fn creat(path: *const c_char, mode: mode_t) -> c_int { sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode) } #[repr(C)] +#[derive(Clone, Copy, Default)] pub struct flock { pub l_type: c_short, pub l_whence: c_short, @@ -41,7 +47,7 @@ pub struct flock { pub l_pid: pid_t, } #[no_mangle] -pub extern "C" fn sys_fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int { +pub extern "C" fn sys_fcntl(fildes: c_int, cmd: c_int, arg: c_ulonglong) -> c_int { Sys::fcntl(fildes, cmd, arg) } diff --git a/src/header/stdio/helpers.rs b/src/header/stdio/helpers.rs index dc42b100158a7002e1d475614bb0edf24adc580e..f29242115d613fa8e566067fc5ef2f3ed3e66f2d 100644 --- a/src/header/stdio/helpers.rs +++ b/src/header/stdio/helpers.rs @@ -50,13 +50,13 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> { } if !strchr(mode, b'e' as i32).is_null() { - sys_fcntl(fd, F_SETFD, FD_CLOEXEC); + sys_fcntl(fd, F_SETFD, FD_CLOEXEC as c_ulonglong); } if *mode == 'a' as i8 { let f = sys_fcntl(fd, F_GETFL, 0); if (f & O_APPEND) == 0 { - sys_fcntl(fd, F_SETFL, f | O_APPEND); + sys_fcntl(fd, F_SETFL, (f | O_APPEND) as c_ulonglong); } flags |= F_APP; } diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index a5ace892c6824c882df0b575288c1c7be5ce170a..79d7a1be7cdf5de5f69d86fd1591e332cd338e54 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -505,7 +505,7 @@ pub unsafe extern "C" fn fopen(filename: *const c_char, mode: *const c_char) -> } if flags & fcntl::O_CLOEXEC > 0 { - fcntl::sys_fcntl(fd, fcntl::F_SETFD, fcntl::FD_CLOEXEC); + fcntl::sys_fcntl(fd, fcntl::F_SETFD, fcntl::FD_CLOEXEC as c_ulonglong); } if let Some(f) = helpers::_fdopen(fd, mode) { @@ -596,10 +596,10 @@ pub unsafe extern "C" fn freopen( if filename.is_null() { // Reopen stream in new mode if flags & fcntl::O_CLOEXEC > 0 { - fcntl::sys_fcntl(*stream.file, fcntl::F_SETFD, fcntl::FD_CLOEXEC); + fcntl::sys_fcntl(*stream.file, fcntl::F_SETFD, fcntl::FD_CLOEXEC as c_ulonglong); } flags &= !(fcntl::O_CREAT | fcntl::O_EXCL | fcntl::O_CLOEXEC); - if fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, flags) < 0 { + if fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, flags as c_ulonglong) < 0 { funlockfile(stream); fclose(stream); return ptr::null_mut(); @@ -615,7 +615,7 @@ pub unsafe extern "C" fn freopen( if *new.file == *stream.file { new.file.fd = -1; } else if Sys::dup2(*new.file, *stream.file) < 0 - || fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, flags & fcntl::O_CLOEXEC) < 0 + || fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, (flags & fcntl::O_CLOEXEC) as c_ulonglong) < 0 { funlockfile(stream); fclose(new); diff --git a/src/header/sys_ioctl/redox.rs b/src/header/sys_ioctl/redox.rs index 8c0a2ea486e8e11bcbebb312ff9b6adf71a5d92a..ab2980260300aec89e3faea7a17af21409cfb3b1 100644 --- a/src/header/sys_ioctl/redox.rs +++ b/src/header/sys_ioctl/redox.rs @@ -63,7 +63,7 @@ fn dup_write<T>(fd: c_int, name: &str, t: &T) -> syscall::Result<usize> { pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int { match request { FIONBIO => { - let mut flags = fcntl::sys_fcntl(fd, fcntl::F_GETFL, 0); + let mut flags = fcntl::sys_fcntl(fd, fcntl::F_GETFL, 0usize); if flags < 0 { return -1; } @@ -72,7 +72,7 @@ pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> } else { flags | fcntl::O_NONBLOCK }; - if fcntl::sys_fcntl(fd, fcntl::F_SETFL, flags) < 0 { + if fcntl::sys_fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong) < 0 { -1 } else { 0 diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index d443509b6e7daaabb5f6768b396c80a43ace5ec2..cfe2fc53ceefbc6fbc7176fc7d369e9a3dfbfa88 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -451,9 +451,43 @@ pub unsafe extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_i Sys::link(path1, path2) } -// #[no_mangle] -pub extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c_int { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c_int { + let mut fl = fcntl::flock { + l_type: fcntl::F_WRLCK as c_short, + l_whence: SEEK_CUR as c_short, + l_start: 0, + l_len: size, + l_pid: -1, + }; + + match function { + fcntl::F_TEST => { + fl.l_type = fcntl::F_RDLCK as c_short; + if fcntl::sys_fcntl(fildes, fcntl::F_GETLK, &mut fl as *mut _ as c_ulonglong) < 0 { + return -1; + } + if fl.l_type == fcntl::F_UNLCK as c_short || fl.l_pid == getpid() { + return 0; + } + platform::errno = errno::EACCES; + return -1; + }, + fcntl::F_ULOCK => { + fl.l_type = fcntl::F_UNLCK as c_short; + return fcntl::sys_fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong); + }, + fcntl::F_TLOCK => { + return fcntl::sys_fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong); + }, + fcntl::F_LOCK => { + return fcntl::sys_fcntl(fildes, fcntl::F_SETLKW, &mut fl as *mut _ as c_ulonglong); + }, + _ => { + platform::errno = errno::EINVAL; + return -1; + }, + }; } #[no_mangle] diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 59fb84f809bb74c1517e771e07d87059eb3f3b5a..fa5e770b23966b3be4ad8656bc85a790f280da25 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -210,7 +210,7 @@ impl Pal for Sys { res } - fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int { + fn fcntl(fildes: c_int, cmd: c_int, arg: c_ulonglong) -> c_int { e(unsafe { syscall!(FCNTL, fildes, cmd, arg) }) as c_int } diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 5c3f7b14a3bd2a7d9580c55ca712296287548a12..2f78c777190eaac1e7f7d718066b6d0c961923e2 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -67,7 +67,7 @@ pub trait Pal { fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int; - fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int; + fn fcntl(fildes: c_int, cmd: c_int, arg: c_ulonglong) -> c_int; fn fork() -> pid_t; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 6477939ec9a435eb736bd247c960895d84d02626..5e09657f7868e89292775c704907f55626165719 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -259,7 +259,7 @@ impl Pal for Sys { e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int } - fn fcntl(fd: c_int, cmd: c_int, args: c_int) -> c_int { + fn fcntl(fd: c_int, cmd: c_int, args: c_ulonglong) -> c_int { e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int }