Linux
Application Development |
Michael K. Johnson Erik W. Troan |
/* lock.c -- simple example of record locking */ #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> /* displays the message, and waits for the user to press return */ void waitforuser(char * message) { char buf[10]; printf("%s", message); fflush(stdout); fgets(buf, 9, stdin); } /* Gets a lock of the indicated type on the fd which is passed. The type should be either F_UNLCK, F_RDLCK, or F_WRLCK */ void getlock(int fd, int type) { struct flock lockinfo; char message[80]; /* we'll lock the entire file */ lockinfo.l_whence = SEEK_SET; lockinfo.l_start = 0; lockinfo.l_len = 0; /* keep trying until we succeed */ while (1) { lockinfo.l_type = type; /* if we get the lock, return immediately */ if (!fcntl(fd, F_SETLK, &lockinfo)) return; /* find out who holds the conflicting lock */ fcntl(fd, F_GETLK, &lockinfo); /* there's a chance the lock was freed between the F_SETLK and F_GETLK; make sure there's still a conflict before complaining about it */ if (lockinfo.l_type != F_UNLCK) { sprintf(message, "conflict with process %d... press " "<return> to retry:", lockinfo.l_pid); waitforuser(message); } } } int main(void) { int fd; /* set up a file to lock */ fd = open("testlockfile", O_RDWR | O_CREAT, 0666); if (fd < 0) { perror("open"); return 1; } printf("getting read lock\n"); getlock(fd, F_RDLCK); printf("got read lock\n"); waitforuser("\npress <return> to continue:"); printf("releasing lock\n"); getlock(fd, F_UNLCK); printf("getting write lock\n"); getlock(fd, F_WRLCK); printf("got write lock\n"); waitforuser("\npress <return> to exit:"); /* locks are released when the file is closed */ return 0; }