1#include <stdio.h> 2#include <fcntl.h> 3#include <unistd.h> 4#include <errno.h> 5#include <string.h> 6#include <sys/wait.h> 7#include "test.h" 8 9#define TEST(c, ...) ((c) ? 1 : (t_error(#c" failed: " __VA_ARGS__),0)) 10#define TESTE(c) (errno=0, TEST(c, "errno = %s\n", strerror(errno))) 11 12int main(void) 13{ 14 struct flock fl = {0}; 15 FILE *f; 16 int fd; 17 pid_t pid; 18 int status; 19 20 if (!TESTE(f=tmpfile())) return t_status; 21 fd = fileno(f); 22 23 fl.l_type = F_WRLCK; 24 fl.l_whence = SEEK_SET; 25 fl.l_start = 0; 26 fl.l_len = 0; 27 TESTE(fcntl(fd, F_SETLK, &fl)==0); 28 29 pid = fork(); 30 if (!pid) { 31 fl.l_type = F_RDLCK; 32 _exit(fcntl(fd, F_SETLK, &fl)==0 || 33 (errno!=EAGAIN && errno!=EACCES)); 34 } 35 while (waitpid(pid, &status, 0)<0 && errno==EINTR); 36 TEST(status==0, "lock failed to work\n"); 37 38 pid = fork(); 39 if (!pid) { 40 fl.l_type = F_WRLCK; 41 _exit(fcntl(fd, F_GETLK, &fl) || fl.l_pid != getppid()); 42 } 43 while (waitpid(pid, &status, 0)<0 && errno==EINTR); 44 TEST(status==0, "child failed to detect lock held by parent\n"); 45 46 fclose(f); 47 48 return t_status; 49} 50