* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)sun_misc.c 8.2 (Berkeley) 9/23/93
* from: $Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp $
* SunOS compatibility module.
* SunOS system calls that are implemented differently in BSD are
#include <sys/filedesc.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <miscfs/specfs/specdev.h>
sun_wait4(p
, uap
, retval
)
struct sun_wait4_args
*uap
;
return (wait4(p
, uap
, retval
));
sun_creat(p
, uap
, retval
)
struct sun_creat_args
*uap
;
openuap
.fname
= uap
->fname
;
openuap
.crtmode
= uap
->fmode
;
openuap
.mode
= O_WRONLY
| O_CREAT
| O_TRUNC
;
return (open(p
, &openuap
, retval
));
char **envp
; /* pseudo */
sun_execv(p
, uap
, retval
)
struct sun_execv_args
*uap
;
return (execve(p
, uap
, retval
));
sun_omsync(p
, uap
, retval
)
struct sun_omsync_args
*uap
;
return (msync(p
, uap
, retval
));
struct sun_unmount_args
{
sun_unmount(p
, uap
, retval
)
struct sun_unmount_args
*uap
;
return (unmount(p
, uap
, retval
));
if (error
= copyinstr((caddr_t
)*tptr
, in
, sizeof in
, (u_int
*)0))
if (strcmp(in
, "4.2") == 0 || strcmp(in
, "ufs") == 0)
else if (strcmp(in
, "nfs") == 0)
#define SUNM_RDONLY 0x01 /* mount fs read-only */
#define SUNM_NOSUID 0x02 /* mount fs with setuid disallowed */
#define SUNM_NEWTYPE 0x04 /* type is string (char *), not int */
#define SUNM_GRPID 0x08 /* (bsd semantics; ignored) */
#define SUNM_REMOUNT 0x10 /* update existing mount */
#define SUNM_NOSUB 0x20 /* prevent submounts (rejected) */
#define SUNM_MULTI 0x40 /* (ignored) */
#define SUNM_SYS5 0x80 /* Sys 5-specific semantics (rejected) */
sun_mount(p
, uap
, retval
)
struct sun_mount_args
*uap
;
int oflags
= uap
->flags
, nflags
, error
;
if (oflags
& (SUNM_NOSUB
| SUNM_SYS5
))
if (oflags
& SUNM_NEWTYPE
&& (error
= gettype(&uap
->type
)))
if (oflags
& SUNM_RDONLY
)
if (oflags
& SUNM_NOSUID
)
if (oflags
& SUNM_REMOUNT
)
return (mount(p
, uap
, retval
));
struct sun_sigpending_args
{
sun_sigpending(p
, uap
, retval
)
struct sun_sigpending_args
*uap
;
mask
= p
->p_siglist
& p
->p_sigmask
;
return (copyout(&mask
, uap
->mask
, sizeof(int)));
* Here is the sun layout. (Compare the BSD layout in <sys/dirent.h>.)
* We can assume big-endian, so the BSD d_type field is just the high
* byte of the SunOS d_namlen field, after adjusting for the extra "long".
* Read Sun-style directory entries. We suck them into kernel space so
* that they can be massaged before being copied out to user code. Like
* SunOS, we squish out `empty' entries.
* This is quite ugly, but what do you expect from compatibility code?
struct sun_getdents_args
{
sun_getdents(p
, uap
, retval
)
register struct sun_getdents_args
*uap
;
register struct vnode
*vp
;
register caddr_t inp
, buf
; /* BSD-format */
register int len
, reclen
; /* BSD-format */
register caddr_t outp
; /* Sun-format */
register int resid
; /* Sun-format */
off_t off
; /* true file offset */
long soff
; /* Sun file offset */
int buflen
, error
, eofflag
;
#define BSD_DIRENT(cp) ((struct dirent *)(cp))
#define SUN_RECLEN(reclen) (reclen + sizeof(long))
if ((error
= getvnode(p
->p_fd
, uap
->fd
, &fp
)) != 0)
if ((fp
->f_flag
& FREAD
) == 0)
vp
= (struct vnode
*)fp
->f_data
;
if (vp
->v_type
!= VDIR
) /* XXX vnode readdir op should do this */
buflen
= min(MAXBSIZE
, uap
->nbytes
);
buf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
auio
.uio_segflg
= UIO_SYSSPACE
;
* First we read into the malloc'ed buffer, then
* we massage it into user space, one record at a time.
if (error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
))
if ((len
= buflen
- auio
.uio_resid
) == 0)
for (; len
> 0; len
-= reclen
) {
reclen
= ((struct dirent
*)inp
)->d_reclen
;
off
+= reclen
; /* each entry points to next */
if (BSD_DIRENT(inp
)->d_fileno
== 0) {
inp
+= reclen
; /* it is a hole; squish it out */
if (reclen
> len
|| resid
< SUN_RECLEN(reclen
)) {
/* entry too big for buffer, so just stop */
* Massage in place to make a Sun-shaped dirent (otherwise
* we have to worry about touching user memory outside of
BSD_DIRENT(inp
)->d_reclen
= SUN_RECLEN(reclen
);
BSD_DIRENT(inp
)->d_type
= 0;
if ((error
= copyout((caddr_t
)&soff
, outp
, sizeof soff
)) != 0 ||
(error
= copyout(inp
, outp
+ sizeof soff
, reclen
)) != 0)
/* advance past this real entry */
/* advance output past Sun-shaped entry */
outp
+= SUN_RECLEN(reclen
);
resid
-= SUN_RECLEN(reclen
);
/* if we squished out the whole block, try again */
fp
->f_offset
= off
; /* update the vnode offset */
*retval
= uap
->nbytes
- resid
;
char sun_domainname
[MAXDOMAINNAME
];
int sun_domainnamelen
= 1;
struct sun_getdomainname_args
{
sun_getdomainname(p
, uap
, retval
)
struct sun_getdomainname_args
*uap
;
register int l
= min(uap
->namelen
, sun_domainnamelen
+ 1);
return (copyout(sun_domainname
, uap
->name
, l
));
struct sun_setdomainname_args
{
sun_setdomainname(p
, uap
, retval
)
struct sun_setdomainname_args
*uap
;
register int l
= uap
->namelen
, error
;
return (EINVAL
); /* ??? ENAMETOOLONG? */
if (error
= suser(p
->p_ucred
, &p
->p_acflag
))
if (error
= copyin(uap
->name
, sun_domainname
, l
))
#define SUN_MMAP_MASK 0xf /* mask for SHARED/PRIVATE */
#define SUN_MMAP_CANDO 0x80000000 /* if not, old mmap & cannot handle */
#define DEVZERO makedev(3, 12) /* major,minor of /dev/zero */
#define SUN_MMAP_SAME (MAP_SHARED|MAP_PRIVATE|MAP_FIXED|MAP_INHERIT)
long off
; /* not off_t! */
quad_t qoff
; /* created here and fed to mmap() */
register struct sun_mmap_args
*uap
;
register struct filedesc
*fdp
;
register struct file
*fp
;
register struct vnode
*vp
;
if ((flags
& SUN_MMAP_CANDO
) == 0)
if ((flags
& SUN_MMAP_MASK
) != MAP_SHARED
&&
(flags
& SUN_MMAP_MASK
) != MAP_PRIVATE
)
flags
&= ~SUN_MMAP_CANDO
;
* Special case: if fd refers to /dev/zero, map as MAP_ANON. (XXX)
if ((unsigned)uap
->fd
< fdp
->fd_nfiles
&& /*XXX*/
(fp
= fdp
->fd_ofiles
[uap
->fd
]) != NULL
&& /*XXX*/
fp
->f_type
== DTYPE_VNODE
&& /*XXX*/
(vp
= (struct vnode
*)fp
->f_data
)->v_type
== VCHR
&& /*XXX*/
vp
->v_rdev
== DEVZERO
) { /*XXX*/
/* All done, fix up fields and go. */
uap
->qoff
= (quad_t
)uap
->off
;
return (mmap(p
, uap
, retval
));
register struct sun_mctl_args
*uap
;
case MC_ADVISE
: /* ignore for now */
case MC_SYNC
: /* translate to msync */
return (msync(p
, uap
, retval
));
struct sun_setsockopt_args
{
sun_setsockopt(p
, uap
, retval
)
register struct sun_setsockopt_args
*uap
;
if (error
= getsock(p
->p_fd
, uap
->s
, &fp
))
#define SO_DONTLINGER (~SO_LINGER)
if (uap
->name
== SO_DONTLINGER
) {
m
= m_get(M_WAIT
, MT_SOOPTS
);
mtod(m
, struct linger
*)->l_onoff
= 0;
m
->m_len
= sizeof(struct linger
);
return (sosetopt((struct socket
*)fp
->f_data
, uap
->level
,
m
= m_get(M_WAIT
, MT_SOOPTS
);
if (error
= copyin(uap
->val
, mtod(m
, caddr_t
),
return (sosetopt((struct socket
*)fp
->f_data
, uap
->level
,
struct sun_fchroot_args
{
sun_fchroot(p
, uap
, retval
)
register struct sun_fchroot_args
*uap
;
register struct filedesc
*fdp
= p
->p_fd
;
register struct vnode
*vp
;
if ((error
= suser(p
->p_ucred
, &p
->p_acflag
)) != 0)
if ((error
= getvnode(fdp
, uap
->fdes
, &fp
)) != 0)
vp
= (struct vnode
*)fp
->f_data
;
error
= VOP_ACCESS(vp
, VEXEC
, p
->p_ucred
, p
);
if (fdp
->fd_rdir
!= NULL
)