1 /* $NetBSD: irix_fcntl.c,v 1.27 2009/08/31 05:34:16 dholland Exp $ */
4 * Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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>
41 #include <sys/malloc.h>
42 #include <sys/vnode.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);
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.
78 syscallarg(irix_off64_t) offset;
79 syscallarg(int) whence;
85 struct sys_lseek_args cup
;
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
),
94 SCARG(&cup
, fd
) = SCARG(uap
, fd
);
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
)
108 syscallarg(char *)arg;
110 struct svr4_sys_fcntl_args cup
;
111 struct sys_fcntl_args bsd_ua
;
115 cmd
= SCARG(uap
, cmd
);
118 case SVR4_F_ALLOCSP
: {
119 struct svr4_flock fl
;
121 if ((error
= copyin(SCARG(uap
, arg
), &fl
, sizeof(fl
))) != 0)
124 return fd_truncate(l
, SCARG(uap
, fd
),
125 fl
.l_whence
, fl
.l_start
, retval
);
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)
136 return fd_truncate(l
, SCARG(uap
, fd
),
137 fl
.l_whence
, fl
.l_start
, retval
);
141 case IRIX_F_SETBSDLKW
:
145 case IRIX_F_SETBSDLK
:
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)
155 *retval
= bsd_to_irix_fcntl_flags(*retval
);
161 * All unsupported flags are silently ignored
162 * except FDIRECT taht will return EINVAL
164 if ((uintptr_t)SCARG(uap
, arg
) & IRIX_FDIRECT
)
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
);
188 case SVR4_F_SETLKW64
:
195 case IRIX_F_FSGETXATTR
:
196 case IRIX_F_FSSETXATTR
:
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
:
211 case IRIX_F_GETBDSATTR
:
212 case IRIX_F_SETBDSATTR
:
213 case IRIX_F_GETBMAPX
:
217 printf("Warning: unimplemented IRIX fcntl() command %d\n",
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
);
230 fd_truncate(struct lwp
*l
, int fd
, int whence
, off_t start
, register_t
*retval
)
235 struct sys_ftruncate_args ft
;
238 if ((error
= fd_getvnode(fd
, &fp
)) != 0)
242 if (vp
->v_type
== VFIFO
) {
249 SCARG(&ft
, length
) = fp
->f_offset
+ start
;
253 if ((error
= VOP_GETATTR(vp
, &vattr
, l
->l_cred
)) != 0)
255 SCARG(&ft
, length
) = vattr
.va_size
+ start
;
259 SCARG(&ft
, length
) = start
;
269 return sys_ftruncate(l
, &ft
, retval
);
273 irix_sys_open(struct lwp
*l
, const struct irix_sys_open_args
*uap
, register_t
*retval
)
276 syscallarg(char *) path;
277 syscallarg(int) flags;
278 syscallarg(mode_t) mode;
280 extern const struct cdevsw irix_usema_cdevsw
;
287 if ((error
= svr4_sys_open(l
, (const void *)uap
, retval
)) != 0)
291 if ((fp
= fd_getfile(fd
)) == NULL
)
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
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
);
315 nvp
= (struct vnode
*)fp
->f_data
;
317 if (SCARG(uap
, flags
) & O_RDWR
|| SCARG(uap
, flags
) & O_WRONLY
)
321 nvp
->v_rdev
= vp
->v_rdev
;
322 nvp
->v_specmountpoint
= vp
->v_specmountpoint
;
324 nvp
->v_data
= (void *)vp
;
333 irix_to_bsd_fcntl_flags(uintptr_t flags
)
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");
359 bsd_to_irix_fcntl_flags(uintptr_t flags
)
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
;