プログラミングインタフェース

ロック情報の取得

どのプロセスがロックを保留しているかを判断できます。ロックは上記の例のように設定され、fcntl(2)F_GETLK が使用されます。

次の例では、ファイル内でロックされているすべてのセグメントについてのデータを検索して出力します。


例 4–2 ファイル内でロックされているセグメントの出力

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 (lck.l_len == 0) {
 			/* それ以外の場合、見つかったロックの後方にあるロックを探す */
 					lck.l_start += lck.l_len;
 			}
 		}
 	} while (lck.l_type != F_UNLCK);

F_GETLK コマンドを指定すると、fcntl(2) はサーバーが応答するまで待機および休眠できます。fcntl(2) はまた、クライアントまたはサーバー側の資源が不足すると失敗して、ENOLCK を返すことがあります。

F_TEST コマンドを指定すると、 lockf(3C) はプロセスがロックを保留しているかどうかを検査できます。このインタフェースは、ロックの位置と所有権についての情報を返しません。


例 4–3 lockf によるプロセスの検査

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