Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / irix / irix_fcntl.c
blobe60c31fb0e9c831115cdc28ad39335d3410a15f6
1 /* $NetBSD: irix_fcntl.c,v 1.27 2009/08/31 05:34:16 dholland Exp $ */
3 /*-
4 * Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Emmanuel Dreyfus.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: irix_fcntl.c,v 1.27 2009/08/31 05:34:16 dholland Exp $");
35 #include <sys/types.h>
36 #include <sys/signal.h>
37 #include <sys/param.h>
38 #include <sys/mount.h>
39 #include <sys/proc.h>
40 #include <sys/conf.h>
41 #include <sys/malloc.h>
42 #include <sys/vnode.h>
43 #include <sys/file.h>
44 #include <sys/filedesc.h>
45 #include <sys/systm.h>
46 #include <sys/fcntl.h>
47 #include <sys/syscallargs.h>
49 #include <miscfs/specfs/specdev.h>
51 #include <compat/irix/irix_types.h>
52 #include <compat/irix/irix_signal.h>
53 #include <compat/irix/irix_fcntl.h>
54 #include <compat/irix/irix_usema.h>
55 #include <compat/irix/irix_syscallargs.h>
57 #include <compat/svr4/svr4_types.h>
58 #include <compat/svr4/svr4_signal.h>
59 #include <compat/svr4/svr4_ucontext.h>
60 #include <compat/svr4/svr4_lwp.h>
61 #include <compat/svr4/svr4_fcntl.h>
62 #include <compat/svr4/svr4_syscallargs.h>
64 static int fd_truncate(struct lwp *, int, int, off_t, register_t *);
65 static uintptr_t bsd_to_irix_fcntl_flags(uintptr_t);
66 static uintptr_t irix_to_bsd_fcntl_flags(uintptr_t);
68 int
69 irix_sys_lseek64(struct lwp *l, const struct irix_sys_lseek64_args *uap, register_t *retval)
72 * Note: we have an alignement problem here. If pad2, pad3 and pad4
73 * are removed, lseek64 will break, because whence will be wrong.
75 /* {
76 syscallarg(int) fd;
77 syscallarg(int) pad1;
78 syscallarg(irix_off64_t) offset;
79 syscallarg(int) whence;
80 syscallarg(int) pad2;
81 syscallarg(int) pad3;
82 syscallarg(int) pad4;
83 } */
85 struct sys_lseek_args cup;
87 #ifdef DEBUG_IRIX
88 printf("irix_sys_lseek64(): fd = %d, pad1 = 0x%08x, offset = 0x%llx\n",
89 SCARG(uap, fd), SCARG(uap, pad1), SCARG(uap, offset));
90 printf("whence = 0x%08x, pad2 = 0x%08x, pad3 = 0x%08x, pad4 = 0x%08x\n",
91 SCARG(uap, whence), SCARG(uap, pad2), SCARG(uap, pad3),
92 SCARG(uap, pad4));
93 #endif
94 SCARG(&cup, fd) = SCARG(uap, fd);
95 SCARG(&cup, PAD) = 0;
96 SCARG(&cup, offset) = SCARG(uap, offset);
97 SCARG(&cup, whence) = SCARG(uap, whence);
99 return sys_lseek(l, (void *)&cup, retval);
103 irix_sys_fcntl(struct lwp *l, const struct irix_sys_fcntl_args *uap, register_t *retval)
105 /* {
106 syscallarg(int) fd;
107 syscallarg(int) cmd;
108 syscallarg(char *)arg;
109 } */
110 struct svr4_sys_fcntl_args cup;
111 struct sys_fcntl_args bsd_ua;
112 int cmd;
113 int error;
115 cmd = SCARG(uap, cmd);
116 switch (cmd) {
117 case SVR4_F_FREESP:
118 case SVR4_F_ALLOCSP: {
119 struct svr4_flock fl;
121 if ((error = copyin(SCARG(uap, arg), &fl, sizeof(fl))) != 0)
122 return error;
124 return fd_truncate(l, SCARG(uap, fd),
125 fl.l_whence, fl.l_start, retval);
126 break;
129 case SVR4_F_FREESP64:
130 case IRIX_F_ALLOCSP64: {
131 struct svr4_flock64 fl;
133 if ((error = copyin(SCARG(uap, arg), &fl, sizeof(fl))) != 0)
134 return error;
136 return fd_truncate(l, SCARG(uap, fd),
137 fl.l_whence, fl.l_start, retval);
138 break;
141 case IRIX_F_SETBSDLKW:
142 cmd = SVR4_F_SETLKW;
143 break;
145 case IRIX_F_SETBSDLK:
146 cmd = SVR4_F_SETLK;
147 break;
149 case IRIX_F_GETFL:
150 SCARG(&bsd_ua, fd) = SCARG(uap, fd);
151 SCARG(&bsd_ua, cmd) = F_GETFL;
152 SCARG(&bsd_ua, arg) = SCARG(uap, arg);
153 if ((error = sys_fcntl(l, &bsd_ua, retval)) != 0)
154 return error;
155 *retval = bsd_to_irix_fcntl_flags(*retval);
156 return 0;
157 break;
159 case IRIX_F_SETFL:
161 * All unsupported flags are silently ignored
162 * except FDIRECT taht will return EINVAL
164 if ((uintptr_t)SCARG(uap, arg) & IRIX_FDIRECT)
165 return EINVAL;
167 SCARG(&bsd_ua, fd) = SCARG(uap, fd);
168 SCARG(&bsd_ua, arg) =
169 (char *)irix_to_bsd_fcntl_flags((uintptr_t)SCARG(uap, arg));
170 SCARG(&bsd_ua, cmd) = F_SETFL;
171 return sys_fcntl(l, &bsd_ua, retval);
172 break;
174 case SVR4_F_DUPFD:
175 case SVR4_F_GETFD:
176 case SVR4_F_SETFD:
177 case SVR4_F_SETLK:
178 case SVR4_F_SETLKW:
179 case SVR4_F_CHKFL:
180 case SVR4_F_GETLK:
181 case SVR4_F_RSETLK:
182 case SVR4_F_RGETLK:
183 case SVR4_F_RSETLKW:
184 case SVR4_F_GETOWN:
185 case SVR4_F_SETOWN:
186 case SVR4_F_GETLK64:
187 case SVR4_F_SETLK64:
188 case SVR4_F_SETLKW64:
189 break;
191 case IRIX_F_CHKLK:
192 case IRIX_F_CHKLKW:
193 case IRIX_F_CLNLK:
194 case IRIX_F_DIOINFO:
195 case IRIX_F_FSGETXATTR:
196 case IRIX_F_FSSETXATTR:
197 case IRIX_F_GETBMAP:
198 case IRIX_F_FSSETDM:
199 case IRIX_F_RESVSP:
200 case IRIX_F_UNRESVSP:
201 case IRIX_F_RESVSP64:
202 case IRIX_F_UNRESVSP64:
203 case IRIX_F_GETBMAPA:
204 case IRIX_F_FSGETXATTRA:
205 case IRIX_F_SETBIOSIZE:
206 case IRIX_F_GETBIOSIZE:
207 case IRIX_F_GETOPS:
208 case IRIX_F_DMAPI:
209 case IRIX_F_FSYNC:
210 case IRIX_F_FSYNC64:
211 case IRIX_F_GETBDSATTR:
212 case IRIX_F_SETBDSATTR:
213 case IRIX_F_GETBMAPX:
214 case IRIX_F_SETPRIO:
215 case IRIX_F_GETPRIO:
216 default:
217 printf("Warning: unimplemented IRIX fcntl() command %d\n",
218 cmd);
219 return EINVAL;
220 break;
223 SCARG(&cup, fd) = SCARG(uap, fd);
224 SCARG(&cup, cmd) = cmd;
225 SCARG(&cup, arg) = SCARG(uap, arg);
226 return svr4_sys_fcntl(l, &cup, retval);
229 static int
230 fd_truncate(struct lwp *l, int fd, int whence, off_t start, register_t *retval)
232 file_t *fp;
233 struct vnode *vp;
234 struct vattr vattr;
235 struct sys_ftruncate_args ft;
236 int error;
238 if ((error = fd_getvnode(fd, &fp)) != 0)
239 return EBADF;
241 vp = fp->f_data;
242 if (vp->v_type == VFIFO) {
243 fd_putfile(fd);
244 return ESPIPE;
247 switch (whence) {
248 case SEEK_CUR:
249 SCARG(&ft, length) = fp->f_offset + start;
250 break;
252 case SEEK_END:
253 if ((error = VOP_GETATTR(vp, &vattr, l->l_cred)) != 0)
254 return error;
255 SCARG(&ft, length) = vattr.va_size + start;
256 break;
258 case SEEK_SET:
259 SCARG(&ft, length) = start;
260 break;
262 default:
263 return EINVAL;
264 break;
266 fd_putfile(fd);
268 SCARG(&ft, fd) = fd;
269 return sys_ftruncate(l, &ft, retval);
273 irix_sys_open(struct lwp *l, const struct irix_sys_open_args *uap, register_t *retval)
275 /* {
276 syscallarg(char *) path;
277 syscallarg(int) flags;
278 syscallarg(mode_t) mode;
279 } */
280 extern const struct cdevsw irix_usema_cdevsw;
281 int error;
282 int fd;
283 file_t *fp;
284 struct vnode *vp;
285 struct vnode *nvp;
287 if ((error = svr4_sys_open(l, (const void *)uap, retval)) != 0)
288 return error;
290 fd = (int)*retval;
291 if ((fp = fd_getfile(fd)) == NULL)
292 return EBADF;
294 vp = fp->f_data;
297 * A special hook for the usemaclone driver: we need to clone
298 * the vnode, because the driver method need a context for each
299 * usemaclone open instance, and because we need to overload
300 * some vnode operations like setattr.
301 * The original vnode is stored in the v_data field of the cloned
302 * vnode.
304 if (vp->v_type == VCHR &&
305 cdevsw_lookup(vp->v_rdev) == &irix_usema_cdevsw &&
306 minor(vp->v_rdev) == IRIX_USEMACLNDEV_MINOR) {
307 if ((error = getnewvnode(VCHR, vp->v_mount,
308 irix_usema_vnodeop_p,
309 (struct vnode **)&fp->f_data)) != 0) {
310 (void) vn_close(vp, fp->f_flag, fp->f_cred);
311 fd_close(fd);
312 return error;
315 nvp = (struct vnode *)fp->f_data;
317 if (SCARG(uap, flags) & O_RDWR || SCARG(uap, flags) & O_WRONLY)
318 nvp->v_writecount++;
320 nvp->v_type = VCHR;
321 nvp->v_rdev = vp->v_rdev;
322 nvp->v_specmountpoint = vp->v_specmountpoint;
324 nvp->v_data = (void *)vp;
325 vref(vp);
327 fd_putfile(fd);
329 return 0;
332 static uintptr_t
333 irix_to_bsd_fcntl_flags(uintptr_t flags)
335 uintptr_t ret = 0;
337 if (flags & IRIX_FNDELAY) ret |= FNDELAY;
338 if (flags & IRIX_FAPPEND) ret |= FAPPEND;
339 if (flags & IRIX_FSYNC) ret |= FFSYNC;
340 if (flags & IRIX_FDSYNC) ret |= FDSYNC;
341 if (flags & IRIX_FASYNC) ret |= FASYNC;
342 if (flags & IRIX_FRSYNC) ret |= FRSYNC;
343 if (flags & IRIX_FNONBLOCK) ret |= FNONBLOCK;
344 if (flags & IRIX_FLARGEFILE)
345 printf("Warning: ignored fcntl IRIX_FLARGEFILE flag");
346 if (flags & IRIX_FDIRECT)
347 printf("Warning: ignored fcntl IRIX_FDIRECT flag");
348 if (flags & IRIX_FBULK)
349 printf("Warning: ignored fcntl IRIX_FBULK flag");
350 if (flags & IRIX_FLCINVAL)
351 printf("Warning: ignored fcntl IRIX_FLCINVAL flag");
352 if (flags & IRIX_FLCFLUSH)
353 printf("Warning: ignored fcntl IRIX_FLCFLUSH flag");
355 return ret;
358 static uintptr_t
359 bsd_to_irix_fcntl_flags(uintptr_t flags)
361 uintptr_t ret = 0;
363 if (flags & FNDELAY) ret |= IRIX_FNDELAY;
364 if (flags & FAPPEND) ret |= IRIX_FAPPEND;
365 if (flags & FFSYNC) ret |= IRIX_FSYNC;
366 if (flags & FDSYNC) ret |= IRIX_FDSYNC;
367 if (flags & FRSYNC) ret |= IRIX_FRSYNC;
368 if (flags & FNONBLOCK) ret |= IRIX_FNONBLOCK;
369 if (flags & FASYNC) ret |= IRIX_FASYNC;
371 return ret;