1*cf84ac9aSAndroid Build Coastguard Worker /*
2*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2015-2016 Dmitry V. Levin <[email protected]>
3*cf84ac9aSAndroid Build Coastguard Worker * Copyright (c) 2015-2018 The strace developers.
4*cf84ac9aSAndroid Build Coastguard Worker * All rights reserved.
5*cf84ac9aSAndroid Build Coastguard Worker *
6*cf84ac9aSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
7*cf84ac9aSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
8*cf84ac9aSAndroid Build Coastguard Worker * are met:
9*cf84ac9aSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
10*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
11*cf84ac9aSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
12*cf84ac9aSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
13*cf84ac9aSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
14*cf84ac9aSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
15*cf84ac9aSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
16*cf84ac9aSAndroid Build Coastguard Worker *
17*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18*cf84ac9aSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19*cf84ac9aSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*cf84ac9aSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21*cf84ac9aSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22*cf84ac9aSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23*cf84ac9aSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24*cf84ac9aSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25*cf84ac9aSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26*cf84ac9aSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*cf84ac9aSAndroid Build Coastguard Worker */
28*cf84ac9aSAndroid Build Coastguard Worker
29*cf84ac9aSAndroid Build Coastguard Worker #include <stdio.h>
30*cf84ac9aSAndroid Build Coastguard Worker #include <stdint.h>
31*cf84ac9aSAndroid Build Coastguard Worker #include <stdlib.h>
32*cf84ac9aSAndroid Build Coastguard Worker #include <string.h>
33*cf84ac9aSAndroid Build Coastguard Worker #include <unistd.h>
34*cf84ac9aSAndroid Build Coastguard Worker #include <assert.h>
35*cf84ac9aSAndroid Build Coastguard Worker #include "flock.h"
36*cf84ac9aSAndroid Build Coastguard Worker
37*cf84ac9aSAndroid Build Coastguard Worker #define FILE_LEN 4096
38*cf84ac9aSAndroid Build Coastguard Worker
39*cf84ac9aSAndroid Build Coastguard Worker #define TEST_FLOCK_EINVAL(cmd) test_flock_einval(cmd, #cmd)
40*cf84ac9aSAndroid Build Coastguard Worker #define TEST_FLOCK64_EINVAL(cmd) test_flock64_einval(cmd, #cmd)
41*cf84ac9aSAndroid Build Coastguard Worker
42*cf84ac9aSAndroid Build Coastguard Worker #ifdef HAVE_TYPEOF
43*cf84ac9aSAndroid Build Coastguard Worker # define TYPEOF_FLOCK_OFF_T typeof(((struct_kernel_flock *) NULL)->l_len)
44*cf84ac9aSAndroid Build Coastguard Worker #else
45*cf84ac9aSAndroid Build Coastguard Worker # define TYPEOF_FLOCK_OFF_T off_t
46*cf84ac9aSAndroid Build Coastguard Worker #endif
47*cf84ac9aSAndroid Build Coastguard Worker
48*cf84ac9aSAndroid Build Coastguard Worker static const char *errstr;
49*cf84ac9aSAndroid Build Coastguard Worker
50*cf84ac9aSAndroid Build Coastguard Worker static long
invoke_test_syscall(const unsigned int fd,const unsigned int cmd,void * const p)51*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(const unsigned int fd, const unsigned int cmd, void *const p)
52*cf84ac9aSAndroid Build Coastguard Worker {
53*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t kfd = F8ILL_KULONG_MASK | fd;
54*cf84ac9aSAndroid Build Coastguard Worker const kernel_ulong_t op = F8ILL_KULONG_MASK | cmd;
55*cf84ac9aSAndroid Build Coastguard Worker
56*cf84ac9aSAndroid Build Coastguard Worker long rc = syscall(TEST_SYSCALL_NR, kfd, op, (uintptr_t) p);
57*cf84ac9aSAndroid Build Coastguard Worker errstr = sprintrc(rc);
58*cf84ac9aSAndroid Build Coastguard Worker return rc;
59*cf84ac9aSAndroid Build Coastguard Worker }
60*cf84ac9aSAndroid Build Coastguard Worker
61*cf84ac9aSAndroid Build Coastguard Worker static void
test_flock_einval(const int cmd,const char * name)62*cf84ac9aSAndroid Build Coastguard Worker test_flock_einval(const int cmd, const char *name)
63*cf84ac9aSAndroid Build Coastguard Worker {
64*cf84ac9aSAndroid Build Coastguard Worker TAIL_ALLOC_OBJECT_CONST_PTR(struct_kernel_flock, fl);
65*cf84ac9aSAndroid Build Coastguard Worker memset(fl, 0, sizeof(*fl));
66*cf84ac9aSAndroid Build Coastguard Worker fl->l_type = F_RDLCK;
67*cf84ac9aSAndroid Build Coastguard Worker fl->l_start = (TYPEOF_FLOCK_OFF_T) 0xdefaced1facefeedULL;
68*cf84ac9aSAndroid Build Coastguard Worker fl->l_len = (TYPEOF_FLOCK_OFF_T) 0xdefaced2cafef00dULL;
69*cf84ac9aSAndroid Build Coastguard Worker
70*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, cmd, fl);
71*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, %s, {l_type=F_RDLCK, l_whence=SEEK_SET"
72*cf84ac9aSAndroid Build Coastguard Worker ", l_start=%jd, l_len=%jd}) = %s\n", TEST_SYSCALL_STR, name,
73*cf84ac9aSAndroid Build Coastguard Worker (intmax_t) fl->l_start, (intmax_t) fl->l_len, errstr);
74*cf84ac9aSAndroid Build Coastguard Worker
75*cf84ac9aSAndroid Build Coastguard Worker void *const bad_addr = (void *) fl + 1;
76*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, cmd, bad_addr);
77*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, %s, %p) = %s\n",
78*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, name, bad_addr, errstr);
79*cf84ac9aSAndroid Build Coastguard Worker }
80*cf84ac9aSAndroid Build Coastguard Worker
81*cf84ac9aSAndroid Build Coastguard Worker /*
82*cf84ac9aSAndroid Build Coastguard Worker * This function is not declared static to avoid potential
83*cf84ac9aSAndroid Build Coastguard Worker * "defined but not used" warning when included by fcntl.c
84*cf84ac9aSAndroid Build Coastguard Worker */
85*cf84ac9aSAndroid Build Coastguard Worker void
test_flock64_einval(const int cmd,const char * name)86*cf84ac9aSAndroid Build Coastguard Worker test_flock64_einval(const int cmd, const char *name)
87*cf84ac9aSAndroid Build Coastguard Worker {
88*cf84ac9aSAndroid Build Coastguard Worker TAIL_ALLOC_OBJECT_CONST_PTR(struct_kernel_flock64, fl);
89*cf84ac9aSAndroid Build Coastguard Worker memset(fl, 0, sizeof(*fl));
90*cf84ac9aSAndroid Build Coastguard Worker fl->l_type = F_RDLCK;
91*cf84ac9aSAndroid Build Coastguard Worker fl->l_start = (TYPEOF_FLOCK_OFF_T) 0xdefaced1facefeedULL;
92*cf84ac9aSAndroid Build Coastguard Worker fl->l_len = (TYPEOF_FLOCK_OFF_T) 0xdefaced2cafef00dULL;
93*cf84ac9aSAndroid Build Coastguard Worker
94*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, cmd, fl);
95*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, %s, {l_type=F_RDLCK, l_whence=SEEK_SET"
96*cf84ac9aSAndroid Build Coastguard Worker ", l_start=%jd, l_len=%jd}) = %s\n", TEST_SYSCALL_STR, name,
97*cf84ac9aSAndroid Build Coastguard Worker (intmax_t) fl->l_start, (intmax_t) fl->l_len, errstr);
98*cf84ac9aSAndroid Build Coastguard Worker
99*cf84ac9aSAndroid Build Coastguard Worker void *const bad_addr = (void *) fl + 1;
100*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, cmd, bad_addr);
101*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, %s, %p) = %s\n",
102*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, name, bad_addr, errstr);
103*cf84ac9aSAndroid Build Coastguard Worker }
104*cf84ac9aSAndroid Build Coastguard Worker
105*cf84ac9aSAndroid Build Coastguard Worker static void
test_flock(void)106*cf84ac9aSAndroid Build Coastguard Worker test_flock(void)
107*cf84ac9aSAndroid Build Coastguard Worker {
108*cf84ac9aSAndroid Build Coastguard Worker TEST_FLOCK_EINVAL(F_SETLK);
109*cf84ac9aSAndroid Build Coastguard Worker TEST_FLOCK_EINVAL(F_SETLKW);
110*cf84ac9aSAndroid Build Coastguard Worker
111*cf84ac9aSAndroid Build Coastguard Worker TAIL_ALLOC_OBJECT_CONST_PTR(struct_kernel_flock, fl);
112*cf84ac9aSAndroid Build Coastguard Worker memset(fl, 0, sizeof(*fl));
113*cf84ac9aSAndroid Build Coastguard Worker fl->l_type = F_RDLCK;
114*cf84ac9aSAndroid Build Coastguard Worker fl->l_len = FILE_LEN;
115*cf84ac9aSAndroid Build Coastguard Worker
116*cf84ac9aSAndroid Build Coastguard Worker long rc = invoke_test_syscall(0, F_SETLK, fl);
117*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, F_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET"
118*cf84ac9aSAndroid Build Coastguard Worker ", l_start=0, l_len=%d}) = %s\n",
119*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, FILE_LEN, errstr);
120*cf84ac9aSAndroid Build Coastguard Worker if (rc)
121*cf84ac9aSAndroid Build Coastguard Worker return;
122*cf84ac9aSAndroid Build Coastguard Worker
123*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, F_GETLK, fl);
124*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, F_GETLK, {l_type=F_UNLCK, l_whence=SEEK_SET"
125*cf84ac9aSAndroid Build Coastguard Worker ", l_start=0, l_len=%d, l_pid=0}) = 0\n",
126*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, FILE_LEN);
127*cf84ac9aSAndroid Build Coastguard Worker
128*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, F_SETLKW, fl);
129*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, F_SETLKW, {l_type=F_UNLCK, l_whence=SEEK_SET"
130*cf84ac9aSAndroid Build Coastguard Worker ", l_start=0, l_len=%d}) = 0\n",
131*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, FILE_LEN);
132*cf84ac9aSAndroid Build Coastguard Worker }
133*cf84ac9aSAndroid Build Coastguard Worker
134*cf84ac9aSAndroid Build Coastguard Worker static void
test_flock64_ofd(void)135*cf84ac9aSAndroid Build Coastguard Worker test_flock64_ofd(void)
136*cf84ac9aSAndroid Build Coastguard Worker {
137*cf84ac9aSAndroid Build Coastguard Worker #if defined F_OFD_GETLK && defined F_OFD_SETLK && defined F_OFD_SETLKW
138*cf84ac9aSAndroid Build Coastguard Worker TEST_FLOCK64_EINVAL(F_OFD_SETLK);
139*cf84ac9aSAndroid Build Coastguard Worker TEST_FLOCK64_EINVAL(F_OFD_SETLKW);
140*cf84ac9aSAndroid Build Coastguard Worker
141*cf84ac9aSAndroid Build Coastguard Worker TAIL_ALLOC_OBJECT_CONST_PTR(struct_kernel_flock64, fl);
142*cf84ac9aSAndroid Build Coastguard Worker memset(fl, 0, sizeof(*fl));
143*cf84ac9aSAndroid Build Coastguard Worker fl->l_type = F_RDLCK;
144*cf84ac9aSAndroid Build Coastguard Worker fl->l_len = FILE_LEN;
145*cf84ac9aSAndroid Build Coastguard Worker
146*cf84ac9aSAndroid Build Coastguard Worker long rc = invoke_test_syscall(0, F_OFD_SETLK, fl);
147*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, F_OFD_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET"
148*cf84ac9aSAndroid Build Coastguard Worker ", l_start=0, l_len=%d}) = %s\n",
149*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, FILE_LEN, errstr);
150*cf84ac9aSAndroid Build Coastguard Worker if (rc)
151*cf84ac9aSAndroid Build Coastguard Worker return;
152*cf84ac9aSAndroid Build Coastguard Worker
153*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, F_OFD_GETLK, fl);
154*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, F_OFD_GETLK, {l_type=F_UNLCK, l_whence=SEEK_SET"
155*cf84ac9aSAndroid Build Coastguard Worker ", l_start=0, l_len=%d, l_pid=0}) = 0\n",
156*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, FILE_LEN);
157*cf84ac9aSAndroid Build Coastguard Worker
158*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, F_OFD_SETLKW, fl);
159*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, F_OFD_SETLKW, {l_type=F_UNLCK, l_whence=SEEK_SET"
160*cf84ac9aSAndroid Build Coastguard Worker ", l_start=0, l_len=%d}) = 0\n",
161*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, FILE_LEN);
162*cf84ac9aSAndroid Build Coastguard Worker #endif /* F_OFD_GETLK && F_OFD_SETLK && F_OFD_SETLKW */
163*cf84ac9aSAndroid Build Coastguard Worker }
164*cf84ac9aSAndroid Build Coastguard Worker
165*cf84ac9aSAndroid Build Coastguard Worker static void test_flock64_lk64(void);
166*cf84ac9aSAndroid Build Coastguard Worker
167*cf84ac9aSAndroid Build Coastguard Worker static void
test_flock64(void)168*cf84ac9aSAndroid Build Coastguard Worker test_flock64(void)
169*cf84ac9aSAndroid Build Coastguard Worker {
170*cf84ac9aSAndroid Build Coastguard Worker test_flock64_ofd();
171*cf84ac9aSAndroid Build Coastguard Worker test_flock64_lk64();
172*cf84ac9aSAndroid Build Coastguard Worker }
173*cf84ac9aSAndroid Build Coastguard Worker
174*cf84ac9aSAndroid Build Coastguard Worker /*
175*cf84ac9aSAndroid Build Coastguard Worker * F_[GS]ETOWN_EX had conflicting values with F_[SG]ETLK64
176*cf84ac9aSAndroid Build Coastguard Worker * in kernel revisions v2.6.32-rc1~96..v2.6.32-rc7~23.
177*cf84ac9aSAndroid Build Coastguard Worker */
178*cf84ac9aSAndroid Build Coastguard Worker #undef TEST_F_OWNER_EX
179*cf84ac9aSAndroid Build Coastguard Worker #if defined F_GETOWN_EX && defined F_SETOWN_EX \
180*cf84ac9aSAndroid Build Coastguard Worker && (F_GETOWN_EX != F_SETLK64) && (F_SETOWN_EX != F_GETLK64)
181*cf84ac9aSAndroid Build Coastguard Worker # define TEST_F_OWNER_EX
182*cf84ac9aSAndroid Build Coastguard Worker #endif
183*cf84ac9aSAndroid Build Coastguard Worker
184*cf84ac9aSAndroid Build Coastguard Worker #ifdef TEST_F_OWNER_EX
185*cf84ac9aSAndroid Build Coastguard Worker # include "f_owner_ex.h"
186*cf84ac9aSAndroid Build Coastguard Worker
187*cf84ac9aSAndroid Build Coastguard Worker static long
test_f_owner_ex_type_pid(const int cmd,const char * const cmd_name,const int type,const char * const type_name,pid_t pid)188*cf84ac9aSAndroid Build Coastguard Worker test_f_owner_ex_type_pid(const int cmd, const char *const cmd_name,
189*cf84ac9aSAndroid Build Coastguard Worker const int type, const char *const type_name,
190*cf84ac9aSAndroid Build Coastguard Worker pid_t pid)
191*cf84ac9aSAndroid Build Coastguard Worker {
192*cf84ac9aSAndroid Build Coastguard Worker TAIL_ALLOC_OBJECT_CONST_PTR(struct_kernel_f_owner_ex, fo);
193*cf84ac9aSAndroid Build Coastguard Worker
194*cf84ac9aSAndroid Build Coastguard Worker fo->type = type;
195*cf84ac9aSAndroid Build Coastguard Worker fo->pid = pid;
196*cf84ac9aSAndroid Build Coastguard Worker long rc = invoke_test_syscall(0, cmd, fo);
197*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, %s, {type=%s, pid=%d}) = %s\n",
198*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, cmd_name, type_name, fo->pid, errstr);
199*cf84ac9aSAndroid Build Coastguard Worker
200*cf84ac9aSAndroid Build Coastguard Worker void *bad_addr = (void *) fo + 1;
201*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(0, cmd, bad_addr);
202*cf84ac9aSAndroid Build Coastguard Worker printf("%s(0, %s, %p) = %s\n",
203*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, cmd_name, bad_addr, errstr);
204*cf84ac9aSAndroid Build Coastguard Worker
205*cf84ac9aSAndroid Build Coastguard Worker return rc;
206*cf84ac9aSAndroid Build Coastguard Worker }
207*cf84ac9aSAndroid Build Coastguard Worker
208*cf84ac9aSAndroid Build Coastguard Worker static void
test_f_owner_ex_umove_or_printaddr(const int type,const char * const type_name,pid_t pid)209*cf84ac9aSAndroid Build Coastguard Worker test_f_owner_ex_umove_or_printaddr(const int type, const char *const type_name,
210*cf84ac9aSAndroid Build Coastguard Worker pid_t pid)
211*cf84ac9aSAndroid Build Coastguard Worker {
212*cf84ac9aSAndroid Build Coastguard Worker long rc = test_f_owner_ex_type_pid(ARG_STR(F_SETOWN_EX),
213*cf84ac9aSAndroid Build Coastguard Worker type, type_name, pid);
214*cf84ac9aSAndroid Build Coastguard Worker if (!rc)
215*cf84ac9aSAndroid Build Coastguard Worker test_f_owner_ex_type_pid(ARG_STR(F_GETOWN_EX),
216*cf84ac9aSAndroid Build Coastguard Worker type, type_name, pid);
217*cf84ac9aSAndroid Build Coastguard Worker }
218*cf84ac9aSAndroid Build Coastguard Worker
219*cf84ac9aSAndroid Build Coastguard Worker static void
test_f_owner_ex(void)220*cf84ac9aSAndroid Build Coastguard Worker test_f_owner_ex(void)
221*cf84ac9aSAndroid Build Coastguard Worker {
222*cf84ac9aSAndroid Build Coastguard Worker static const struct {
223*cf84ac9aSAndroid Build Coastguard Worker int type;
224*cf84ac9aSAndroid Build Coastguard Worker const char *type_name;
225*cf84ac9aSAndroid Build Coastguard Worker pid_t pid[2];
226*cf84ac9aSAndroid Build Coastguard Worker } a[] = {
227*cf84ac9aSAndroid Build Coastguard Worker { ARG_STR(F_OWNER_TID), { 1234567890, 20 } },
228*cf84ac9aSAndroid Build Coastguard Worker { ARG_STR(F_OWNER_PID), { 1298126790, 30 } },
229*cf84ac9aSAndroid Build Coastguard Worker { ARG_STR(F_OWNER_PGRP), { 1294567890, 40 } }
230*cf84ac9aSAndroid Build Coastguard Worker };
231*cf84ac9aSAndroid Build Coastguard Worker
232*cf84ac9aSAndroid Build Coastguard Worker for (unsigned int i = 0; i < ARRAY_SIZE(a); i++) {
233*cf84ac9aSAndroid Build Coastguard Worker for (unsigned int j = 0; j < ARRAY_SIZE(a[0].pid); j++) {
234*cf84ac9aSAndroid Build Coastguard Worker test_f_owner_ex_umove_or_printaddr(a[i].type,
235*cf84ac9aSAndroid Build Coastguard Worker a[i].type_name,
236*cf84ac9aSAndroid Build Coastguard Worker a[i].pid[j]);
237*cf84ac9aSAndroid Build Coastguard Worker }
238*cf84ac9aSAndroid Build Coastguard Worker }
239*cf84ac9aSAndroid Build Coastguard Worker }
240*cf84ac9aSAndroid Build Coastguard Worker #endif /* TEST_F_OWNER_EX */
241*cf84ac9aSAndroid Build Coastguard Worker
242*cf84ac9aSAndroid Build Coastguard Worker struct fcntl_cmd_check {
243*cf84ac9aSAndroid Build Coastguard Worker int fd;
244*cf84ac9aSAndroid Build Coastguard Worker int cmd;
245*cf84ac9aSAndroid Build Coastguard Worker const char *cmd_str;
246*cf84ac9aSAndroid Build Coastguard Worker long arg;
247*cf84ac9aSAndroid Build Coastguard Worker const char *arg_str;
248*cf84ac9aSAndroid Build Coastguard Worker void (*print_flags)(long rc);
249*cf84ac9aSAndroid Build Coastguard Worker };
250*cf84ac9aSAndroid Build Coastguard Worker
251*cf84ac9aSAndroid Build Coastguard Worker static void
print_retval_flags(const struct fcntl_cmd_check * check,long rc)252*cf84ac9aSAndroid Build Coastguard Worker print_retval_flags(const struct fcntl_cmd_check *check, long rc)
253*cf84ac9aSAndroid Build Coastguard Worker {
254*cf84ac9aSAndroid Build Coastguard Worker if (check->print_flags) {
255*cf84ac9aSAndroid Build Coastguard Worker check->print_flags(rc);
256*cf84ac9aSAndroid Build Coastguard Worker } else {
257*cf84ac9aSAndroid Build Coastguard Worker printf("%s", errstr);
258*cf84ac9aSAndroid Build Coastguard Worker }
259*cf84ac9aSAndroid Build Coastguard Worker printf("\n");
260*cf84ac9aSAndroid Build Coastguard Worker }
261*cf84ac9aSAndroid Build Coastguard Worker
262*cf84ac9aSAndroid Build Coastguard Worker static void
test_other_set_cmd(const struct fcntl_cmd_check * check)263*cf84ac9aSAndroid Build Coastguard Worker test_other_set_cmd(const struct fcntl_cmd_check *check)
264*cf84ac9aSAndroid Build Coastguard Worker {
265*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(check->fd, check->cmd, (void *) check->arg);
266*cf84ac9aSAndroid Build Coastguard Worker printf("%s(%d, %s, %s) = %s\n",
267*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, check->fd,
268*cf84ac9aSAndroid Build Coastguard Worker check->cmd_str, check->arg_str, errstr);
269*cf84ac9aSAndroid Build Coastguard Worker
270*cf84ac9aSAndroid Build Coastguard Worker /* bad file fd */
271*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(-1, check->cmd, (void *) check->arg);
272*cf84ac9aSAndroid Build Coastguard Worker printf("%s(-1, %s, %s) = %s\n",
273*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, check->cmd_str,
274*cf84ac9aSAndroid Build Coastguard Worker check->arg_str, errstr);
275*cf84ac9aSAndroid Build Coastguard Worker }
276*cf84ac9aSAndroid Build Coastguard Worker
277*cf84ac9aSAndroid Build Coastguard Worker static void
test_other_get_cmd(const struct fcntl_cmd_check * check)278*cf84ac9aSAndroid Build Coastguard Worker test_other_get_cmd(const struct fcntl_cmd_check *check)
279*cf84ac9aSAndroid Build Coastguard Worker {
280*cf84ac9aSAndroid Build Coastguard Worker long rc = invoke_test_syscall(check->fd, check->cmd, NULL);
281*cf84ac9aSAndroid Build Coastguard Worker printf("%s(%d, %s) = ",
282*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, check->fd, check->cmd_str);
283*cf84ac9aSAndroid Build Coastguard Worker print_retval_flags(check, rc);
284*cf84ac9aSAndroid Build Coastguard Worker
285*cf84ac9aSAndroid Build Coastguard Worker /* bad file fd */
286*cf84ac9aSAndroid Build Coastguard Worker invoke_test_syscall(-1, check->cmd, NULL);
287*cf84ac9aSAndroid Build Coastguard Worker printf("%s(-1, %s) = %s\n",
288*cf84ac9aSAndroid Build Coastguard Worker TEST_SYSCALL_STR, check->cmd_str, errstr);
289*cf84ac9aSAndroid Build Coastguard Worker }
290*cf84ac9aSAndroid Build Coastguard Worker
291*cf84ac9aSAndroid Build Coastguard Worker static void
print_flags_getfd(long rc)292*cf84ac9aSAndroid Build Coastguard Worker print_flags_getfd(long rc)
293*cf84ac9aSAndroid Build Coastguard Worker {
294*cf84ac9aSAndroid Build Coastguard Worker assert(rc >= 0);
295*cf84ac9aSAndroid Build Coastguard Worker printf("%#lx%s", rc, rc & 1 ? " (flags FD_CLOEXEC)" : "");
296*cf84ac9aSAndroid Build Coastguard Worker }
297*cf84ac9aSAndroid Build Coastguard Worker
298*cf84ac9aSAndroid Build Coastguard Worker static void
print_flags_getsig(long rc)299*cf84ac9aSAndroid Build Coastguard Worker print_flags_getsig(long rc)
300*cf84ac9aSAndroid Build Coastguard Worker {
301*cf84ac9aSAndroid Build Coastguard Worker assert(rc >= 0);
302*cf84ac9aSAndroid Build Coastguard Worker
303*cf84ac9aSAndroid Build Coastguard Worker if (!rc) {
304*cf84ac9aSAndroid Build Coastguard Worker printf("%ld", rc);
305*cf84ac9aSAndroid Build Coastguard Worker } else {
306*cf84ac9aSAndroid Build Coastguard Worker printf("%ld (%s)", rc, signal2name((int) rc));
307*cf84ac9aSAndroid Build Coastguard Worker }
308*cf84ac9aSAndroid Build Coastguard Worker }
309*cf84ac9aSAndroid Build Coastguard Worker
310*cf84ac9aSAndroid Build Coastguard Worker static void
print_flags_getlease(long rc)311*cf84ac9aSAndroid Build Coastguard Worker print_flags_getlease(long rc)
312*cf84ac9aSAndroid Build Coastguard Worker {
313*cf84ac9aSAndroid Build Coastguard Worker assert(rc >= 0);
314*cf84ac9aSAndroid Build Coastguard Worker const char *text;
315*cf84ac9aSAndroid Build Coastguard Worker
316*cf84ac9aSAndroid Build Coastguard Worker switch (rc) {
317*cf84ac9aSAndroid Build Coastguard Worker case F_RDLCK:
318*cf84ac9aSAndroid Build Coastguard Worker text = "F_RDLCK";
319*cf84ac9aSAndroid Build Coastguard Worker break;
320*cf84ac9aSAndroid Build Coastguard Worker case F_WRLCK:
321*cf84ac9aSAndroid Build Coastguard Worker text = "F_WRLCK";
322*cf84ac9aSAndroid Build Coastguard Worker break;
323*cf84ac9aSAndroid Build Coastguard Worker case F_UNLCK:
324*cf84ac9aSAndroid Build Coastguard Worker text = "F_UNLCK";
325*cf84ac9aSAndroid Build Coastguard Worker break;
326*cf84ac9aSAndroid Build Coastguard Worker default:
327*cf84ac9aSAndroid Build Coastguard Worker error_msg_and_fail("fcntl returned %#lx, does the"
328*cf84ac9aSAndroid Build Coastguard Worker " test have to be updated?", rc);
329*cf84ac9aSAndroid Build Coastguard Worker }
330*cf84ac9aSAndroid Build Coastguard Worker printf("%#lx (%s)", rc, text);
331*cf84ac9aSAndroid Build Coastguard Worker }
332*cf84ac9aSAndroid Build Coastguard Worker
333*cf84ac9aSAndroid Build Coastguard Worker static void
test_fcntl_others(void)334*cf84ac9aSAndroid Build Coastguard Worker test_fcntl_others(void)
335*cf84ac9aSAndroid Build Coastguard Worker {
336*cf84ac9aSAndroid Build Coastguard Worker static const struct fcntl_cmd_check set_checks[] = {
337*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_SETFD), ARG_STR(FD_CLOEXEC) },
338*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_SETOWN), ARG_STR(20) },
339*cf84ac9aSAndroid Build Coastguard Worker #ifdef F_SETPIPE_SZ
340*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_SETPIPE_SZ), ARG_STR(4097) },
341*cf84ac9aSAndroid Build Coastguard Worker #endif
342*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_DUPFD), ARG_STR(0) },
343*cf84ac9aSAndroid Build Coastguard Worker #ifdef F_DUPFD_CLOEXEC
344*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_DUPFD_CLOEXEC), ARG_STR(0) },
345*cf84ac9aSAndroid Build Coastguard Worker #endif
346*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_SETFL), ARG_STR(O_RDWR|O_LARGEFILE) },
347*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_NOTIFY), ARG_STR(DN_ACCESS) },
348*cf84ac9aSAndroid Build Coastguard Worker { 1, ARG_STR(F_SETLEASE), ARG_STR(F_RDLCK) },
349*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_SETSIG), 0, "SIG_0" },
350*cf84ac9aSAndroid Build Coastguard Worker { 1, ARG_STR(F_SETSIG), 1, "SIGHUP" }
351*cf84ac9aSAndroid Build Coastguard Worker };
352*cf84ac9aSAndroid Build Coastguard Worker for (unsigned int i = 0; i < ARRAY_SIZE(set_checks); i++) {
353*cf84ac9aSAndroid Build Coastguard Worker test_other_set_cmd(set_checks + i);
354*cf84ac9aSAndroid Build Coastguard Worker }
355*cf84ac9aSAndroid Build Coastguard Worker
356*cf84ac9aSAndroid Build Coastguard Worker static const struct fcntl_cmd_check get_checks[] = {
357*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_GETFD), .print_flags = print_flags_getfd },
358*cf84ac9aSAndroid Build Coastguard Worker { 1, ARG_STR(F_GETFD), .print_flags = print_flags_getfd },
359*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_GETOWN) },
360*cf84ac9aSAndroid Build Coastguard Worker #ifdef F_GETPIPE_SZ
361*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_GETPIPE_SZ) },
362*cf84ac9aSAndroid Build Coastguard Worker #endif
363*cf84ac9aSAndroid Build Coastguard Worker { 1, ARG_STR(F_GETLEASE), .print_flags = print_flags_getlease },
364*cf84ac9aSAndroid Build Coastguard Worker { 0, ARG_STR(F_GETSIG), .print_flags = print_flags_getsig },
365*cf84ac9aSAndroid Build Coastguard Worker { 1, ARG_STR(F_GETSIG), .print_flags = print_flags_getsig }
366*cf84ac9aSAndroid Build Coastguard Worker };
367*cf84ac9aSAndroid Build Coastguard Worker for (unsigned int j = 0; j < ARRAY_SIZE(get_checks); j++) {
368*cf84ac9aSAndroid Build Coastguard Worker test_other_get_cmd(get_checks + j);
369*cf84ac9aSAndroid Build Coastguard Worker }
370*cf84ac9aSAndroid Build Coastguard Worker }
371*cf84ac9aSAndroid Build Coastguard Worker
372*cf84ac9aSAndroid Build Coastguard Worker static void
create_sample(void)373*cf84ac9aSAndroid Build Coastguard Worker create_sample(void)
374*cf84ac9aSAndroid Build Coastguard Worker {
375*cf84ac9aSAndroid Build Coastguard Worker char fname[] = TEST_SYSCALL_STR "_XXXXXX";
376*cf84ac9aSAndroid Build Coastguard Worker
377*cf84ac9aSAndroid Build Coastguard Worker (void) close(0);
378*cf84ac9aSAndroid Build Coastguard Worker if (mkstemp(fname))
379*cf84ac9aSAndroid Build Coastguard Worker perror_msg_and_fail("mkstemp: %s", fname);
380*cf84ac9aSAndroid Build Coastguard Worker if (unlink(fname))
381*cf84ac9aSAndroid Build Coastguard Worker perror_msg_and_fail("unlink: %s", fname);
382*cf84ac9aSAndroid Build Coastguard Worker if (ftruncate(0, FILE_LEN))
383*cf84ac9aSAndroid Build Coastguard Worker perror_msg_and_fail("ftruncate");
384*cf84ac9aSAndroid Build Coastguard Worker }
385*cf84ac9aSAndroid Build Coastguard Worker
386*cf84ac9aSAndroid Build Coastguard Worker int
main(void)387*cf84ac9aSAndroid Build Coastguard Worker main(void)
388*cf84ac9aSAndroid Build Coastguard Worker {
389*cf84ac9aSAndroid Build Coastguard Worker create_sample();
390*cf84ac9aSAndroid Build Coastguard Worker test_flock();
391*cf84ac9aSAndroid Build Coastguard Worker test_flock64();
392*cf84ac9aSAndroid Build Coastguard Worker #ifdef TEST_F_OWNER_EX
393*cf84ac9aSAndroid Build Coastguard Worker test_f_owner_ex();
394*cf84ac9aSAndroid Build Coastguard Worker #endif
395*cf84ac9aSAndroid Build Coastguard Worker test_fcntl_others();
396*cf84ac9aSAndroid Build Coastguard Worker
397*cf84ac9aSAndroid Build Coastguard Worker puts("+++ exited with 0 +++");
398*cf84ac9aSAndroid Build Coastguard Worker return 0;
399*cf84ac9aSAndroid Build Coastguard Worker }
400