You can determine which process is holding a lock. A lock is set, as in the previous examples, and F_GETLK is used in fcntl(2).
The next example finds and prints identifying data on all the locked segments of a file.
struct flock lck;
lck.l_whence = 0;
lck.l_start = 0L;
lck.l_len = 0L;
do {
lck.l_type = F_WRLCK;
(void) fcntl(fd, F_GETLK, &lck);
if (lck.l_type != F_UNLCK) {
(void) printf("%d %d %c %8ld %8ld\n", lck.l_sysid, lck.l_pid,
(lck.l_type == F_WRLCK) ? 'W' : 'R', lck.l_start, lck.l_len);
/* If this lock goes to the end of the address space, no
* need to look further, so break out. */
if (lck.l_len == 0) {
/* else, look for new lock after the one just found. */
lck.l_start += lck.l_len;
}
}
} while (lck.l_type != F_UNLCK);
fcntl(2) with the F_GETLK command can sleep while waiting for a server to respond. The command can fail, returning ENOLCK, if either the client or the server have a resource shortage.
Use lockf(3C) with the F_TEST command to test if a process is holding a lock. This interface does not return information about the lock's location or ownership.
(void) lseek(fd, 0, 0L);
/* set the size of the test region to zero (0). to test until the
end of the file address space. */
if (lockf(fd, (off_t)0, SEEK_SET) < 0) {
switch (errno) {
case EACCES:
case EAGAIN:
(void) printf("file is locked by another process\n");
break;
case EBADF:
/* bad argument passed to lockf */
perror("lockf");
break;
default:
(void) printf("lockf: unexpected error <%d>\n", errno);
break;
}
}