2 * Copyright 2007, Vasilis Kaoutsis, kaoutsis@sch.gr.
3 * Distributed under the terms of the MIT License.
10 #include <errno_private.h>
14 lockf(int fileDescriptor
, int function
, off_t size
)
16 struct flock fileLock
;
18 fileLock
.l_len
= size
;
19 fileLock
.l_whence
= SEEK_CUR
;
21 if (function
== F_ULOCK
) {
22 // unlock locked sections
23 fileLock
.l_type
= F_UNLCK
;
24 return fcntl(fileDescriptor
, F_SETLK
, &fileLock
);
25 } else if (function
== F_LOCK
) {
26 // lock a section for exclusive use
27 fileLock
.l_type
= F_WRLCK
;
28 return fcntl(fileDescriptor
, F_SETLKW
, &fileLock
);
29 } else if (function
== F_TLOCK
) {
30 // test and lock a section for exclusive use
31 fileLock
.l_type
= F_WRLCK
;
32 return fcntl(fileDescriptor
, F_SETLK
, &fileLock
);
33 } else if (function
== F_TEST
) {
34 // test a section for locks by other processes
35 fileLock
.l_type
= F_WRLCK
;
36 if (fcntl(fileDescriptor
, F_GETLK
, &fileLock
) == -1)
38 if (fileLock
.l_type
== F_UNLCK
)
48 // Notes regarding standard compliance (cf. Open Group Base Specs):
49 // * "The interaction between fcntl() and lockf() locks is unspecified."
50 // * fcntl() locking works on a per-process level. The lockf() description
51 // is a little fuzzy on whether it works the same way. The first quote
52 // seem to describe per-thread locks (though it might actually mean
53 // "threads of other processes"), but the others quotes are strongly
54 // indicating per-process locks:
55 // - "Calls to lockf() from other threads which attempt to lock the locked
56 // file section shall either return an error value or block until the
57 // section becomes unlocked."
58 // - "All the locks for a process are removed when the process
60 // - "F_TEST shall detect if a lock by another process is present on the
61 // specified section."
62 // - "The sections locked with F_LOCK or F_TLOCK may, in whole or in part,
63 // contain or be contained by a previously locked section for the same
64 // process. When this occurs, or if adjacent locked sections would
65 // occur, the sections shall be combined into a single locked section."
66 // * fcntl() and lockf() handle a 0 size argument differently. The former
67 // use the file size at the time of the call:
68 // "If the command is F_SETLKW and the process must wait for another
69 // process to release a lock, then the range of bytes to be locked shall
70 // be determined before the fcntl() function blocks. If the file size
71 // or file descriptor seek offset change while fcntl() is blocked, this
72 // shall not affect the range of bytes locked."
73 // lockf(), on the other hand, is supposed to create a lock whose size
74 // dynamically adjusts to the file size:
75 // "If size is 0, the section from the current offset through the largest
76 // possible file offset shall be locked (that is, from the current
77 // offset through the present or any future end-of-file)."
78 // * The lock release handling when closing descriptors sounds a little
79 // different, though might actually mean the same.
81 // "All locks associated with a file for a given process shall be removed
82 // when a file descriptor for that file is closed by that process or the
83 // process holding that file descriptor terminates."
85 // "File locks shall be released on first close by the locking process of
86 // any file descriptor for the file."