1/* test whether fcntl locking works on this system */ 2 3#if defined(HAVE_UNISTD_H) 4#include <unistd.h> 5#endif 6 7#include <stdio.h> 8#include <stdlib.h> 9#include <sys/types.h> 10 11#ifdef HAVE_FCNTL_H 12#include <fcntl.h> 13#endif 14 15#ifdef HAVE_SYS_FCNTL_H 16#include <sys/fcntl.h> 17#endif 18 19#ifdef HAVE_SYS_WAIT_H 20#include <sys/wait.h> 21#endif 22 23#include <errno.h> 24 25static int sys_waitpid(pid_t pid,int *status,int options) 26{ 27#ifdef HAVE_WAITPID 28 return waitpid(pid,status,options); 29#else /* USE_WAITPID */ 30 return wait4(pid, status, options, NULL); 31#endif /* USE_WAITPID */ 32} 33 34#define DATA "conftest.fcntl" 35 36#ifndef SEEK_SET 37#define SEEK_SET 0 38#endif 39 40/* lock a byte range in a open file */ 41int main(int argc, char *argv[]) 42{ 43 struct flock lock; 44 int fd, ret, status=1; 45 pid_t pid; 46 char *testdir = NULL; 47 48 testdir = getenv("TESTDIR"); 49 if (testdir) chdir(testdir); 50 51 alarm(10); 52 53 if (!(pid=fork())) { 54 sleep(2); 55 fd = open(DATA, O_RDONLY); 56 57 if (fd == -1) { 58 fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", 59 DATA, (int)errno); 60 exit(1); 61 } 62 63 lock.l_type = F_WRLCK; 64 lock.l_whence = SEEK_SET; 65 lock.l_start = 0; 66 lock.l_len = 4; 67 lock.l_pid = getpid(); 68 69 lock.l_type = F_WRLCK; 70 71 /* check if a lock applies */ 72 ret = fcntl(fd,F_GETLK,&lock); 73 74 if ((ret == -1) || 75 (lock.l_type == F_UNLCK)) { 76 fprintf(stderr,"ERROR: lock test failed (ret=%d errno=%d)\n", ret, (int)errno); 77 exit(1); 78 } else { 79 exit(0); 80 } 81 } 82 83 unlink(DATA); 84 fd = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600); 85 86 if (fd == -1) { 87 fprintf(stderr,"ERROR: failed to open %s (errno=%d)\n", 88 DATA, (int)errno); 89 exit(1); 90 } 91 92 lock.l_type = F_WRLCK; 93 lock.l_whence = SEEK_SET; 94 lock.l_start = 0; 95 lock.l_len = 4; 96 lock.l_pid = getpid(); 97 98 /* set a 4 byte write lock */ 99 fcntl(fd,F_SETLK,&lock); 100 101 sys_waitpid(pid, &status, 0); 102 103 unlink(DATA); 104 105#if defined(WIFEXITED) && defined(WEXITSTATUS) 106 if(WIFEXITED(status)) { 107 status = WEXITSTATUS(status); 108 } else { 109 status = 1; 110 } 111#else /* defined(WIFEXITED) && defined(WEXITSTATUS) */ 112 status = (status == 0) ? 0 : 1; 113#endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */ 114 115 if (status) { 116 fprintf(stderr,"ERROR: lock test failed with status=%d\n", 117 status); 118 } 119 120 exit(status); 121} 122