You can determine which process, if any, is holding a lock. Use this as a simple test or to find locks on a file. A lock is set, as in the previous examples, and F_GETLK is used in fcntl(2). The next example finds and prints indentifying 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, and it can fail (returning ENOLCK) if there is a resource shortage on either the client or server.
lockf(3C) with the F_TEST command can be used to test if a process is holding a lock. This function does not return information about where the lock is and which process owns it.
(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;
}