The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/sunos/sunos_misc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: sunos_misc.c,v 1.161.4.1 2010/03/17 02:59:52 snj Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1992, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    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.
   10  *
   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.
   15  *
   16  * Redistribution and use in source and binary forms, with or without
   17  * modification, are permitted provided that the following conditions
   18  * are met:
   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.
   27  *
   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
   38  * SUCH DAMAGE.
   39  *
   40  *      @(#)sunos_misc.c        8.1 (Berkeley) 6/18/93
   41  *
   42  *      Header: sunos_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
   43  */
   44 
   45 /*
   46  * SunOS compatibility module.
   47  *
   48  * SunOS system calls that are implemented differently in BSD are
   49  * handled here.
   50  */
   51 
   52 #include <sys/cdefs.h>
   53 __KERNEL_RCSID(0, "$NetBSD: sunos_misc.c,v 1.161.4.1 2010/03/17 02:59:52 snj Exp $");
   54 
   55 #if defined(_KERNEL_OPT)
   56 #include "opt_nfsserver.h"
   57 #include "opt_ptrace.h"
   58 #include "fs_nfs.h"
   59 #endif
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/namei.h>
   64 #include <sys/proc.h>
   65 #include <sys/dirent.h>
   66 #include <sys/file.h>
   67 #include <sys/stat.h>
   68 #include <sys/filedesc.h>
   69 #include <sys/ioctl.h>
   70 #include <sys/kernel.h>
   71 #include <sys/reboot.h>
   72 #include <sys/malloc.h>
   73 #include <sys/mbuf.h>
   74 #include <sys/mman.h>
   75 #include <sys/mount.h>
   76 #include <sys/ptrace.h>
   77 #include <sys/resource.h>
   78 #include <sys/resourcevar.h>
   79 #include <sys/signal.h>
   80 #include <sys/signalvar.h>
   81 #include <sys/socket.h>
   82 #include <sys/tty.h>
   83 #include <sys/vnode.h>
   84 #include <sys/uio.h>
   85 #include <sys/wait.h>
   86 #include <sys/utsname.h>
   87 #include <sys/unistd.h>
   88 #include <sys/syscall.h>
   89 #include <sys/syscallargs.h>
   90 #include <sys/conf.h>
   91 #include <sys/socketvar.h>
   92 #include <sys/exec.h>
   93 #include <sys/swap.h>
   94 #include <sys/kauth.h>
   95 
   96 #include <compat/sys/signal.h>
   97 
   98 #include <compat/sunos/sunos.h>
   99 #include <compat/sunos/sunos_syscallargs.h>
  100 #include <compat/common/compat_util.h>
  101 #include <compat/sunos/sunos_dirent.h>
  102 #include <compat/sys/mount.h>
  103 
  104 #include <netinet/in.h>
  105 
  106 #include <miscfs/specfs/specdev.h>
  107 
  108 #include <nfs/rpcv2.h>
  109 #include <nfs/nfsproto.h>
  110 #include <nfs/nfs.h>
  111 #include <nfs/nfsmount.h>
  112 
  113 static int sunstatfs(struct statvfs *, void *);
  114 
  115 int
  116 sunos_sys_stime(struct lwp *l, const struct sunos_sys_stime_args *uap, register_t *retval)
  117 {
  118         struct timeval tv;
  119         int error;
  120 
  121         error = copyin(SCARG(uap, tp), &tv.tv_sec, sizeof(tv.tv_sec));
  122         if (error)
  123                 return error;
  124         tv.tv_usec = 0;
  125 
  126         return settimeofday1(&tv, false, NULL, l, true);
  127 }
  128 
  129 int
  130 sunos_sys_wait4(struct lwp *l, const struct sunos_sys_wait4_args *uap, register_t *retval)
  131 {
  132         struct sys_wait4_args bsd_ua;
  133 
  134         SCARG(&bsd_ua, pid) = SCARG(uap, pid) == 0 ? WAIT_ANY : SCARG(uap, pid);
  135         SCARG(&bsd_ua, status) = SCARG(uap, status);
  136         SCARG(&bsd_ua, options) = SCARG(uap, options);
  137         SCARG(&bsd_ua, rusage) = SCARG(uap, rusage);
  138 
  139         return (sys_wait4(l, &bsd_ua, retval));
  140 }
  141 
  142 int
  143 sunos_sys_creat(struct lwp *l, const struct sunos_sys_creat_args *uap, register_t *retval)
  144 {
  145         struct sys_open_args ouap;
  146 
  147         SCARG(&ouap, path) = SCARG(uap, path);
  148         SCARG(&ouap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
  149         SCARG(&ouap, mode) = SCARG(uap, mode);
  150 
  151         return (sys_open(l, &ouap, retval));
  152 }
  153 
  154 int
  155 sunos_sys_execv(struct lwp *l, const struct sunos_sys_execv_args *uap, register_t *retval)
  156 {
  157         /* {
  158                 syscallarg(const char *) path;
  159                 syscallarg(char **) argv;
  160         } */
  161         struct sys_execve_args ap;
  162 
  163         SCARG(&ap, path) = SCARG(uap, path);
  164         SCARG(&ap, argp) = SCARG(uap, argp);
  165         SCARG(&ap, envp) = NULL;
  166 
  167         return (sys_execve(l, &ap, retval));
  168 }
  169 
  170 int
  171 sunos_sys_execve(struct lwp *l, const struct sunos_sys_execve_args *uap, register_t *retval)
  172 {
  173         /* {
  174                 syscallarg(const char *) path;
  175                 syscallarg(char **) argv;
  176                 syscallarg(char **) envp;
  177         } */
  178         struct sys_execve_args ap;
  179 
  180         SCARG(&ap, path) = SCARG(uap, path);
  181         SCARG(&ap, argp) = SCARG(uap, argp);
  182         SCARG(&ap, envp) = SCARG(uap, envp);
  183 
  184         return (sys_execve(l, &ap, retval));
  185 }
  186 
  187 int
  188 sunos_sys_omsync(struct lwp *l, const struct sunos_sys_omsync_args *uap, register_t *retval)
  189 {
  190         struct sys___msync13_args ouap;
  191 
  192         SCARG(&ouap, addr) = SCARG(uap, addr);
  193         SCARG(&ouap, len) = SCARG(uap, len);
  194         SCARG(&ouap, flags) = SCARG(uap, flags);
  195 
  196         return (sys___msync13(l, &ouap, retval));
  197 }
  198 
  199 int
  200 sunos_sys_unmount(struct lwp *l, const struct sunos_sys_unmount_args *uap, register_t *retval)
  201 {
  202         struct sys_unmount_args ouap;
  203 
  204         SCARG(&ouap, path) = SCARG(uap, path);
  205         SCARG(&ouap, flags) = 0;
  206 
  207         return (sys_unmount(l, &ouap, retval));
  208 }
  209 
  210 /*
  211  * Conversion table for SunOS NFS mount flags.
  212  */
  213 static struct {
  214         int     sun_flg;
  215         int     bsd_flg;
  216 } sunnfs_flgtab[] = {
  217         { SUNNFS_SOFT,          NFSMNT_SOFT },
  218         { SUNNFS_WSIZE,         NFSMNT_WSIZE },
  219         { SUNNFS_RSIZE,         NFSMNT_RSIZE },
  220         { SUNNFS_TIMEO,         NFSMNT_TIMEO },
  221         { SUNNFS_RETRANS,       NFSMNT_RETRANS },
  222         { SUNNFS_HOSTNAME,      0 },                    /* Ignored */
  223         { SUNNFS_INT,           NFSMNT_INT },
  224         { SUNNFS_NOAC,          0 },                    /* Ignored */
  225         { SUNNFS_ACREGMIN,      0 },                    /* Ignored */
  226         { SUNNFS_ACREGMAX,      0 },                    /* Ignored */
  227         { SUNNFS_ACDIRMIN,      0 },                    /* Ignored */
  228         { SUNNFS_ACDIRMAX,      0 },                    /* Ignored */
  229         { SUNNFS_SECURE,        0 },                    /* Ignored */
  230         { SUNNFS_NOCTO,         0 },                    /* Ignored */
  231         { SUNNFS_POSIX,         0 }                     /* Ignored */
  232 };
  233 
  234 int
  235 sunos_sys_mount(struct lwp *l, const struct sunos_sys_mount_args *uap, register_t *retval)
  236 {
  237         int oflags = SCARG(uap, flags), nflags, error;
  238         char fsname[MFSNAMELEN];
  239         register_t dummy;
  240 
  241         if (oflags & (SUNM_NOSUB | SUNM_SYS5))
  242                 return (EINVAL);
  243         if ((oflags & SUNM_NEWTYPE) == 0)
  244                 return (EINVAL);
  245         nflags = 0;
  246         if (oflags & SUNM_RDONLY)
  247                 nflags |= MNT_RDONLY;
  248         if (oflags & SUNM_NOSUID)
  249                 nflags |= MNT_NOSUID;
  250         if (oflags & SUNM_REMOUNT)
  251                 nflags |= MNT_UPDATE;
  252 
  253         error = copyinstr(SCARG(uap, type), fsname, sizeof fsname, NULL);
  254         if (error)
  255                 return (error);
  256 
  257         if (strcmp(fsname, "nfs") == 0) {
  258                 struct sunos_nfs_args sna;
  259                 struct nfs_args na;
  260                 int n;
  261 
  262                 error = copyin(SCARG(uap, data), &sna, sizeof sna);
  263                 if (error)
  264                         return (error);
  265                 /* sa.sa_len = sizeof(sain); */
  266                 na.version = NFS_ARGSVERSION;
  267                 na.addr = (void *)sna.addr;
  268                 na.addrlen = sizeof(struct sockaddr);
  269                 na.sotype = SOCK_DGRAM;
  270                 na.proto = IPPROTO_UDP;
  271                 na.fh = sna.fh;
  272                 na.fhsize = NFSX_V2FH;
  273                 na.flags = 0;
  274                 n = sizeof(sunnfs_flgtab) / sizeof(sunnfs_flgtab[0]);
  275                 while (--n >= 0)
  276                         if (sna.flags & sunnfs_flgtab[n].sun_flg)
  277                                 na.flags |= sunnfs_flgtab[n].bsd_flg;
  278                 na.wsize = sna.wsize;
  279                 na.rsize = sna.rsize;
  280                 if (na.flags & NFSMNT_RSIZE) {
  281                         na.flags |= NFSMNT_READDIRSIZE;
  282                         na.readdirsize = na.rsize;
  283                 }
  284                 na.timeo = sna.timeo;
  285                 na.retrans = sna.retrans;
  286                 na.hostname = /* (char *)(u_long) */ sna.hostname;
  287 
  288                 return do_sys_mount(l, vfs_getopsbyname("nfs"), NULL,
  289                     SCARG(uap, dir), nflags, &na,
  290                     UIO_SYSSPACE, sizeof na, &dummy);
  291         }
  292 
  293         if (strcmp(fsname, "4.2") == 0)
  294                 strcpy(fsname, "ffs");
  295 
  296         return do_sys_mount(l, vfs_getopsbyname(fsname), NULL,
  297             SCARG(uap, dir), nflags, SCARG(uap, data),
  298             UIO_USERSPACE, 0, &dummy);
  299 }
  300 
  301 #if defined(NFS)
  302 int
  303 async_daemon(struct lwp *l, const void *v, register_t *retval)
  304 {
  305         struct sys_nfssvc_args ouap;
  306 
  307         SCARG(&ouap, flag) = NFSSVC_BIOD;
  308         SCARG(&ouap, argp) = NULL;
  309 
  310         return (sys_nfssvc(l, &ouap, retval));
  311 }
  312 #endif /* NFS */
  313 
  314 void    native_to_sunos_sigset(const sigset_t *, int *);
  315 void    sunos_to_native_sigset(const int, sigset_t *);
  316 
  317 inline void
  318 native_to_sunos_sigset(const sigset_t *ss, int *mask)
  319 {
  320         *mask = ss->__bits[0];
  321 }
  322 
  323 inline void
  324 sunos_to_native_sigset(const int mask, sigset_t *ss)
  325 {
  326 
  327         ss->__bits[0] = mask;
  328         ss->__bits[1] = 0;
  329         ss->__bits[2] = 0;
  330         ss->__bits[3] = 0;
  331 }
  332 
  333 int
  334 sunos_sys_sigpending(struct lwp *l, const struct sunos_sys_sigpending_args *uap, register_t *retval)
  335 {
  336         sigset_t ss;
  337         int mask;
  338 
  339         sigpending1(l, &ss);
  340         native_to_sunos_sigset(&ss, &mask);
  341 
  342         return (copyout((void *)&mask, (void *)SCARG(uap, mask), sizeof(int)));
  343 }
  344 
  345 int
  346 sunos_sys_sigsuspend(struct lwp *l, const struct sunos_sys_sigsuspend_args *uap, register_t *retval)
  347 {
  348         /* {
  349                 syscallarg(int) mask;
  350         } */
  351         int mask;
  352         sigset_t ss;
  353 
  354         mask = SCARG(uap, mask);
  355         sunos_to_native_sigset(mask, &ss);
  356         return (sigsuspend1(l, &ss));
  357 }
  358 
  359 /*
  360  * Read Sun-style directory entries.  We suck them into kernel space so
  361  * that they can be massaged before being copied out to user code.  Like
  362  * SunOS, we squish out `empty' entries.
  363  *
  364  * This is quite ugly, but what do you expect from compatibility code?
  365  */
  366 int
  367 sunos_sys_getdents(struct lwp *l, const struct sunos_sys_getdents_args *uap, register_t *retval)
  368 {
  369         struct dirent *bdp;
  370         struct vnode *vp;
  371         char *inp, *buf;        /* BSD-format */
  372         int len, reclen;        /* BSD-format */
  373         char *outp;             /* Sun-format */
  374         int resid, sunos_reclen;/* Sun-format */
  375         struct file *fp;
  376         struct uio auio;
  377         struct iovec aiov;
  378         struct sunos_dirent idb;
  379         off_t off;                      /* true file offset */
  380         int buflen, error, eofflag;
  381         off_t *cookiebuf, *cookie;
  382         int ncookies;
  383 
  384         if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
  385                 return (error);
  386 
  387         if ((fp->f_flag & FREAD) == 0) {
  388                 error = EBADF;
  389                 goto out1;
  390         }
  391 
  392         vp = fp->f_data;
  393         if (vp->v_type != VDIR) {
  394                 error = EINVAL;
  395                 goto out1;
  396         }
  397 
  398         buflen = min(MAXBSIZE, SCARG(uap, nbytes));
  399         buf = malloc(buflen, M_TEMP, M_WAITOK);
  400         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  401         off = fp->f_offset;
  402 again:
  403         aiov.iov_base = buf;
  404         aiov.iov_len = buflen;
  405         auio.uio_iov = &aiov;
  406         auio.uio_iovcnt = 1;
  407         auio.uio_rw = UIO_READ;
  408         auio.uio_resid = buflen;
  409         auio.uio_offset = off;
  410         UIO_SETUP_SYSSPACE(&auio);
  411         /*
  412          * First we read into the malloc'ed buffer, then
  413          * we massage it into user space, one record at a time.
  414          */
  415         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
  416             &ncookies);
  417         if (error)
  418                 goto out;
  419 
  420         inp = buf;
  421         outp = SCARG(uap, buf);
  422         resid = SCARG(uap, nbytes);
  423         if ((len = buflen - auio.uio_resid) == 0)
  424                 goto eof;
  425 
  426         for (cookie = cookiebuf; len > 0; len -= reclen) {
  427                 bdp = (struct dirent *)inp;
  428                 reclen = bdp->d_reclen;
  429                 if (reclen & 3)
  430                         panic("sunos_getdents");
  431                 if ((*cookie >> 32) != 0) {
  432                         compat_offseterr(vp, "sunos_getdents");
  433                         error = EINVAL;
  434                         goto out;
  435                 }
  436                 if (bdp->d_fileno == 0) {
  437                         inp += reclen;  /* it is a hole; squish it out */
  438                         if (cookie)
  439                                 off = *cookie++;
  440                         else
  441                                 off += reclen;
  442                         continue;
  443                 }
  444                 sunos_reclen = SUNOS_RECLEN(&idb, bdp->d_namlen);
  445                 if (reclen > len || resid < sunos_reclen) {
  446                         /* entry too big for buffer, so just stop */
  447                         outp++;
  448                         break;
  449                 }
  450                 if (cookie)
  451                         off = *cookie++;        /* each entry points to next */
  452                 else
  453                         off += reclen;
  454                 /*
  455                  * Massage in place to make a Sun-shaped dirent (otherwise
  456                  * we have to worry about touching user memory outside of
  457                  * the copyout() call).
  458                  */
  459                 idb.d_fileno = bdp->d_fileno;
  460                 idb.d_off = off;
  461                 idb.d_reclen = sunos_reclen;
  462                 idb.d_namlen = bdp->d_namlen;
  463                 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
  464                 if ((error = copyout((void *)&idb, outp, sunos_reclen)) != 0)
  465                         goto out;
  466                 /* advance past this real entry */
  467                 inp += reclen;
  468                 /* advance output past Sun-shaped entry */
  469                 outp += sunos_reclen;
  470                 resid -= sunos_reclen;
  471         }
  472 
  473         /* if we squished out the whole block, try again */
  474         if (outp == SCARG(uap, buf)) {
  475                 if (cookiebuf)
  476                         free(cookiebuf, M_TEMP);
  477                 cookiebuf = NULL;
  478                 goto again;
  479         }
  480         fp->f_offset = off;             /* update the vnode offset */
  481 
  482 eof:
  483         *retval = SCARG(uap, nbytes) - resid;
  484 out:
  485         VOP_UNLOCK(vp, 0);
  486         free(cookiebuf, M_TEMP);
  487         free(buf, M_TEMP);
  488  out1:
  489         fd_putfile(SCARG(uap, fd));
  490         return (error);
  491 }
  492 
  493 #define SUNOS__MAP_NEW  0x80000000      /* if not, old mmap & cannot handle */
  494 
  495 int
  496 sunos_sys_mmap(struct lwp *l, const struct sunos_sys_mmap_args *uap, register_t *retval)
  497 {
  498         struct sys_mmap_args ouap;
  499 
  500         /*
  501          * Verify the arguments.
  502          */
  503         if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
  504                 return (EINVAL);                        /* XXX still needed? */
  505 
  506         if ((SCARG(uap, flags) & SUNOS__MAP_NEW) == 0)
  507                 return (EINVAL);
  508 
  509         SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUNOS__MAP_NEW;
  510         SCARG(&ouap, addr) = SCARG(uap, addr);
  511         SCARG(&ouap, len) = SCARG(uap, len);
  512         SCARG(&ouap, prot) = SCARG(uap, prot);
  513         SCARG(&ouap, fd) = SCARG(uap, fd);
  514         SCARG(&ouap, pos) = SCARG(uap, pos);
  515 
  516         return (sys_mmap(l, &ouap, retval));
  517 }
  518 
  519 #define MC_SYNC         1
  520 #define MC_LOCK         2
  521 #define MC_UNLOCK       3
  522 #define MC_ADVISE       4
  523 #define MC_LOCKAS       5
  524 #define MC_UNLOCKAS     6
  525 
  526 int
  527 sunos_sys_mctl(struct lwp *l, const struct sunos_sys_mctl_args *uap, register_t *retval)
  528 {
  529 
  530         switch (SCARG(uap, func)) {
  531         case MC_ADVISE:         /* ignore for now */
  532                 return (0);
  533         case MC_SYNC:           /* translate to msync */
  534                 return (sys___msync13(l, (const void *)uap, retval));
  535         default:
  536                 return (EINVAL);
  537         }
  538 }
  539 
  540 int
  541 sunos_sys_setsockopt(struct lwp *l, const struct sunos_sys_setsockopt_args *uap, register_t *retval)
  542 {
  543         struct sockopt sopt;
  544         struct socket *so;
  545         int name = SCARG(uap, name);
  546         int error;
  547 
  548         /* fd_getsock() will use the descriptor for us */
  549         if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
  550                 return (error);
  551 #define SO_DONTLINGER (~SO_LINGER)
  552         if (name == SO_DONTLINGER) {
  553                 struct linger lg;
  554 
  555                 lg.l_onoff = 0;
  556                 error = so_setsockopt(l, so, SCARG(uap, level), SO_LINGER,
  557                     &lg, sizeof(lg));
  558                 goto out;
  559         }
  560         if (SCARG(uap, level) == IPPROTO_IP) {
  561 #define         SUNOS_IP_MULTICAST_IF           2
  562 #define         SUNOS_IP_MULTICAST_TTL          3
  563 #define         SUNOS_IP_MULTICAST_LOOP         4
  564 #define         SUNOS_IP_ADD_MEMBERSHIP         5
  565 #define         SUNOS_IP_DROP_MEMBERSHIP        6
  566                 static const int ipoptxlat[] = {
  567                         IP_MULTICAST_IF,
  568                         IP_MULTICAST_TTL,
  569                         IP_MULTICAST_LOOP,
  570                         IP_ADD_MEMBERSHIP,
  571                         IP_DROP_MEMBERSHIP
  572                 };
  573                 if (name >= SUNOS_IP_MULTICAST_IF &&
  574                     name <= SUNOS_IP_DROP_MEMBERSHIP) {
  575                         name = ipoptxlat[name - SUNOS_IP_MULTICAST_IF];
  576                 }
  577         }
  578         if (SCARG(uap, valsize) > MLEN) {
  579                 error = EINVAL;
  580                 goto out;
  581         }
  582         sockopt_init(&sopt, SCARG(uap, level), name, SCARG(uap, valsize));
  583         if (SCARG(uap, val)) {
  584                 error = copyin(SCARG(uap, val), sopt.sopt_data,
  585                     (u_int)SCARG(uap, valsize));
  586         }
  587         if (error == 0)
  588                 error = sosetopt(so, &sopt);
  589         sockopt_destroy(&sopt);
  590  out:
  591         fd_putfile(SCARG(uap, s));
  592         return (error);
  593 }
  594 
  595 static inline int sunos_sys_socket_common(struct lwp *, register_t *,
  596                                               int type);
  597 static inline int
  598 sunos_sys_socket_common(struct lwp *l, register_t *retval, int type)
  599 {
  600         struct socket *so;
  601         int error, fd;
  602 
  603         /* fd_getsock() will use the descriptor for us */
  604         fd = (int)*retval;
  605         if ((error = fd_getsock(fd, &so)) == 0) {
  606                 if (type == SOCK_DGRAM)
  607                         so->so_options |= SO_BROADCAST;
  608                 fd_putfile(fd);
  609         }
  610         return (error);
  611 }
  612 
  613 int
  614 sunos_sys_socket(struct lwp *l, const struct sunos_sys_socket_args *uap, register_t *retval)
  615 {
  616         /* {
  617                 syscallarg(int) domain;
  618                 syscallarg(int) type;
  619                 syscallarg(int) protocol;
  620         } */
  621         int error;
  622 
  623         error = compat_30_sys_socket(l, (const void *)uap, retval);
  624         if (error)
  625                 return (error);
  626         return sunos_sys_socket_common(l, retval, SCARG(uap, type));
  627 }
  628 
  629 int
  630 sunos_sys_socketpair(struct lwp *l, const struct sunos_sys_socketpair_args *uap, register_t *retval)
  631 {
  632         /* {
  633                 syscallarg(int) domain;
  634                 syscallarg(int) type;
  635                 syscallarg(int) protocol;
  636                 syscallarg(int *) rsv;
  637         } */
  638         int error;
  639 
  640         error = sys_socketpair(l, (const void *)uap, retval);
  641         if (error)
  642                 return (error);
  643         return sunos_sys_socket_common(l, retval, SCARG(uap, type));
  644 }
  645 
  646 /*
  647  * XXX: This needs cleaning up.
  648  */
  649 int
  650 sunos_sys_auditsys(struct lwp *l, const struct sunos_sys_auditsys_args *uap, register_t *retval)
  651 {
  652         return 0;
  653 }
  654 
  655 int
  656 sunos_sys_uname(struct lwp *l, const struct sunos_sys_uname_args *uap, register_t *retval)
  657 {
  658         struct sunos_utsname sut;
  659 
  660         memset(&sut, 0, sizeof(sut));
  661 
  662         memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1);
  663         memcpy(sut.nodename, hostname, sizeof(sut.nodename));
  664         sut.nodename[sizeof(sut.nodename)-1] = '\0';
  665         memcpy(sut.release, osrelease, sizeof(sut.release) - 1);
  666         memcpy(sut.version, "1", sizeof(sut.version) - 1);
  667         memcpy(sut.machine, machine, sizeof(sut.machine) - 1);
  668 
  669         return copyout((void *)&sut, (void *)SCARG(uap, name),
  670             sizeof(struct sunos_utsname));
  671 }
  672 
  673 int
  674 sunos_sys_setpgrp(struct lwp *l, const struct sunos_sys_setpgrp_args *uap, register_t *retval)
  675 {
  676         struct proc *p = l->l_proc;
  677 
  678         /*
  679          * difference to our setpgid call is to include backwards
  680          * compatibility to pre-setsid() binaries. Do setsid()
  681          * instead of setpgid() in those cases where the process
  682          * tries to create a new session the old way.
  683          */
  684         if (!SCARG(uap, pgid) &&
  685             (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid))
  686                 return sys_setsid(l, NULL, retval);
  687         else
  688                 return sys_setpgid(l, (const void *)uap, retval);
  689 }
  690 
  691 int
  692 sunos_sys_open(struct lwp *l, const struct sunos_sys_open_args *uap, register_t *retval)
  693 {
  694         struct proc *p = l->l_proc;
  695         struct sys_open_args open_ua;
  696         int smode, nmode;
  697         int noctty;
  698         int ret;
  699 
  700         /* convert mode into NetBSD mode */
  701         smode = SCARG(uap, flags);
  702         noctty = smode & 0x8000;
  703         nmode = smode &
  704                 (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800);
  705         nmode |= ((smode & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
  706         nmode |= ((smode & 0x0080) ? O_SHLOCK : 0);
  707         nmode |= ((smode & 0x0100) ? O_EXLOCK : 0);
  708         nmode |= ((smode & 0x2000) ? O_FSYNC : 0);
  709 
  710         SCARG(&open_ua, path) = SCARG(uap, path);
  711         SCARG(&open_ua, flags) = nmode;
  712         SCARG(&open_ua, mode) = SCARG(uap, mode);
  713         ret = sys_open(l, &open_ua, retval);
  714 
  715         /* XXXSMP */
  716         if (!ret && !noctty && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
  717                 file_t *fp;
  718                 int fd;
  719 
  720                 fd = (int)*retval;
  721                 fp = fd_getfile(fd);
  722 
  723                 /* ignore any error, just give it a try */
  724                 if (fp != NULL) {
  725                         if (fp->f_type == DTYPE_VNODE)
  726                                 (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, NULL);
  727                         fd_putfile(fd);
  728                 }
  729         }
  730         return ret;
  731 }
  732 
  733 #if defined (NFSSERVER)
  734 int
  735 sunos_sys_nfssvc(struct lwp *l, const struct sunos_sys_nfssvc_args *uap, register_t *retval)
  736 {
  737 #if 0
  738         struct proc *p = l->l_proc;
  739         struct emul *e = p->p_emul;
  740         struct sys_nfssvc_args outuap;
  741         struct sockaddr sa;
  742         int error;
  743         void *sg = stackgap_init(p, 0);
  744 
  745         memset(&outuap, 0, sizeof outuap);
  746         SCARG(&outuap, fd) = SCARG(uap, fd);
  747         SCARG(&outuap, mskval) = stackgap_alloc(p, &sg, sizeof(sa));
  748         SCARG(&outuap, msklen) = sizeof(sa);
  749         SCARG(&outuap, mtchval) = stackgap_alloc(p, &sg, sizeof(sa));
  750         SCARG(&outuap, mtchlen) = sizeof(sa);
  751 
  752         memset(&sa, 0, sizeof sa);
  753         if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen)))
  754                 return (error);
  755         if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen)))
  756                 return (error);
  757 
  758         return nfssvc(l, &outuap, retval);
  759 #else
  760         return (ENOSYS);
  761 #endif
  762 }
  763 #endif /* NFSSERVER */
  764 
  765 int
  766 sunos_sys_ustat(struct lwp *l, const struct sunos_sys_ustat_args *uap, register_t *retval)
  767 {
  768         struct sunos_ustat us;
  769         int error;
  770 
  771         memset(&us, 0, sizeof us);
  772 
  773         /*
  774          * XXX: should set f_tfree and f_tinode at least
  775          * How do we translate dev -> fstat? (and then to sunos_ustat)
  776          */
  777 
  778         if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0)
  779                 return (error);
  780         return 0;
  781 }
  782 
  783 int
  784 sunos_sys_quotactl(struct lwp *l, const struct sunos_sys_quotactl_args *uap, register_t *retval)
  785 {
  786 
  787         return EINVAL;
  788 }
  789 
  790 int
  791 sunos_sys_vhangup(struct lwp *l, const void *v, register_t *retval)
  792 {
  793         struct proc *p = l->l_proc;
  794         struct session *sp = p->p_session;
  795 
  796         if (sp->s_ttyvp == 0)
  797                 return 0;
  798 
  799         if (sp->s_ttyp && sp->s_ttyp->t_session == sp && sp->s_ttyp->t_pgrp)
  800                 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
  801 
  802         (void) ttywait(sp->s_ttyp);
  803         if (sp->s_ttyvp)
  804                 VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
  805         if (sp->s_ttyvp)
  806                 vrele(sp->s_ttyvp);
  807         sp->s_ttyvp = NULL;
  808 
  809         return 0;
  810 }
  811 
  812 static int
  813 sunstatfs(struct statvfs *sp, void *buf)
  814 {
  815         struct sunos_statfs ssfs;
  816 
  817         memset(&ssfs, 0, sizeof ssfs);
  818         ssfs.f_type = 0;
  819         ssfs.f_bsize = sp->f_bsize;
  820         ssfs.f_blocks = sp->f_blocks;
  821         ssfs.f_bfree = sp->f_bfree;
  822         ssfs.f_bavail = sp->f_bavail;
  823         ssfs.f_files = sp->f_files;
  824         ssfs.f_ffree = sp->f_ffree;
  825         ssfs.f_fsid = sp->f_fsidx;
  826         return copyout((void *)&ssfs, buf, sizeof ssfs);
  827 }
  828 
  829 int
  830 sunos_sys_statfs(struct lwp *l, const struct sunos_sys_statfs_args *uap, register_t *retval)
  831 {
  832         struct mount *mp;
  833         struct statvfs *sp;
  834         int error;
  835         struct nameidata nd;
  836 
  837         NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, UIO_USERSPACE,
  838             SCARG(uap, path));
  839         if ((error = namei(&nd)) != 0)
  840                 return (error);
  841         mp = nd.ni_vp->v_mount;
  842         sp = &mp->mnt_stat;
  843         vrele(nd.ni_vp);
  844         if ((error = VFS_STATVFS(mp, sp)) != 0)
  845                 return (error);
  846         sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
  847         return sunstatfs(sp, (void *)SCARG(uap, buf));
  848 }
  849 
  850 int
  851 sunos_sys_fstatfs(struct lwp *l, const struct sunos_sys_fstatfs_args *uap, register_t *retval)
  852 {
  853         file_t *fp;
  854         struct mount *mp;
  855         struct statvfs *sp;
  856         int error;
  857 
  858         /* fd_getvnode() will use the descriptor for us */
  859         if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
  860                 return (error);
  861         mp = ((struct vnode *)fp->f_data)->v_mount;
  862         sp = &mp->mnt_stat;
  863         if ((error = VFS_STATVFS(mp, sp)) != 0)
  864                 goto out;
  865         sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
  866         error = sunstatfs(sp, (void *)SCARG(uap, buf));
  867  out:
  868         fd_putfile(SCARG(uap, fd));
  869         return (error);
  870 }
  871 
  872 int
  873 sunos_sys_exportfs(struct lwp *l, const struct sunos_sys_exportfs_args *uap, register_t *retval)
  874 {
  875         /*
  876          * XXX: should perhaps translate into a mount(2)
  877          * with MOUNT_EXPORT?
  878          */
  879         return 0;
  880 }
  881 
  882 int
  883 sunos_sys_mknod(struct lwp *l, const struct sunos_sys_mknod_args *uap, register_t *retval)
  884 {
  885         struct sys_mkfifo_args fifo_ua;
  886 
  887         if (S_ISFIFO(SCARG(uap, mode))) {
  888                 SCARG(&fifo_ua, path) = SCARG(uap, path);
  889                 SCARG(&fifo_ua, mode) = SCARG(uap, mode);
  890                 return sys_mkfifo(l, &fifo_ua, retval);
  891         }
  892 
  893         return sys_mknod(l, (const struct sys_mknod_args *)uap, retval);
  894 }
  895 
  896 #define SUNOS_SC_ARG_MAX        1
  897 #define SUNOS_SC_CHILD_MAX      2
  898 #define SUNOS_SC_CLK_TCK        3
  899 #define SUNOS_SC_NGROUPS_MAX    4
  900 #define SUNOS_SC_OPEN_MAX       5
  901 #define SUNOS_SC_JOB_CONTROL    6
  902 #define SUNOS_SC_SAVED_IDS      7
  903 #define SUNOS_SC_VERSION        8
  904 
  905 int
  906 sunos_sys_sysconf(struct lwp *l, const struct sunos_sys_sysconf_args *uap, register_t *retval)
  907 {
  908 
  909         switch(SCARG(uap, name)) {
  910         case SUNOS_SC_ARG_MAX:
  911                 *retval = ARG_MAX;
  912                 break;
  913         case SUNOS_SC_CHILD_MAX:
  914                 *retval = maxproc;
  915                 break;
  916         case SUNOS_SC_CLK_TCK:
  917                 *retval = 60;           /* should this be `hz', ie. 100? */
  918                 break;
  919         case SUNOS_SC_NGROUPS_MAX:
  920                 *retval = NGROUPS_MAX;
  921                 break;
  922         case SUNOS_SC_OPEN_MAX:
  923                 *retval = maxfiles;
  924                 break;
  925         case SUNOS_SC_JOB_CONTROL:
  926                 *retval = 1;
  927                 break;
  928         case SUNOS_SC_SAVED_IDS:
  929 #ifdef _POSIX_SAVED_IDS
  930                 *retval = 1;
  931 #else
  932                 *retval = 0;
  933 #endif
  934                 break;
  935         case SUNOS_SC_VERSION:
  936                 *retval = 198808;
  937                 break;
  938         default:
  939                 return EINVAL;
  940         }
  941         return 0;
  942 }
  943 
  944 #define SUNOS_RLIMIT_NOFILE     6       /* Other RLIMIT_* are the same */
  945 #define SUNOS_RLIM_NLIMITS      7
  946 
  947 int
  948 sunos_sys_getrlimit(struct lwp *l, const struct sunos_sys_getrlimit_args *uap, register_t *retval)
  949 {
  950         struct compat_43_sys_getrlimit_args ua_43;
  951 
  952         SCARG(&ua_43, which) = SCARG(uap, which);
  953         SCARG(&ua_43, rlp) = SCARG(uap, rlp);
  954 
  955         if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
  956                 return EINVAL;
  957 
  958         if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
  959                 SCARG(&ua_43, which) = RLIMIT_NOFILE;
  960 
  961         return compat_43_sys_getrlimit(l, &ua_43, retval);
  962 }
  963 
  964 int
  965 sunos_sys_setrlimit(struct lwp *l, const struct sunos_sys_setrlimit_args *uap, register_t *retval)
  966 {
  967         struct compat_43_sys_setrlimit_args ua_43;
  968 
  969         SCARG(&ua_43, which) = SCARG(uap, which);
  970         SCARG(&ua_43, rlp) = SCARG(uap, rlp);
  971 
  972         if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
  973                 return EINVAL;
  974 
  975         if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
  976                 SCARG(&ua_43, which) = RLIMIT_NOFILE;
  977 
  978         return compat_43_sys_setrlimit(l, &ua_43, retval);
  979 }
  980 
  981 #if defined(PTRACE) || defined(_LKM)
  982 /* for the m68k machines */
  983 #ifndef PT_GETFPREGS
  984 #define PT_GETFPREGS -1
  985 #endif
  986 #ifndef PT_SETFPREGS
  987 #define PT_SETFPREGS -1
  988 #endif
  989 
  990 static const int sreq2breq[] = {
  991         PT_TRACE_ME,    PT_READ_I,      PT_READ_D,      -1,
  992         PT_WRITE_I,     PT_WRITE_D,     -1,             PT_CONTINUE,
  993         PT_KILL,        -1,             PT_ATTACH,      PT_DETACH,
  994         PT_GETREGS,     PT_SETREGS,     PT_GETFPREGS,   PT_SETFPREGS
  995 };
  996 static const int nreqs = sizeof(sreq2breq) / sizeof(sreq2breq[0]);
  997 #endif /* PTRACE || _LKM */
  998 
  999 int
 1000 sunos_sys_ptrace(struct lwp *l, const struct sunos_sys_ptrace_args *uap, register_t *retval)
 1001 {
 1002 #if defined(PTRACE) || defined(_LKM)
 1003         struct sys_ptrace_args pa;
 1004         int req;
 1005 
 1006 #ifdef _LKM
 1007 #define sys_ptrace sysent[SYS_ptrace].sy_call 
 1008         if (sys_ptrace == sys_nosys)
 1009                 return ENOSYS;
 1010 #endif
 1011 
 1012         req = SCARG(uap, req);
 1013 
 1014         if (req < 0 || req >= nreqs)
 1015                 return (EINVAL);
 1016 
 1017         req = sreq2breq[req];
 1018         if (req == -1)
 1019                 return (EINVAL);
 1020 
 1021         SCARG(&pa, req) = req;
 1022         SCARG(&pa, pid) = (pid_t)SCARG(uap, pid);
 1023         SCARG(&pa, addr) = (void *)SCARG(uap, addr);
 1024         SCARG(&pa, data) = SCARG(uap, data);
 1025 
 1026         return sys_ptrace(l, &pa, retval);
 1027 #else
 1028         return ENOSYS;
 1029 #endif /* PTRACE || _LKM */
 1030 }
 1031 
 1032 /*
 1033  * SunOS reboot system call (for compatibility).
 1034  * Sun lets you pass in a boot string which the PROM
 1035  * saves and provides to the next boot program.
 1036  */
 1037 
 1038 #define SUNOS_RB_ASKNAME        0x001
 1039 #define SUNOS_RB_SINGLE         0x002
 1040 #define SUNOS_RB_NOSYNC         0x004
 1041 #define SUNOS_RB_HALT           0x008
 1042 #define SUNOS_RB_DUMP           0x080
 1043 #define SUNOS_RB_STRING         0x200
 1044 
 1045 static struct sunos_howto_conv {
 1046         int sun_howto;
 1047         int bsd_howto;
 1048 } sunos_howto_conv[] = {
 1049         { SUNOS_RB_ASKNAME,     RB_ASKNAME },
 1050         { SUNOS_RB_SINGLE,      RB_SINGLE },
 1051         { SUNOS_RB_NOSYNC,      RB_NOSYNC },
 1052         { SUNOS_RB_HALT,        RB_HALT },
 1053         { SUNOS_RB_DUMP,        RB_DUMP },
 1054         { SUNOS_RB_STRING,      RB_STRING },
 1055         { 0x000,                0 },
 1056 };
 1057 
 1058 int
 1059 sunos_sys_reboot(struct lwp *l, const struct sunos_sys_reboot_args *uap, register_t *retval)
 1060 {
 1061         struct sys_reboot_args ua;
 1062         struct sunos_howto_conv *convp;
 1063         int error, bsd_howto, sun_howto;
 1064         char *bootstr;
 1065 
 1066         if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_REBOOT,
 1067             0, NULL, NULL, NULL)) != 0)
 1068                 return (error);
 1069 
 1070         /*
 1071          * Convert howto bits to BSD format.
 1072          */
 1073         sun_howto = SCARG(uap, howto);
 1074         bsd_howto = 0;
 1075         convp = sunos_howto_conv;
 1076         while (convp->sun_howto) {
 1077                 if (sun_howto & convp->sun_howto)
 1078                         bsd_howto |= convp->bsd_howto;
 1079                 convp++;
 1080         }
 1081 
 1082         /*
 1083          * Sun RB_STRING (Get user supplied bootstring.)
 1084          * If the machine supports passing a string to the
 1085          * next booted kernel.
 1086          */
 1087         if (sun_howto & SUNOS_RB_STRING) {
 1088                 char bs[128];
 1089 
 1090                 error = copyinstr(SCARG(uap, bootstr), bs, sizeof(bs), 0);
 1091 
 1092                 if (error)
 1093                         bootstr = NULL;
 1094                 else
 1095                         bootstr = bs;
 1096         } else
 1097                 bootstr = NULL;
 1098 
 1099         SCARG(&ua, opt) = bsd_howto;
 1100         SCARG(&ua, bootstr) = bootstr;
 1101         sys_reboot(l, &ua, retval);
 1102         return(0);
 1103 }
 1104 
 1105 /*
 1106  * Generalized interface signal handler, 4.3-compatible.
 1107  */
 1108 /* ARGSUSED */
 1109 int
 1110 sunos_sys_sigvec(struct lwp *l, const struct sunos_sys_sigvec_args *uap, register_t *retval)
 1111 {
 1112         /* {
 1113                 syscallarg(int) signum;
 1114                 syscallarg(struct sigvec *) nsv;
 1115                 syscallarg(struct sigvec *) osv;
 1116         } */
 1117         struct sigvec nsv, osv;
 1118         struct sigaction nsa, osa;
 1119         int error;
 1120 /*XXX*/extern   void compat_43_sigvec_to_sigaction
 1121 (const struct sigvec *, struct sigaction *);
 1122 /*XXX*/extern   void compat_43_sigaction_to_sigvec
 1123 (const struct sigaction *, struct sigvec *);
 1124 
 1125         if (SCARG(uap, nsv)) {
 1126                 error = copyin(SCARG(uap, nsv), &nsv, sizeof(nsv));
 1127                 if (error != 0)
 1128                         return (error);
 1129 
 1130                 /*
 1131                  * SunOS uses the mask 0x0004 as SV_RESETHAND
 1132                  * meaning: `reset to SIG_DFL on delivery'.
 1133                  * We support only the bits in: 0xF
 1134                  * (those bits are the same as ours)
 1135                  */
 1136                 if (nsv.sv_flags & ~0xF)
 1137                         return (EINVAL);
 1138 
 1139                 compat_43_sigvec_to_sigaction(&nsv, &nsa);
 1140         }
 1141         error = sigaction1(l, SCARG(uap, signum),
 1142                            SCARG(uap, nsv) ? &nsa : 0,
 1143                            SCARG(uap, osv) ? &osa : 0,
 1144                            NULL, 0);
 1145         if (error != 0)
 1146                 return (error);
 1147 
 1148         if (SCARG(uap, osv)) {
 1149                 compat_43_sigaction_to_sigvec(&osa, &osv);
 1150                 error = copyout(&osv, SCARG(uap, osv), sizeof(osv));
 1151                 if (error != 0)
 1152                         return (error);
 1153         }
 1154 
 1155         return (0);
 1156 }

Cache object: 12c944655769b5f338e1334c912f1b29


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.