f31105626c2521035269b731eab63e7233fd416f
[metze/samba/wip.git] / tests / fcntl_lock_thread.c
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
18 static 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
27 static 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 */
59 int 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 }