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