1 /* $NetBSD: sunos_misc.c,v 1.164 2009/01/11 12:44:47 tsutsui Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * @(#)sunos_misc.c 8.1 (Berkeley) 6/18/93
42 * Header: sunos_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
46 * SunOS compatibility module.
48 * SunOS system calls that are implemented differently in BSD are
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: sunos_misc.c,v 1.164 2009/01/11 12:44:47 tsutsui Exp $");
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/namei.h>
59 #include <sys/dirent.h>
62 #include <sys/filedesc.h>
63 #include <sys/ioctl.h>
64 #include <sys/kernel.h>
65 #include <sys/reboot.h>
66 #include <sys/malloc.h>
69 #include <sys/mount.h>
70 #include <sys/ptrace.h>
71 #include <sys/resource.h>
72 #include <sys/resourcevar.h>
73 #include <sys/signal.h>
74 #include <sys/signalvar.h>
75 #include <sys/socket.h>
77 #include <sys/vnode.h>
80 #include <sys/utsname.h>
81 #include <sys/unistd.h>
82 #include <sys/syscall.h>
83 #include <sys/syscallargs.h>
85 #include <sys/socketvar.h>
88 #include <sys/kauth.h>
90 #include <compat/sys/signal.h>
92 #include <compat/sunos/sunos.h>
93 #include <compat/sunos/sunos_syscallargs.h>
94 #include <compat/common/compat_util.h>
95 #include <compat/sunos/sunos_dirent.h>
96 #include <compat/sys/mount.h>
98 #include <netinet/in.h>
100 #include <miscfs/specfs/specdev.h>
102 #include <nfs/rpcv2.h>
103 #include <nfs/nfsproto.h>
105 #include <nfs/nfsmount.h>
107 static int sunstatfs(struct statvfs
*, void *);
110 sunos_sys_stime(struct lwp
*l
, const struct sunos_sys_stime_args
*uap
, register_t
*retval
)
115 error
= copyin(SCARG(uap
, tp
), &tv
.tv_sec
, sizeof(tv
.tv_sec
));
120 return settimeofday1(&tv
, false, NULL
, l
, true);
124 sunos_sys_wait4(struct lwp
*l
, const struct sunos_sys_wait4_args
*uap
, register_t
*retval
)
126 struct compat_50_sys_wait4_args bsd_ua
;
128 SCARG(&bsd_ua
, pid
) = SCARG(uap
, pid
) == 0 ? WAIT_ANY
: SCARG(uap
, pid
);
129 SCARG(&bsd_ua
, status
) = SCARG(uap
, status
);
130 SCARG(&bsd_ua
, options
) = SCARG(uap
, options
);
131 SCARG(&bsd_ua
, rusage
) = SCARG(uap
, rusage
);
133 return (compat_50_sys_wait4(l
, &bsd_ua
, retval
));
137 sunos_sys_creat(struct lwp
*l
, const struct sunos_sys_creat_args
*uap
, register_t
*retval
)
139 struct sys_open_args ouap
;
141 SCARG(&ouap
, path
) = SCARG(uap
, path
);
142 SCARG(&ouap
, flags
) = O_WRONLY
| O_CREAT
| O_TRUNC
;
143 SCARG(&ouap
, mode
) = SCARG(uap
, mode
);
145 return (sys_open(l
, &ouap
, retval
));
149 sunos_sys_execv(struct lwp
*l
, const struct sunos_sys_execv_args
*uap
, register_t
*retval
)
152 syscallarg(const char *) path;
153 syscallarg(char **) argv;
155 struct sys_execve_args ap
;
157 SCARG(&ap
, path
) = SCARG(uap
, path
);
158 SCARG(&ap
, argp
) = SCARG(uap
, argp
);
159 SCARG(&ap
, envp
) = NULL
;
161 return (sys_execve(l
, &ap
, retval
));
165 sunos_sys_execve(struct lwp
*l
, const struct sunos_sys_execve_args
*uap
, register_t
*retval
)
168 syscallarg(const char *) path;
169 syscallarg(char **) argv;
170 syscallarg(char **) envp;
172 struct sys_execve_args ap
;
174 SCARG(&ap
, path
) = SCARG(uap
, path
);
175 SCARG(&ap
, argp
) = SCARG(uap
, argp
);
176 SCARG(&ap
, envp
) = SCARG(uap
, envp
);
178 return (sys_execve(l
, &ap
, retval
));
182 sunos_sys_omsync(struct lwp
*l
, const struct sunos_sys_omsync_args
*uap
, register_t
*retval
)
184 struct sys___msync13_args ouap
;
186 SCARG(&ouap
, addr
) = SCARG(uap
, addr
);
187 SCARG(&ouap
, len
) = SCARG(uap
, len
);
188 SCARG(&ouap
, flags
) = SCARG(uap
, flags
);
190 return (sys___msync13(l
, &ouap
, retval
));
194 sunos_sys_unmount(struct lwp
*l
, const struct sunos_sys_unmount_args
*uap
, register_t
*retval
)
196 struct sys_unmount_args ouap
;
198 SCARG(&ouap
, path
) = SCARG(uap
, path
);
199 SCARG(&ouap
, flags
) = 0;
201 return (sys_unmount(l
, &ouap
, retval
));
205 * Conversion table for SunOS NFS mount flags.
210 } sunnfs_flgtab
[] = {
211 { SUNNFS_SOFT
, NFSMNT_SOFT
},
212 { SUNNFS_WSIZE
, NFSMNT_WSIZE
},
213 { SUNNFS_RSIZE
, NFSMNT_RSIZE
},
214 { SUNNFS_TIMEO
, NFSMNT_TIMEO
},
215 { SUNNFS_RETRANS
, NFSMNT_RETRANS
},
216 { SUNNFS_HOSTNAME
, 0 }, /* Ignored */
217 { SUNNFS_INT
, NFSMNT_INT
},
218 { SUNNFS_NOAC
, 0 }, /* Ignored */
219 { SUNNFS_ACREGMIN
, 0 }, /* Ignored */
220 { SUNNFS_ACREGMAX
, 0 }, /* Ignored */
221 { SUNNFS_ACDIRMIN
, 0 }, /* Ignored */
222 { SUNNFS_ACDIRMAX
, 0 }, /* Ignored */
223 { SUNNFS_SECURE
, 0 }, /* Ignored */
224 { SUNNFS_NOCTO
, 0 }, /* Ignored */
225 { SUNNFS_POSIX
, 0 } /* Ignored */
229 sunos_sys_mount(struct lwp
*l
, const struct sunos_sys_mount_args
*uap
, register_t
*retval
)
231 int oflags
= SCARG(uap
, flags
), nflags
, error
;
232 char fsname
[MFSNAMELEN
];
235 if (oflags
& (SUNM_NOSUB
| SUNM_SYS5
))
237 if ((oflags
& SUNM_NEWTYPE
) == 0)
240 if (oflags
& SUNM_RDONLY
)
241 nflags
|= MNT_RDONLY
;
242 if (oflags
& SUNM_NOSUID
)
243 nflags
|= MNT_NOSUID
;
244 if (oflags
& SUNM_REMOUNT
)
245 nflags
|= MNT_UPDATE
;
247 error
= copyinstr(SCARG(uap
, type
), fsname
, sizeof fsname
, NULL
);
251 if (strcmp(fsname
, "nfs") == 0) {
252 struct sunos_nfs_args sna
;
256 error
= copyin(SCARG(uap
, data
), &sna
, sizeof sna
);
259 /* sa.sa_len = sizeof(sain); */
260 na
.version
= NFS_ARGSVERSION
;
261 na
.addr
= (void *)sna
.addr
;
262 na
.addrlen
= sizeof(struct sockaddr
);
263 na
.sotype
= SOCK_DGRAM
;
264 na
.proto
= IPPROTO_UDP
;
266 na
.fhsize
= NFSX_V2FH
;
268 n
= sizeof(sunnfs_flgtab
) / sizeof(sunnfs_flgtab
[0]);
270 if (sna
.flags
& sunnfs_flgtab
[n
].sun_flg
)
271 na
.flags
|= sunnfs_flgtab
[n
].bsd_flg
;
272 na
.wsize
= sna
.wsize
;
273 na
.rsize
= sna
.rsize
;
274 if (na
.flags
& NFSMNT_RSIZE
) {
275 na
.flags
|= NFSMNT_READDIRSIZE
;
276 na
.readdirsize
= na
.rsize
;
278 na
.timeo
= sna
.timeo
;
279 na
.retrans
= sna
.retrans
;
280 na
.hostname
= /* (char *)(u_long) */ sna
.hostname
;
282 return do_sys_mount(l
, vfs_getopsbyname("nfs"), NULL
,
283 SCARG(uap
, dir
), nflags
, &na
,
284 UIO_SYSSPACE
, sizeof na
, &dummy
);
287 if (strcmp(fsname
, "4.2") == 0)
288 strcpy(fsname
, "ffs");
290 return do_sys_mount(l
, vfs_getopsbyname(fsname
), NULL
,
291 SCARG(uap
, dir
), nflags
, SCARG(uap
, data
),
292 UIO_USERSPACE
, 0, &dummy
);
296 async_daemon(struct lwp
*l
, const void *v
, register_t
*retval
)
299 return kpause("fakeniod", false, 0, NULL
);
302 void native_to_sunos_sigset(const sigset_t
*, int *);
303 void sunos_to_native_sigset(const int, sigset_t
*);
306 native_to_sunos_sigset(const sigset_t
*ss
, int *mask
)
308 *mask
= ss
->__bits
[0];
312 sunos_to_native_sigset(const int mask
, sigset_t
*ss
)
315 ss
->__bits
[0] = mask
;
322 sunos_sys_sigpending(struct lwp
*l
, const struct sunos_sys_sigpending_args
*uap
, register_t
*retval
)
328 native_to_sunos_sigset(&ss
, &mask
);
330 return (copyout((void *)&mask
, (void *)SCARG(uap
, mask
), sizeof(int)));
334 sunos_sys_sigsuspend(struct lwp
*l
, const struct sunos_sys_sigsuspend_args
*uap
, register_t
*retval
)
337 syscallarg(int) mask;
342 mask
= SCARG(uap
, mask
);
343 sunos_to_native_sigset(mask
, &ss
);
344 return (sigsuspend1(l
, &ss
));
348 * Read Sun-style directory entries. We suck them into kernel space so
349 * that they can be massaged before being copied out to user code. Like
350 * SunOS, we squish out `empty' entries.
352 * This is quite ugly, but what do you expect from compatibility code?
355 sunos_sys_getdents(struct lwp
*l
, const struct sunos_sys_getdents_args
*uap
, register_t
*retval
)
359 char *inp
, *buf
; /* BSD-format */
360 int len
, reclen
; /* BSD-format */
361 char *outp
; /* Sun-format */
362 int resid
, sunos_reclen
;/* Sun-format */
366 struct sunos_dirent idb
;
367 off_t off
; /* true file offset */
368 int buflen
, error
, eofflag
;
369 off_t
*cookiebuf
, *cookie
;
372 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
375 if ((fp
->f_flag
& FREAD
) == 0) {
381 if (vp
->v_type
!= VDIR
) {
386 buflen
= min(MAXBSIZE
, SCARG(uap
, nbytes
));
387 buf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
388 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
392 aiov
.iov_len
= buflen
;
393 auio
.uio_iov
= &aiov
;
395 auio
.uio_rw
= UIO_READ
;
396 auio
.uio_resid
= buflen
;
397 auio
.uio_offset
= off
;
398 UIO_SETUP_SYSSPACE(&auio
);
400 * First we read into the malloc'ed buffer, then
401 * we massage it into user space, one record at a time.
403 error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &cookiebuf
,
409 outp
= SCARG(uap
, buf
);
410 resid
= SCARG(uap
, nbytes
);
411 if ((len
= buflen
- auio
.uio_resid
) == 0)
414 for (cookie
= cookiebuf
; len
> 0; len
-= reclen
) {
415 bdp
= (struct dirent
*)inp
;
416 reclen
= bdp
->d_reclen
;
418 panic("sunos_getdents");
419 if ((*cookie
>> 32) != 0) {
420 compat_offseterr(vp
, "sunos_getdents");
424 if (bdp
->d_fileno
== 0) {
425 inp
+= reclen
; /* it is a hole; squish it out */
432 sunos_reclen
= SUNOS_RECLEN(&idb
, bdp
->d_namlen
);
433 if (reclen
> len
|| resid
< sunos_reclen
) {
434 /* entry too big for buffer, so just stop */
439 off
= *cookie
++; /* each entry points to next */
443 * Massage in place to make a Sun-shaped dirent (otherwise
444 * we have to worry about touching user memory outside of
445 * the copyout() call).
447 idb
.d_fileno
= bdp
->d_fileno
;
449 idb
.d_reclen
= sunos_reclen
;
450 idb
.d_namlen
= bdp
->d_namlen
;
451 strlcpy(idb
.d_name
, bdp
->d_name
, sizeof(idb
.d_name
));
452 if ((error
= copyout((void *)&idb
, outp
, sunos_reclen
)) != 0)
454 /* advance past this real entry */
456 /* advance output past Sun-shaped entry */
457 outp
+= sunos_reclen
;
458 resid
-= sunos_reclen
;
461 /* if we squished out the whole block, try again */
462 if (outp
== SCARG(uap
, buf
))
464 fp
->f_offset
= off
; /* update the vnode offset */
467 *retval
= SCARG(uap
, nbytes
) - resid
;
470 free(cookiebuf
, M_TEMP
);
473 fd_putfile(SCARG(uap
, fd
));
477 #define SUNOS__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */
480 sunos_sys_mmap(struct lwp
*l
, const struct sunos_sys_mmap_args
*uap
, register_t
*retval
)
482 struct sys_mmap_args ouap
;
485 * Verify the arguments.
487 if (SCARG(uap
, prot
) & ~(PROT_READ
|PROT_WRITE
|PROT_EXEC
))
488 return (EINVAL
); /* XXX still needed? */
490 if ((SCARG(uap
, flags
) & SUNOS__MAP_NEW
) == 0)
493 SCARG(&ouap
, flags
) = SCARG(uap
, flags
) & ~SUNOS__MAP_NEW
;
494 SCARG(&ouap
, addr
) = SCARG(uap
, addr
);
495 SCARG(&ouap
, len
) = SCARG(uap
, len
);
496 SCARG(&ouap
, prot
) = SCARG(uap
, prot
);
497 SCARG(&ouap
, fd
) = SCARG(uap
, fd
);
498 SCARG(&ouap
, pos
) = SCARG(uap
, pos
);
500 return (sys_mmap(l
, &ouap
, retval
));
508 #define MC_UNLOCKAS 6
511 sunos_sys_mctl(struct lwp
*l
, const struct sunos_sys_mctl_args
*uap
, register_t
*retval
)
514 switch (SCARG(uap
, func
)) {
515 case MC_ADVISE
: /* ignore for now */
517 case MC_SYNC
: /* translate to msync */
518 return (sys___msync13(l
, (const void *)uap
, retval
));
525 sunos_sys_setsockopt(struct lwp
*l
, const struct sunos_sys_setsockopt_args
*uap
, register_t
*retval
)
529 int name
= SCARG(uap
, name
);
532 /* fd_getsock() will use the descriptor for us */
533 if ((error
= fd_getsock(SCARG(uap
, s
), &so
)) != 0)
535 #define SO_DONTLINGER (~SO_LINGER)
536 if (name
== SO_DONTLINGER
) {
540 error
= so_setsockopt(l
, so
, SCARG(uap
, level
), SO_LINGER
,
544 if (SCARG(uap
, level
) == IPPROTO_IP
) {
545 #define SUNOS_IP_MULTICAST_IF 2
546 #define SUNOS_IP_MULTICAST_TTL 3
547 #define SUNOS_IP_MULTICAST_LOOP 4
548 #define SUNOS_IP_ADD_MEMBERSHIP 5
549 #define SUNOS_IP_DROP_MEMBERSHIP 6
550 static const int ipoptxlat
[] = {
557 if (name
>= SUNOS_IP_MULTICAST_IF
&&
558 name
<= SUNOS_IP_DROP_MEMBERSHIP
) {
559 name
= ipoptxlat
[name
- SUNOS_IP_MULTICAST_IF
];
562 if (SCARG(uap
, valsize
) > MLEN
) {
566 sockopt_init(&sopt
, SCARG(uap
, level
), name
, SCARG(uap
, valsize
));
567 if (SCARG(uap
, val
)) {
568 error
= copyin(SCARG(uap
, val
), sopt
.sopt_data
,
569 (u_int
)SCARG(uap
, valsize
));
572 error
= sosetopt(so
, &sopt
);
573 sockopt_destroy(&sopt
);
575 fd_putfile(SCARG(uap
, s
));
579 static inline int sunos_sys_socket_common(struct lwp
*, register_t
*,
582 sunos_sys_socket_common(struct lwp
*l
, register_t
*retval
, int type
)
587 /* fd_getsock() will use the descriptor for us */
589 if ((error
= fd_getsock(fd
, &so
)) == 0) {
590 if (type
== SOCK_DGRAM
)
591 so
->so_options
|= SO_BROADCAST
;
598 sunos_sys_socket(struct lwp
*l
, const struct sunos_sys_socket_args
*uap
, register_t
*retval
)
601 syscallarg(int) domain;
602 syscallarg(int) type;
603 syscallarg(int) protocol;
607 error
= compat_30_sys_socket(l
, (const void *)uap
, retval
);
610 return sunos_sys_socket_common(l
, retval
, SCARG(uap
, type
));
614 sunos_sys_socketpair(struct lwp
*l
, const struct sunos_sys_socketpair_args
*uap
, register_t
*retval
)
617 syscallarg(int) domain;
618 syscallarg(int) type;
619 syscallarg(int) protocol;
620 syscallarg(int *) rsv;
624 error
= sys_socketpair(l
, (const void *)uap
, retval
);
627 return sunos_sys_socket_common(l
, retval
, SCARG(uap
, type
));
631 * XXX: This needs cleaning up.
634 sunos_sys_auditsys(struct lwp
*l
, const struct sunos_sys_auditsys_args
*uap
, register_t
*retval
)
640 sunos_sys_uname(struct lwp
*l
, const struct sunos_sys_uname_args
*uap
, register_t
*retval
)
642 struct sunos_utsname sut
;
644 memset(&sut
, 0, sizeof(sut
));
646 memcpy(sut
.sysname
, ostype
, sizeof(sut
.sysname
) - 1);
647 memcpy(sut
.nodename
, hostname
, sizeof(sut
.nodename
));
648 sut
.nodename
[sizeof(sut
.nodename
)-1] = '\0';
649 memcpy(sut
.release
, osrelease
, sizeof(sut
.release
) - 1);
650 memcpy(sut
.version
, "1", sizeof(sut
.version
) - 1);
651 memcpy(sut
.machine
, machine
, sizeof(sut
.machine
) - 1);
653 return copyout((void *)&sut
, (void *)SCARG(uap
, name
),
654 sizeof(struct sunos_utsname
));
658 sunos_sys_setpgrp(struct lwp
*l
, const struct sunos_sys_setpgrp_args
*uap
, register_t
*retval
)
660 struct proc
*p
= l
->l_proc
;
663 * difference to our setpgid call is to include backwards
664 * compatibility to pre-setsid() binaries. Do setsid()
665 * instead of setpgid() in those cases where the process
666 * tries to create a new session the old way.
668 if (!SCARG(uap
, pgid
) &&
669 (!SCARG(uap
, pid
) || SCARG(uap
, pid
) == p
->p_pid
))
670 return sys_setsid(l
, NULL
, retval
);
672 return sys_setpgid(l
, (const void *)uap
, retval
);
676 sunos_sys_open(struct lwp
*l
, const struct sunos_sys_open_args
*uap
, register_t
*retval
)
678 struct proc
*p
= l
->l_proc
;
679 struct sys_open_args open_ua
;
684 /* convert mode into NetBSD mode */
685 smode
= SCARG(uap
, flags
);
686 noctty
= smode
& 0x8000;
688 (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800);
689 nmode
|= ((smode
& (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK
: 0);
690 nmode
|= ((smode
& 0x0080) ? O_SHLOCK
: 0);
691 nmode
|= ((smode
& 0x0100) ? O_EXLOCK
: 0);
692 nmode
|= ((smode
& 0x2000) ? O_FSYNC
: 0);
694 SCARG(&open_ua
, path
) = SCARG(uap
, path
);
695 SCARG(&open_ua
, flags
) = nmode
;
696 SCARG(&open_ua
, mode
) = SCARG(uap
, mode
);
697 ret
= sys_open(l
, &open_ua
, retval
);
700 if (!ret
&& !noctty
&& SESS_LEADER(p
) && !(p
->p_lflag
& PL_CONTROLT
)) {
707 /* ignore any error, just give it a try */
709 if (fp
->f_type
== DTYPE_VNODE
)
710 (fp
->f_ops
->fo_ioctl
)(fp
, TIOCSCTTY
, NULL
);
718 sunos_sys_nfssvc(struct lwp
*l
, const struct sunos_sys_nfssvc_args
*uap
, register_t
*retval
)
721 struct proc
*p
= l
->l_proc
;
722 struct emul
*e
= p
->p_emul
;
723 struct sys_nfssvc_args outuap
;
726 void *sg
= stackgap_init(p
, 0);
728 memset(&outuap
, 0, sizeof outuap
);
729 SCARG(&outuap
, fd
) = SCARG(uap
, fd
);
730 SCARG(&outuap
, mskval
) = stackgap_alloc(p
, &sg
, sizeof(sa
));
731 SCARG(&outuap
, msklen
) = sizeof(sa
);
732 SCARG(&outuap
, mtchval
) = stackgap_alloc(p
, &sg
, sizeof(sa
));
733 SCARG(&outuap
, mtchlen
) = sizeof(sa
);
735 memset(&sa
, 0, sizeof sa
);
736 if (error
= copyout(&sa
, SCARG(&outuap
, mskval
), SCARG(&outuap
, msklen
)))
738 if (error
= copyout(&sa
, SCARG(&outuap
, mtchval
), SCARG(&outuap
, mtchlen
)))
741 return nfssvc(l
, &outuap
, retval
);
748 sunos_sys_ustat(struct lwp
*l
, const struct sunos_sys_ustat_args
*uap
, register_t
*retval
)
750 struct sunos_ustat us
;
753 memset(&us
, 0, sizeof us
);
756 * XXX: should set f_tfree and f_tinode at least
757 * How do we translate dev -> fstat? (and then to sunos_ustat)
760 if ((error
= copyout(&us
, SCARG(uap
, buf
), sizeof us
)) != 0)
766 sunos_sys_quotactl(struct lwp
*l
, const struct sunos_sys_quotactl_args
*uap
, register_t
*retval
)
773 sunos_sys_vhangup(struct lwp
*l
, const void *v
, register_t
*retval
)
775 struct proc
*p
= l
->l_proc
;
776 struct session
*sp
= p
->p_session
;
778 if (sp
->s_ttyvp
== 0)
781 if (sp
->s_ttyp
&& sp
->s_ttyp
->t_session
== sp
&& sp
->s_ttyp
->t_pgrp
)
782 pgsignal(sp
->s_ttyp
->t_pgrp
, SIGHUP
, 1);
784 (void) ttywait(sp
->s_ttyp
);
786 VOP_REVOKE(sp
->s_ttyvp
, REVOKEALL
);
795 sunstatfs(struct statvfs
*sp
, void *buf
)
797 struct sunos_statfs ssfs
;
799 memset(&ssfs
, 0, sizeof ssfs
);
801 ssfs
.f_bsize
= sp
->f_bsize
;
802 ssfs
.f_blocks
= sp
->f_blocks
;
803 ssfs
.f_bfree
= sp
->f_bfree
;
804 ssfs
.f_bavail
= sp
->f_bavail
;
805 ssfs
.f_files
= sp
->f_files
;
806 ssfs
.f_ffree
= sp
->f_ffree
;
807 ssfs
.f_fsid
= sp
->f_fsidx
;
808 return copyout((void *)&ssfs
, buf
, sizeof ssfs
);
812 sunos_sys_statfs(struct lwp
*l
, const struct sunos_sys_statfs_args
*uap
, register_t
*retval
)
819 error
= namei_simple_user(SCARG(uap
, path
),
820 NSM_FOLLOW_TRYEMULROOT
, &vp
);
826 if ((error
= VFS_STATVFS(mp
, sp
)) != 0)
828 sp
->f_flag
= mp
->mnt_flag
& MNT_VISFLAGMASK
;
829 return sunstatfs(sp
, (void *)SCARG(uap
, buf
));
833 sunos_sys_fstatfs(struct lwp
*l
, const struct sunos_sys_fstatfs_args
*uap
, register_t
*retval
)
840 /* fd_getvnode() will use the descriptor for us */
841 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
843 mp
= ((struct vnode
*)fp
->f_data
)->v_mount
;
845 if ((error
= VFS_STATVFS(mp
, sp
)) != 0)
847 sp
->f_flag
= mp
->mnt_flag
& MNT_VISFLAGMASK
;
848 error
= sunstatfs(sp
, (void *)SCARG(uap
, buf
));
850 fd_putfile(SCARG(uap
, fd
));
855 sunos_sys_exportfs(struct lwp
*l
, const struct sunos_sys_exportfs_args
*uap
, register_t
*retval
)
858 * XXX: should perhaps translate into a mount(2)
865 sunos_sys_mknod(struct lwp
*l
, const struct sunos_sys_mknod_args
*uap
, register_t
*retval
)
867 struct sys_mkfifo_args fifo_ua
;
869 if (S_ISFIFO(SCARG(uap
, mode
))) {
870 SCARG(&fifo_ua
, path
) = SCARG(uap
, path
);
871 SCARG(&fifo_ua
, mode
) = SCARG(uap
, mode
);
872 return sys_mkfifo(l
, &fifo_ua
, retval
);
875 return compat_50_sys_mknod(l
,
876 (const struct compat_50_sys_mknod_args
*)uap
, retval
);
879 #define SUNOS_SC_ARG_MAX 1
880 #define SUNOS_SC_CHILD_MAX 2
881 #define SUNOS_SC_CLK_TCK 3
882 #define SUNOS_SC_NGROUPS_MAX 4
883 #define SUNOS_SC_OPEN_MAX 5
884 #define SUNOS_SC_JOB_CONTROL 6
885 #define SUNOS_SC_SAVED_IDS 7
886 #define SUNOS_SC_VERSION 8
889 sunos_sys_sysconf(struct lwp
*l
, const struct sunos_sys_sysconf_args
*uap
, register_t
*retval
)
892 switch(SCARG(uap
, name
)) {
893 case SUNOS_SC_ARG_MAX
:
896 case SUNOS_SC_CHILD_MAX
:
899 case SUNOS_SC_CLK_TCK
:
900 *retval
= 60; /* should this be `hz', ie. 100? */
902 case SUNOS_SC_NGROUPS_MAX
:
903 *retval
= NGROUPS_MAX
;
905 case SUNOS_SC_OPEN_MAX
:
908 case SUNOS_SC_JOB_CONTROL
:
911 case SUNOS_SC_SAVED_IDS
:
912 #ifdef _POSIX_SAVED_IDS
918 case SUNOS_SC_VERSION
:
927 #define SUNOS_RLIMIT_NOFILE 6 /* Other RLIMIT_* are the same */
928 #define SUNOS_RLIM_NLIMITS 7
931 sunos_sys_getrlimit(struct lwp
*l
, const struct sunos_sys_getrlimit_args
*uap
, register_t
*retval
)
933 struct compat_43_sys_getrlimit_args ua_43
;
935 SCARG(&ua_43
, which
) = SCARG(uap
, which
);
936 SCARG(&ua_43
, rlp
) = SCARG(uap
, rlp
);
938 if (SCARG(uap
, which
) >= SUNOS_RLIM_NLIMITS
)
941 if (SCARG(uap
, which
) == SUNOS_RLIMIT_NOFILE
)
942 SCARG(&ua_43
, which
) = RLIMIT_NOFILE
;
944 return compat_43_sys_getrlimit(l
, &ua_43
, retval
);
948 sunos_sys_setrlimit(struct lwp
*l
, const struct sunos_sys_setrlimit_args
*uap
, register_t
*retval
)
950 struct compat_43_sys_setrlimit_args ua_43
;
952 SCARG(&ua_43
, which
) = SCARG(uap
, which
);
953 SCARG(&ua_43
, rlp
) = SCARG(uap
, rlp
);
955 if (SCARG(uap
, which
) >= SUNOS_RLIM_NLIMITS
)
958 if (SCARG(uap
, which
) == SUNOS_RLIMIT_NOFILE
)
959 SCARG(&ua_43
, which
) = RLIMIT_NOFILE
;
961 return compat_43_sys_setrlimit(l
, &ua_43
, retval
);
964 /* for the m68k machines */
966 #define PT_GETFPREGS -1
969 #define PT_SETFPREGS -1
972 static const int sreq2breq
[] = {
973 PT_TRACE_ME
, PT_READ_I
, PT_READ_D
, -1,
974 PT_WRITE_I
, PT_WRITE_D
, -1, PT_CONTINUE
,
975 PT_KILL
, -1, PT_ATTACH
, PT_DETACH
,
976 PT_GETREGS
, PT_SETREGS
, PT_GETFPREGS
, PT_SETFPREGS
978 static const int nreqs
= sizeof(sreq2breq
) / sizeof(sreq2breq
[0]);
981 sunos_sys_ptrace(struct lwp
*l
, const struct sunos_sys_ptrace_args
*uap
, register_t
*retval
)
983 struct sys_ptrace_args pa
;
986 #define sys_ptrace sysent[SYS_ptrace].sy_call
987 if (sys_ptrace
== sys_nosys
)
990 req
= SCARG(uap
, req
);
992 if (req
< 0 || req
>= nreqs
)
995 req
= sreq2breq
[req
];
999 SCARG(&pa
, req
) = req
;
1000 SCARG(&pa
, pid
) = (pid_t
)SCARG(uap
, pid
);
1001 SCARG(&pa
, addr
) = (void *)SCARG(uap
, addr
);
1002 SCARG(&pa
, data
) = SCARG(uap
, data
);
1004 return sys_ptrace(l
, &pa
, retval
);
1008 * SunOS reboot system call (for compatibility).
1009 * Sun lets you pass in a boot string which the PROM
1010 * saves and provides to the next boot program.
1013 #define SUNOS_RB_ASKNAME 0x001
1014 #define SUNOS_RB_SINGLE 0x002
1015 #define SUNOS_RB_NOSYNC 0x004
1016 #define SUNOS_RB_HALT 0x008
1017 #define SUNOS_RB_DUMP 0x080
1018 #define SUNOS_RB_STRING 0x200
1020 static struct sunos_howto_conv
{
1023 } sunos_howto_conv
[] = {
1024 { SUNOS_RB_ASKNAME
, RB_ASKNAME
},
1025 { SUNOS_RB_SINGLE
, RB_SINGLE
},
1026 { SUNOS_RB_NOSYNC
, RB_NOSYNC
},
1027 { SUNOS_RB_HALT
, RB_HALT
},
1028 { SUNOS_RB_DUMP
, RB_DUMP
},
1029 { SUNOS_RB_STRING
, RB_STRING
},
1034 sunos_sys_reboot(struct lwp
*l
, const struct sunos_sys_reboot_args
*uap
, register_t
*retval
)
1036 struct sys_reboot_args ua
;
1037 struct sunos_howto_conv
*convp
;
1038 int error
, bsd_howto
, sun_howto
;
1041 if ((error
= kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_REBOOT
,
1042 0, NULL
, NULL
, NULL
)) != 0)
1046 * Convert howto bits to BSD format.
1048 sun_howto
= SCARG(uap
, howto
);
1050 convp
= sunos_howto_conv
;
1051 while (convp
->sun_howto
) {
1052 if (sun_howto
& convp
->sun_howto
)
1053 bsd_howto
|= convp
->bsd_howto
;
1058 * Sun RB_STRING (Get user supplied bootstring.)
1059 * If the machine supports passing a string to the
1060 * next booted kernel.
1062 if (sun_howto
& SUNOS_RB_STRING
) {
1065 error
= copyinstr(SCARG(uap
, bootstr
), bs
, sizeof(bs
), 0);
1074 SCARG(&ua
, opt
) = bsd_howto
;
1075 SCARG(&ua
, bootstr
) = bootstr
;
1076 sys_reboot(l
, &ua
, retval
);
1081 * Generalized interface signal handler, 4.3-compatible.
1085 sunos_sys_sigvec(struct lwp
*l
, const struct sunos_sys_sigvec_args
*uap
, register_t
*retval
)
1088 syscallarg(int) signum;
1089 syscallarg(struct sigvec *) nsv;
1090 syscallarg(struct sigvec *) osv;
1092 struct sigvec nsv
, osv
;
1093 struct sigaction nsa
, osa
;
1095 /*XXX*/extern void compat_43_sigvec_to_sigaction
1096 (const struct sigvec
*, struct sigaction
*);
1097 /*XXX*/extern void compat_43_sigaction_to_sigvec
1098 (const struct sigaction
*, struct sigvec
*);
1100 if (SCARG(uap
, nsv
)) {
1101 error
= copyin(SCARG(uap
, nsv
), &nsv
, sizeof(nsv
));
1106 * SunOS uses the mask 0x0004 as SV_RESETHAND
1107 * meaning: `reset to SIG_DFL on delivery'.
1108 * We support only the bits in: 0xF
1109 * (those bits are the same as ours)
1111 if (nsv
.sv_flags
& ~0xF)
1114 compat_43_sigvec_to_sigaction(&nsv
, &nsa
);
1116 error
= sigaction1(l
, SCARG(uap
, signum
),
1117 SCARG(uap
, nsv
) ? &nsa
: 0,
1118 SCARG(uap
, osv
) ? &osa
: 0,
1123 if (SCARG(uap
, osv
)) {
1124 compat_43_sigaction_to_sigvec(&osa
, &osv
);
1125 error
= copyout(&osv
, SCARG(uap
, osv
), sizeof(osv
));