Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / ibcs2 / ibcs2_fcntl.c
bloba479fe4e7f8d7c2baa5c81e3d75582b77d4d79e4
1 /* $NetBSD: ibcs2_fcntl.c,v 1.33 2007/12/20 23:02:49 dsl Exp $ */
3 /*
4 * Copyright (c) 1995 Scott Bartram
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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>
36 #include <sys/proc.h>
37 #include <sys/file.h>
38 #include <sys/stat.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);
60 static int
61 cvt_o_flags(int flags)
63 int r = 0;
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;
74 return r;
77 static void
78 cvt_flock2iflock(struct flock *flp, struct ibcs2_flock *iflp)
80 switch (flp->l_type) {
81 case F_RDLCK:
82 iflp->l_type = IBCS2_F_RDLCK;
83 break;
84 case F_WRLCK:
85 iflp->l_type = IBCS2_F_WRLCK;
86 break;
87 case F_UNLCK:
88 iflp->l_type = IBCS2_F_UNLCK;
89 break;
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;
94 iflp->l_sysid = 0;
95 iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
98 static void
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) {
105 case IBCS2_F_RDLCK:
106 flp->l_type = F_RDLCK;
107 break;
108 case IBCS2_F_WRLCK:
109 flp->l_type = F_WRLCK;
110 break;
111 case IBCS2_F_UNLCK:
112 flp->l_type = F_UNLCK;
113 break;
115 flp->l_whence = iflp->l_whence;
118 /* convert iBCS2 mode into NetBSD mode */
119 static int
120 ioflags2oflags(int flags)
122 int r = 0;
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;
135 return r;
138 /* convert NetBSD mode into iBCS2 mode */
139 static int
140 oflags2ioflags(int flags)
142 int r = 0;
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;
155 return r;
159 ibcs2_sys_open(struct lwp *l, const struct ibcs2_sys_open_args *uap, register_t *retval)
161 /* {
162 syscallarg(char *) path;
163 syscallarg(int) flags;
164 syscallarg(int) mode;
165 } */
166 struct proc *p = l->l_proc;
167 struct sys_open_args bsd_ua;
168 int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
169 int ret;
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)) {
177 file_t *fp;
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);
183 fd_putfile(*retval);
186 return ret;
190 ibcs2_sys_creat(struct lwp *l, const struct ibcs2_sys_creat_args *uap, register_t *retval)
192 /* {
193 syscallarg(char *) path;
194 syscallarg(int) mode;
195 } */
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)
207 /* {
208 syscallarg(char *) path;
209 syscallarg(int) flags;
210 } */
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)
221 /* {
222 syscallarg(char *) path;
223 syscallarg(int) flags;
224 } */
225 struct vnode *vp;
226 int error, flags;
227 struct nameidata nd;
229 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, UIO_USERSPACE,
230 SCARG(uap, path));
231 if ((error = namei(&nd)) != 0)
232 return error;
233 vp = nd.ni_vp;
235 /* Flags == 0 means only check for existence. */
236 if (SCARG(uap, flags)) {
237 flags = 0;
238 if (SCARG(uap, flags) & IBCS2_R_OK)
239 flags |= VREAD;
240 if (SCARG(uap, flags) & IBCS2_W_OK)
241 flags |= VWRITE;
242 if (SCARG(uap, flags) & IBCS2_X_OK)
243 flags |= VEXEC;
244 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
245 error = VOP_ACCESS(vp, flags, l->l_cred);
247 vput(vp);
248 return error;
252 ibcs2_sys_fcntl(struct lwp *l, const struct ibcs2_sys_fcntl_args *uap, register_t *retval)
254 /* {
255 syscallarg(int) fd;
256 syscallarg(int) cmd;
257 syscallarg(char *) arg;
258 } */
259 struct sys_fcntl_args fa;
260 struct flock fl;
261 struct ibcs2_flock ifl;
262 int error;
263 int cmd;
265 switch(SCARG(uap, cmd)) {
266 case IBCS2_F_DUPFD:
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);
271 case IBCS2_F_GETFD:
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);
276 case IBCS2_F_SETFD:
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);
281 case IBCS2_F_GETFL:
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);
286 if (error)
287 return error;
288 *retval = oflags2ioflags(*retval);
289 return error;
290 case IBCS2_F_SETFL:
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);
296 case IBCS2_F_GETLK:
297 cmd = F_GETLK;
298 goto lock;
299 case IBCS2_F_SETLK:
300 cmd = F_SETLK;
301 goto lock;
302 case IBCS2_F_SETLKW:
303 cmd = F_SETLKW;
304 lock:
305 error = copyin(SCARG(uap, arg), &ifl, ibcs2_flock_len);
306 if (error)
307 return error;
308 cvt_iflock2flock(&ifl, &fl);
309 error = do_fcntl_lock(SCARG(uap, fd), cmd, &fl);
310 if (cmd != F_GETLK || error != 0)
311 return error;
312 cvt_flock2iflock(&fl, &ifl);
313 return copyout(&ifl, SCARG(uap, arg), ibcs2_flock_len);
315 default:
316 return ENOSYS;