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; }