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