@@ -139,4 +139,74 @@ mod fcntl {
139139 }
140140 }
141141 }
142+
143+ // XXX: at the time of writing, wasi and redox don't have the necessary constants/function
144+ #[ cfg( not( any( target_os = "wasi" , target_os = "redox" ) ) ) ]
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 { std:: 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