Skip to content

Commit 8d0ba74

Browse files
committed
Add flock and lockf to fcntl module
1 parent 4a6df6b commit 8d0ba74

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

stdlib/src/fcntl.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ pub(crate) use fcntl::make_module;
22

33
#[pymodule]
44
mod fcntl {
5+
use std::mem;
6+
57
use crate::vm::{
68
builtins::PyIntRef,
79
function::{ArgMemoryBuffer, ArgStrOrBytesLike, Either, OptionalArg},
@@ -139,4 +141,72 @@ mod fcntl {
139141
}
140142
}
141143
}
144+
145+
#[pyfunction]
146+
fn flock(fd: i32, operation: i32, vm: &VirtualMachine) -> PyResult {
147+
let ret = unsafe { libc::flock(fd, operation) };
148+
// TODO: add support for platforms that don't have a builtin `flock` syscall
149+
if ret < 0 {
150+
return Err(os::errno_err(vm));
151+
}
152+
Ok(vm.ctx.new_int(ret).into())
153+
}
154+
155+
// XXX: at the time of writing, wasi and redox don't have the necessary constants
156+
#[cfg(not(any(target_os = "wasi", target_os = "redox")))]
157+
#[pyfunction]
158+
fn lockf(
159+
fd: i32,
160+
cmd: i32,
161+
len: OptionalArg<PyIntRef>,
162+
start: OptionalArg<PyIntRef>,
163+
whence: OptionalArg<i32>,
164+
vm: &VirtualMachine,
165+
) -> PyResult {
166+
let mut l: libc::flock = unsafe { mem::zeroed() };
167+
if cmd == libc::LOCK_UN {
168+
l.l_type = libc::F_UNLCK
169+
.try_into()
170+
.map_err(|e| vm.new_overflow_error(format!("{e}")))?;
171+
} else if (cmd & libc::LOCK_SH) != 0 {
172+
l.l_type = libc::F_RDLCK
173+
.try_into()
174+
.map_err(|e| vm.new_overflow_error(format!("{e}")))?;
175+
} else if (cmd & libc::LOCK_EX) != 0 {
176+
l.l_type = libc::F_WRLCK
177+
.try_into()
178+
.map_err(|e| vm.new_overflow_error(format!("{e}")))?;
179+
} else {
180+
return Err(vm.new_value_error("unrecognized lockf argument".to_owned()));
181+
}
182+
l.l_start = match start {
183+
OptionalArg::Present(s) => s.try_to_primitive(vm)?,
184+
OptionalArg::Missing => 0,
185+
};
186+
l.l_len = match len {
187+
OptionalArg::Present(l_) => l_.try_to_primitive(vm)?,
188+
OptionalArg::Missing => 0,
189+
};
190+
l.l_whence = match whence {
191+
OptionalArg::Present(w) => w
192+
.try_into()
193+
.map_err(|e| vm.new_overflow_error(format!("{e}")))?,
194+
OptionalArg::Missing => 0,
195+
};
196+
let ret = unsafe {
197+
libc::fcntl(
198+
fd,
199+
if (cmd & libc::LOCK_NB) != 0 {
200+
libc::F_SETLK
201+
} else {
202+
libc::F_SETLKW
203+
},
204+
&l,
205+
)
206+
};
207+
if ret < 0 {
208+
return Err(os::errno_err(vm));
209+
}
210+
Ok(vm.ctx.new_int(ret).into())
211+
}
142212
}

0 commit comments

Comments
 (0)