ロッキングを設定できないようにブロッキングしているプロセスがあれば、それがどのプロセスかを判定できます。これは簡単なテストとして、またはファイル上のロッキングを見つけるために使用できます。ロッキングは上記の例のように設定され、fcntl(2) で F_GETLK が使用されます。次の例では、ファイル内でロッキングされているすべてのセグメントについてのデータを検索して出力します。
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 %8d %8d¥n", lck.l_sysid, lck.l_pid, (lck.l_type == F_WRLCK) ? 'W' : 'R', lck.l_start, lck.l_len); /* このロッキングがアドレス空間の終わりまで続いている場合は、 * それ以上探す必要がないのでループは終了する */ if (lck.l_len == 0) { /* それ以外の場合は、見つかったロッキングの後方のロッキングを探す */ lck.l_start += lck.l_len; } } } while (lck.l_type != F_UNLCK); |
F_GETLK() コマンドを伴う fcntl(2) 関数は、サーバの応答を待つ間に休眠することがあり、クライアント側またはサーバ側の資源が不足すると失敗する場合もあります (ENOLCK を戻します)。
F_TEST コマンドを伴う lockf(3C) 関数は、プロセスがロッキングを 保持しているかどうかの検査にも使用できます。ただしこの関数は、ロッキングの位置とそのロッキングを 所有しているプロセスについての情報は戻しません。
(void) lseek(fd, 0, 0L); /* ファイルアドレス空間の終わりまで検索するため、 テスト領域の大きさを 0 に設定する */ 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: /* lockf に渡された引数が不正 */ perror("lockf"); break; default: (void) printf("lockf: unexpected error <%d>¥n", errno); break; } |