bla
[slow/toolbox.git] / sharemode.c
1 #define _FILE_OFFSET_BITS 64
2 #define LINUX
3
4 #ifdef LINUX
5 #define _GNU_SOURCE
6 #endif
7
8 #include <sys/file.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <stdint.h>
15
16 #ifdef SOLARIS
17 static int test_shmd(int fd, int access, int deny)
18 {
19     int ret;
20     fshare_t sh;
21
22     sh.f_id = 1;
23     sh.f_access = access;
24     sh.f_deny = deny;
25
26     if ((ret = fcntl(fd, F_SHARE, &sh)) == 0)
27         fcntl(fd, F_UNSHARE, &sh);
28
29     return ret;
30 }
31
32 static int get_shmd(int fd, fshare_t *sh_rv)
33 {
34     fshare_t sh;
35     sh.f_id = 1;
36     sh_rv->f_access = 0;
37     sh_rv->f_deny = 0;
38
39     /* Check deny modes */
40     if (test_shmd(fd, F_RDACC, F_NODNY) != 0) {
41         perror("test_shmd(fd, F_RDACC, F_NODNY)");
42         sh_rv->f_deny |= F_RDDNY;
43     }
44     if (test_shmd(fd, F_WRACC, F_NODNY) != 0) {
45         perror("test_shmd(fd, F_WRACC, F_NODNY)");
46         sh_rv->f_deny |= F_WRDNY;
47     }
48
49     /* Check access modes */
50     if (test_shmd(fd, F_RWACC, F_RDDNY) != 0) {
51         perror("test_shmd(fd, 0, F_RDDNY)");
52         sh_rv->f_access |= F_RDACC;
53     }
54     if (test_shmd(fd, F_RWACC, F_WRDNY) != 0) {
55         perror("test_shmd(fd, 0, F_WRDNY)");
56         sh_rv->f_access |= F_WRACC;
57     }
58
59     return 0;
60 }
61 #endif
62
63 int main(int argc, char *argv[])
64 {
65 #ifdef SOLARIS
66     fshare_t share;
67 #endif
68     int fd;
69     pid_t pid;
70
71     if (argc != 2) {
72         printf("usage: %s FILE\n", argv[0]);
73         exit(1);
74     }
75
76     if ((pid = fork()) == -1) {
77         perror("fork");
78         exit(1);
79     }
80
81     if (pid == 0) {
82         /* Child */
83
84         sleep(5);
85
86 #ifdef SOLARIS
87         printf("Press <RETURN> to get sharemodee: ");
88         getchar();
89
90         get_shmd(fd, &share);
91
92         printf("Sharemodes:\n"
93                "\t F_RDACC: %s\n"
94                "\t F_WRACC: %s\n"
95                "\t F_RDDNY: %s\n"
96                "\t F_WRDNY: %s\n",
97                (share.f_access & F_RDACC) ? "yes" : "no",
98                (share.f_access & F_WRACC) ? "yes" : "no",
99                (share.f_deny & F_RDDNY) ? "yes" : "no",
100                (share.f_deny & F_WRDNY) ? "yes" : "no"
101             );
102 #endif
103 #ifdef LINUX
104         printf("Child: Press <RETURN> to set sharemode: ");
105         getchar();
106
107         int fd2;
108         if ((fd2 = open(argv[1], O_RDWR)) == -1) {
109             perror("open");
110             exit(1);
111         }
112
113         if (flock(fd2, LOCK_MAND | LOCK_READ | LOCK_NB) != 0) {
114             perror("flock");
115             exit(1);
116         }
117
118         printf("Child: got lock\n");
119 #endif
120
121         printf("Child: Press <RETURN> to exit");
122         getchar();
123         exit(0);
124     }
125
126     if ((fd = open(argv[1], O_RDWR)) == -1) {
127         perror("open");
128         exit(1);
129     }
130
131     printf("Parent: Press <RETURN> to set sharemode: ");
132     getchar();
133
134 #ifdef SOLARIS
135     share.f_access = F_RDACC;
136     share.f_deny = F_WRDNY;
137     share.f_id = 1;
138
139     if (fcntl(fd, F_SHARE, &share) == -1) {
140         perror("fcntl");
141         exit(1);
142     }
143 #endif
144 #ifdef LINUX
145     if (flock(fd, LOCK_MAND | LOCK_READ | LOCK_NB) != 0) {
146         perror("flock");
147         exit(1);
148     }
149 #endif
150
151     printf("Parent: got lock\n");
152
153     /* Parent */
154     if (waitpid(pid, NULL, 0) != pid) {
155         perror("waitpid");
156         exit(1);
157     }
158
159     close(fd);
160
161     return 0;
162 }