/* Test advisory file locking. This program is meant to be run under * strace(1) or equivalent. If its first argument is the word "fcntl" * it tests fcntl() locking, otherwise it tests flock() locking. * You are on your own for any other sort of locks and for portability * problems. * * Copyright 2011 Zack Weinberg. * Copying and distribution of this program, with or without modification, * are permitted in any medium without royalty provided the copyright * notice and this notice are preserved. This program is offered as-is, * without any warranty. */ #include #include #include #include #include #include #include #include static void alarm_handler(int unused) { } int main(int argc, char **argv) { struct sigaction sa; char template[] = "./tstlckXXXXXX"; int fd; sa.sa_handler = alarm_handler; sigfillset(&sa.sa_mask); sa.sa_flags = 0; /* _not_ SA_RESTART */ if (sigaction(SIGALRM, &sa, 0)) { fprintf(stderr, "sigaction(SIGALRM): %s\n", strerror(errno)); return 1; } fd = mkstemp(template); if (fd == -1) { fprintf(stderr, "mkstemp(%s): %s\n", template, strerror(errno)); return 1; } unlink(template); alarm(1); if (argc >= 2 && !strcmp(argv[1], "fcntl")) { struct flock lock; memset(&lock, 0, sizeof(struct flock)); lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; /* lock entire file */ if (fcntl(fd, F_SETLKW, &lock)) { fprintf(stderr, "setting fcntl lock: %s\n", strerror(errno)); return 1; } lock.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &lock)) { fprintf(stderr, "releasing fcntl lock: %s\n", strerror(errno)); return 1; } } else { if (flock(fd, LOCK_EX)) { fprintf(stderr, "setting flock lock: %s\n", strerror(errno)); return 1; } if (flock(fd, LOCK_UN)) { fprintf(stderr, "releasing flock lock: %s\n", strerror(errno)); return 1; } } return 0; }