1 /* $NetBSD: ibcs2_fcntl.c,v 1.33 2007/12/20 23:02:49 dsl Exp $ */
4 * Copyright (c) 1995 Scott Bartram
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ibcs2_fcntl.c,v 1.33 2007/12/20 23:02:49 dsl Exp $");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/namei.h>
39 #include <sys/filedesc.h>
40 #include <sys/ioctl.h>
41 #include <sys/kernel.h>
42 #include <sys/mount.h>
43 #include <sys/syscallargs.h>
44 #include <sys/vnode.h>
45 #include <sys/kauth.h>
47 #include <compat/ibcs2/ibcs2_types.h>
48 #include <compat/ibcs2/ibcs2_fcntl.h>
49 #include <compat/ibcs2/ibcs2_unistd.h>
50 #include <compat/ibcs2/ibcs2_signal.h>
51 #include <compat/ibcs2/ibcs2_syscallargs.h>
52 #include <compat/ibcs2/ibcs2_util.h>
54 static int cvt_o_flags(int);
55 static void cvt_flock2iflock(struct flock
*, struct ibcs2_flock
*);
56 static void cvt_iflock2flock(struct ibcs2_flock
*, struct flock
*);
57 static int ioflags2oflags(int);
58 static int oflags2ioflags(int);
61 cvt_o_flags(int flags
)
65 /* convert mode into NetBSD mode */
66 if (flags
& IBCS2_O_WRONLY
) r
|= O_WRONLY
;
67 if (flags
& IBCS2_O_RDWR
) r
|= O_RDWR
;
68 if (flags
& (IBCS2_O_NDELAY
| IBCS2_O_NONBLOCK
)) r
|= O_NONBLOCK
;
69 if (flags
& IBCS2_O_APPEND
) r
|= O_APPEND
;
70 if (flags
& IBCS2_O_SYNC
) r
|= O_FSYNC
;
71 if (flags
& IBCS2_O_CREAT
) r
|= O_CREAT
;
72 if (flags
& IBCS2_O_TRUNC
) r
|= O_TRUNC
;
73 if (flags
& IBCS2_O_EXCL
) r
|= O_EXCL
;
78 cvt_flock2iflock(struct flock
*flp
, struct ibcs2_flock
*iflp
)
80 switch (flp
->l_type
) {
82 iflp
->l_type
= IBCS2_F_RDLCK
;
85 iflp
->l_type
= IBCS2_F_WRLCK
;
88 iflp
->l_type
= IBCS2_F_UNLCK
;
91 iflp
->l_whence
= (short)flp
->l_whence
;
92 iflp
->l_start
= (ibcs2_off_t
)flp
->l_start
;
93 iflp
->l_len
= (ibcs2_off_t
)flp
->l_len
;
95 iflp
->l_pid
= (ibcs2_pid_t
)flp
->l_pid
;
99 cvt_iflock2flock(struct ibcs2_flock
*iflp
, struct flock
*flp
)
101 flp
->l_start
= (off_t
)iflp
->l_start
;
102 flp
->l_len
= (off_t
)iflp
->l_len
;
103 flp
->l_pid
= (pid_t
)iflp
->l_pid
;
104 switch (iflp
->l_type
) {
106 flp
->l_type
= F_RDLCK
;
109 flp
->l_type
= F_WRLCK
;
112 flp
->l_type
= F_UNLCK
;
115 flp
->l_whence
= iflp
->l_whence
;
118 /* convert iBCS2 mode into NetBSD mode */
120 ioflags2oflags(int flags
)
124 if (flags
& IBCS2_O_RDONLY
) r
|= O_RDONLY
;
125 if (flags
& IBCS2_O_WRONLY
) r
|= O_WRONLY
;
126 if (flags
& IBCS2_O_RDWR
) r
|= O_RDWR
;
127 if (flags
& IBCS2_O_NDELAY
) r
|= O_NONBLOCK
;
128 if (flags
& IBCS2_O_APPEND
) r
|= O_APPEND
;
129 if (flags
& IBCS2_O_SYNC
) r
|= O_FSYNC
;
130 if (flags
& IBCS2_O_NONBLOCK
) r
|= O_NONBLOCK
;
131 if (flags
& IBCS2_O_CREAT
) r
|= O_CREAT
;
132 if (flags
& IBCS2_O_TRUNC
) r
|= O_TRUNC
;
133 if (flags
& IBCS2_O_EXCL
) r
|= O_EXCL
;
134 if (flags
& IBCS2_O_NOCTTY
) r
|= O_NOCTTY
;
138 /* convert NetBSD mode into iBCS2 mode */
140 oflags2ioflags(int flags
)
144 if (flags
& O_RDONLY
) r
|= IBCS2_O_RDONLY
;
145 if (flags
& O_WRONLY
) r
|= IBCS2_O_WRONLY
;
146 if (flags
& O_RDWR
) r
|= IBCS2_O_RDWR
;
147 if (flags
& O_NDELAY
) r
|= IBCS2_O_NONBLOCK
;
148 if (flags
& O_APPEND
) r
|= IBCS2_O_APPEND
;
149 if (flags
& O_FSYNC
) r
|= IBCS2_O_SYNC
;
150 if (flags
& O_NONBLOCK
) r
|= IBCS2_O_NONBLOCK
;
151 if (flags
& O_CREAT
) r
|= IBCS2_O_CREAT
;
152 if (flags
& O_TRUNC
) r
|= IBCS2_O_TRUNC
;
153 if (flags
& O_EXCL
) r
|= IBCS2_O_EXCL
;
154 if (flags
& O_NOCTTY
) r
|= IBCS2_O_NOCTTY
;
159 ibcs2_sys_open(struct lwp
*l
, const struct ibcs2_sys_open_args
*uap
, register_t
*retval
)
162 syscallarg(char *) path;
163 syscallarg(int) flags;
164 syscallarg(int) mode;
166 struct proc
*p
= l
->l_proc
;
167 struct sys_open_args bsd_ua
;
168 int noctty
= SCARG(uap
, flags
) & IBCS2_O_NOCTTY
;
171 SCARG(&bsd_ua
, path
) = SCARG(uap
, path
);
172 SCARG(&bsd_ua
, flags
) = cvt_o_flags(SCARG(uap
, flags
));
173 SCARG(&bsd_ua
, mode
) = SCARG(uap
, mode
);
174 ret
= sys_open(l
, &bsd_ua
, retval
);
176 if (!ret
&& !noctty
&& SESS_LEADER(p
) && !(p
->p_lflag
& PL_CONTROLT
)) {
179 if ((fp
= fd_getfile(*retval
)) != NULL
) {
180 /* ignore any error, just give it a try */
181 if (fp
->f_type
== DTYPE_VNODE
)
182 (fp
->f_ops
->fo_ioctl
)(fp
, TIOCSCTTY
, NULL
);
190 ibcs2_sys_creat(struct lwp
*l
, const struct ibcs2_sys_creat_args
*uap
, register_t
*retval
)
193 syscallarg(char *) path;
194 syscallarg(int) mode;
196 struct sys_open_args cup
;
198 SCARG(&cup
, path
) = SCARG(uap
, path
);
199 SCARG(&cup
, mode
) = SCARG(uap
, mode
);
200 SCARG(&cup
, flags
) = O_WRONLY
| O_CREAT
| O_TRUNC
;
201 return sys_open(l
, &cup
, retval
);
205 ibcs2_sys_access(struct lwp
*l
, const struct ibcs2_sys_access_args
*uap
, register_t
*retval
)
208 syscallarg(char *) path;
209 syscallarg(int) flags;
211 struct sys_access_args cup
;
213 SCARG(&cup
, path
) = SCARG(uap
, path
);
214 SCARG(&cup
, flags
) = SCARG(uap
, flags
);
215 return sys_access(l
, &cup
, retval
);
219 ibcs2_sys_eaccess(struct lwp
*l
, const struct ibcs2_sys_eaccess_args
*uap
, register_t
*retval
)
222 syscallarg(char *) path;
223 syscallarg(int) flags;
229 NDINIT(&nd
, LOOKUP
, FOLLOW
| LOCKLEAF
| TRYEMULROOT
, UIO_USERSPACE
,
231 if ((error
= namei(&nd
)) != 0)
235 /* Flags == 0 means only check for existence. */
236 if (SCARG(uap
, flags
)) {
238 if (SCARG(uap
, flags
) & IBCS2_R_OK
)
240 if (SCARG(uap
, flags
) & IBCS2_W_OK
)
242 if (SCARG(uap
, flags
) & IBCS2_X_OK
)
244 if ((flags
& VWRITE
) == 0 || (error
= vn_writechk(vp
)) == 0)
245 error
= VOP_ACCESS(vp
, flags
, l
->l_cred
);
252 ibcs2_sys_fcntl(struct lwp
*l
, const struct ibcs2_sys_fcntl_args
*uap
, register_t
*retval
)
257 syscallarg(char *) arg;
259 struct sys_fcntl_args fa
;
261 struct ibcs2_flock ifl
;
265 switch(SCARG(uap
, cmd
)) {
267 SCARG(&fa
, fd
) = SCARG(uap
, fd
);
268 SCARG(&fa
, cmd
) = F_DUPFD
;
269 SCARG(&fa
, arg
) = SCARG(uap
, arg
);
270 return sys_fcntl(l
, &fa
, retval
);
272 SCARG(&fa
, fd
) = SCARG(uap
, fd
);
273 SCARG(&fa
, cmd
) = F_GETFD
;
274 SCARG(&fa
, arg
) = SCARG(uap
, arg
);
275 return sys_fcntl(l
, &fa
, retval
);
277 SCARG(&fa
, fd
) = SCARG(uap
, fd
);
278 SCARG(&fa
, cmd
) = F_SETFD
;
279 SCARG(&fa
, arg
) = SCARG(uap
, arg
);
280 return sys_fcntl(l
, &fa
, retval
);
282 SCARG(&fa
, fd
) = SCARG(uap
, fd
);
283 SCARG(&fa
, cmd
) = F_GETFL
;
284 SCARG(&fa
, arg
) = SCARG(uap
, arg
);
285 error
= sys_fcntl(l
, &fa
, retval
);
288 *retval
= oflags2ioflags(*retval
);
291 SCARG(&fa
, fd
) = SCARG(uap
, fd
);
292 SCARG(&fa
, cmd
) = F_SETFL
;
293 SCARG(&fa
, arg
) = (void *)ioflags2oflags((int) SCARG(uap
, arg
));
294 return sys_fcntl(l
, &fa
, retval
);
305 error
= copyin(SCARG(uap
, arg
), &ifl
, ibcs2_flock_len
);
308 cvt_iflock2flock(&ifl
, &fl
);
309 error
= do_fcntl_lock(SCARG(uap
, fd
), cmd
, &fl
);
310 if (cmd
!= F_GETLK
|| error
!= 0)
312 cvt_flock2iflock(&fl
, &ifl
);
313 return copyout(&ifl
, SCARG(uap
, arg
), ibcs2_flock_len
);