Locking a record is done the same way as locking a file except that the starting point and length of the lock segment are not set to zero.
Plan a failure response for when you cannot obtain all the required locks. Contention for data is why you use record locking, so different programs might:
Wait a certain amount of time, then try again
Abort the procedure and warn the user
Let the process sleep until signaled that the lock has been freed
Do some combination of the above
This example shows locking a record using fcntl(2).
{ struct flock lck; ... lck.l_type = F_WRLCK; /* setting a write lock */ lck.l_whence = 0; /* offset l_start from beginning of file */ lck.l_start = here; lck.l_len = sizeof(struct record); /* lock "this" with write lock */ lck.l_start = this; if (fcntl(fd, F_SETLKW, &lck) < 0) { /* "this" lock failed. */ return (-1); ... }
The next example shows the lockf(3C) function.
#include <unistd.h> { ... /* lock "this" */ (void) lseek(fd, this, SEEK_SET); if (lockf(fd, F_LOCK, sizeof(struct record)) < 0) { /* Lock on "this" failed. Clear lock on "here". */ (void) lseek(fd, here, 0); (void) lockf(fd, F_ULOCK, sizeof(struct record)); return (-1); }
Locks are removed the same way they are set--only the lock type is different (F_ULOCK). An unlock cannot be blocked by another process and affects only locks placed by the calling process. The unlock affects only the segment of the file specified in the preceding locking call.