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 
sys_waitpid(pid_t pid,int * status,int options)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 
test_thread(void * thread_parm)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 */
main(int argc,char * argv[])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 }
123