ptg10805159
494 Advanced I/O Chapter 14
the linked list of locks for the corresponding i-node and releases the locks held by the
calling process. The kernel can’t tell (and doesn’t care) which descriptor of the three
was used by the parent to obtain the lock.
Example
In the program in Figure13.6, we saw how a daemon can use a lock on a file to ensure
that only one copy of the daemon is running. Figure14.9 shows the implementation of
thelockfilefunction used by the daemon to place a write lock on a file.
#include <unistd.h>
#include <fcntl.h>
int
lockfile(int fd)
{
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
return(fcntl(fd, F_SETLK, &fl));
}
Figure 14.9 Place a write lock on an entirefile
Alternatively, we could define thelockfilefunction in terms of thewrite_lock
function:
#define lockfile(fd) write_lock((fd), 0, SEEK_SET, 0)
Locks at End of File
We need to use caution when locking or unlocking byte ranges relative to the end of file.
Most implementations convert anl_whencevalue ofSEEK_CURorSEEK_ENDinto an
absolute file offset, usingl_startand the file’s current position or current length.
Often, however, we need to specify a lock relative to the file’s current length, but we
can’t callfstatto obtain the current file size, since we don’t have a lock on the file.
(There’s a chance that another process could change the file’s length between the call to
fstatand the lock call.)
Consider the following sequence of steps:
writew_lock(fd, 0, SEEK_END, 0);
write(fd, buf, 1);
un_lock(fd, 0, SEEK_END);
write(fd, buf, 1);
This sequence of code might not do what you expect. It obtains a write lock from the
current end of the file onward, covering any futuredata we might append to the file.