root/compat/sunos/sunos_misc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sunos_sys_wait4
  2. sunos_sys_creat
  3. sunos_sys_access
  4. sunos_sys_stat
  5. sunos_sys_lstat
  6. sunos_sys_execve
  7. sunos_sys_execv
  8. sunos_sys_unmount
  9. sunos_sys_mount
  10. async_daemon
  11. sunos_sys_sigpending
  12. sunos_readdir_callback
  13. sunos_sys_getdents
  14. sunos_sys_mmap
  15. sunos_sys_mctl
  16. sunos_sys_setsockopt
  17. sunos_sys_fchroot
  18. sunos_sys_auditsys
  19. sunos_sys_uname
  20. sunos_sys_setpgrp
  21. sunos_sys_open
  22. sunos_sys_nfssvc
  23. sunos_sys_ustat
  24. sunos_sys_quotactl
  25. sunos_sys_vhangup
  26. sunstatfs
  27. sunos_sys_statfs
  28. sunos_sys_fstatfs
  29. sunos_sys_exportfs
  30. sunos_sys_mknod
  31. sunos_sys_sysconf
  32. sunos_sys_getrlimit
  33. sunos_sys_setrlimit
  34. sunos_sys_ptrace
  35. sunos_sys_reboot
  36. sunos_sys_sigvec
  37. sunos_sys_ostime
  38. sunos_sys_otimes

    1 /*      $OpenBSD: sunos_misc.c,v 1.46 2004/06/24 19:35:23 tholo Exp $   */
    2 /*      $NetBSD: sunos_misc.c,v 1.65 1996/04/22 01:44:31 christos Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1992, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * This software was developed by the Computer Systems Engineering group
    9  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
   10  * contributed to Berkeley.
   11  *
   12  * All advertising materials mentioning features or use of this software
   13  * must display the following acknowledgement:
   14  *      This product includes software developed by the University of
   15  *      California, Lawrence Berkeley Laboratory.
   16  *
   17  * Redistribution and use in source and binary forms, with or without
   18  * modification, are permitted provided that the following conditions
   19  * are met:
   20  * 1. Redistributions of source code must retain the above copyright
   21  *    notice, this list of conditions and the following disclaimer.
   22  * 2. Redistributions in binary form must reproduce the above copyright
   23  *    notice, this list of conditions and the following disclaimer in the
   24  *    documentation and/or other materials provided with the distribution.
   25  * 3. Neither the name of the University nor the names of its contributors
   26  *    may be used to endorse or promote products derived from this software
   27  *    without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  *      @(#)sunos_misc.c        8.1 (Berkeley) 6/18/93
   42  *
   43  *      Header: sunos_misc.c,v 1.16 93/04/07 02:46:27 torek Exp 
   44  */
   45 
   46 /*
   47  * SunOS compatibility module.
   48  *
   49  * SunOS system calls that are implemented differently in BSD are
   50  * handled here.
   51  */
   52 
   53 #include <sys/param.h>
   54 #include <sys/systm.h>
   55 #include <sys/namei.h>
   56 #include <sys/proc.h>
   57 #include <sys/dirent.h>
   58 #include <sys/file.h>
   59 #include <sys/stat.h>
   60 #include <sys/filedesc.h>
   61 #include <sys/ioctl.h>
   62 #include <sys/kernel.h>
   63 #include <sys/reboot.h>
   64 #include <sys/malloc.h>
   65 #include <sys/mbuf.h>
   66 #include <sys/mman.h>
   67 #include <sys/mount.h>
   68 #include <sys/ptrace.h>
   69 #include <sys/resource.h>
   70 #include <sys/resourcevar.h>
   71 #include <sys/signal.h>
   72 #include <sys/signalvar.h>
   73 #include <sys/socket.h>
   74 #include <sys/tty.h>
   75 #include <sys/vnode.h>
   76 #include <sys/uio.h>
   77 #include <sys/wait.h>
   78 #include <sys/utsname.h>
   79 #include <sys/unistd.h>
   80 #include <sys/syscallargs.h>
   81 #include <sys/conf.h>
   82 #include <sys/socketvar.h>
   83 #include <sys/times.h>
   84 
   85 #include <compat/sunos/sunos.h>
   86 #include <compat/sunos/sunos_syscallargs.h>
   87 #include <compat/sunos/sunos_util.h>
   88 #include <compat/sunos/sunos_dirent.h>
   89 
   90 #include <compat/common/compat_dir.h>
   91 
   92 #include <netinet/in.h>
   93 
   94 #include <miscfs/specfs/specdev.h>
   95 
   96 #include <nfs/rpcv2.h>
   97 #include <nfs/nfsproto.h>
   98 #include <nfs/nfs.h>
   99 
  100 #include <uvm/uvm_extern.h>
  101 
  102 #ifdef sun3
  103 # include <machine/machdep.h>   /* for prototype of reboot2() */
  104 #endif
  105 
  106 static int sunstatfs(struct statfs *, caddr_t);
  107 
  108 int
  109 sunos_sys_wait4(p, v, retval)
  110         struct proc *p;
  111         void *v;
  112         register_t *retval;
  113 {
  114         struct sunos_sys_wait4_args *uap = v;
  115         if (SCARG(uap, pid) == 0)
  116                 SCARG(uap, pid) = WAIT_ANY;
  117         return (sys_wait4(p, uap, retval));
  118 }
  119 
  120 int
  121 sunos_sys_creat(p, v, retval)
  122         struct proc *p;
  123         void *v;
  124         register_t *retval;
  125 {
  126         struct sunos_sys_creat_args *uap = v;
  127         struct sys_open_args ouap;
  128 
  129         caddr_t sg = stackgap_init(p->p_emul);
  130         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  131 
  132         SCARG(&ouap, path) = SCARG(uap, path);
  133         SCARG(&ouap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
  134         SCARG(&ouap, mode) = SCARG(uap, mode);
  135 
  136         return (sys_open(p, &ouap, retval));
  137 }
  138 
  139 int
  140 sunos_sys_access(p, v, retval)
  141         struct proc *p;
  142         void *v;
  143         register_t *retval;
  144 {
  145         struct sunos_sys_access_args *uap = v;
  146         caddr_t sg = stackgap_init(p->p_emul);
  147         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  148 
  149         return (sys_access(p, uap, retval));
  150 }
  151 
  152 int
  153 sunos_sys_stat(p, v, retval)
  154         struct proc *p;
  155         void *v;
  156         register_t *retval;
  157 {
  158         struct sunos_sys_stat_args *uap = v;
  159         caddr_t sg = stackgap_init(p->p_emul);
  160         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  161 
  162         return (compat_43_sys_stat(p, uap, retval));
  163 }
  164 
  165 int
  166 sunos_sys_lstat(p, v, retval)
  167         struct proc *p;
  168         void *v;
  169         register_t *retval;
  170 {
  171         struct sunos_sys_lstat_args *uap = v;
  172         caddr_t sg = stackgap_init(p->p_emul);
  173         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  174 
  175         return (compat_43_sys_lstat(p, uap, retval));
  176 }
  177 
  178 int
  179 sunos_sys_execve(p, v, retval)
  180         struct proc *p;
  181         void *v;
  182         register_t *retval;
  183 {
  184         struct sunos_sys_execve_args /* {
  185                 syscallarg(char *) path;
  186                 syscallarg(char **) argv;
  187                 syscallarg(char **) envp;
  188         } */ *uap = v;
  189         struct sys_execve_args ap;
  190         caddr_t sg;
  191 
  192         sg = stackgap_init(p->p_emul);
  193         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  194 
  195         SCARG(&ap, path) = SCARG(uap, path);
  196         SCARG(&ap, argp) = SCARG(uap, argp);
  197         SCARG(&ap, envp) = SCARG(uap, envp);
  198 
  199         return (sys_execve(p, &ap, retval));
  200 }
  201 
  202 int
  203 sunos_sys_execv(p, v, retval)
  204         struct proc *p;
  205         void *v;
  206         register_t *retval;
  207 {
  208         struct sunos_sys_execv_args *uap = v;
  209         struct sys_execve_args ouap;
  210 
  211         caddr_t sg = stackgap_init(p->p_emul);
  212         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  213 
  214         SCARG(&ouap, path) = SCARG(uap, path);
  215         SCARG(&ouap, argp) = SCARG(uap, argp);
  216         SCARG(&ouap, envp) = NULL;
  217 
  218         return (sys_execve(p, &ouap, retval));
  219 }
  220 
  221 int
  222 sunos_sys_unmount(p, v, retval)
  223         struct proc *p;
  224         void *v;
  225         register_t *retval;
  226 {
  227         struct sunos_sys_unmount_args *uap = v;
  228         struct sys_unmount_args ouap;
  229 
  230         SCARG(&ouap, path) = SCARG(uap, path);
  231         SCARG(&ouap, flags) = 0;
  232 
  233         return (sys_unmount(p, &ouap, retval));
  234 }
  235 
  236 /*
  237  * Conversion table for SunOS NFS mount flags.
  238  */
  239 static struct {
  240         int     sun_flg;
  241         int     bsd_flg;
  242 } sunnfs_flgtab[] = {
  243         { SUNNFS_SOFT,          NFSMNT_SOFT },
  244         { SUNNFS_WSIZE,         NFSMNT_WSIZE },
  245         { SUNNFS_RSIZE,         NFSMNT_RSIZE },
  246         { SUNNFS_TIMEO,         NFSMNT_TIMEO },
  247         { SUNNFS_RETRANS,       NFSMNT_RETRANS },
  248         { SUNNFS_HOSTNAME,      0 },                    /* Ignored */
  249         { SUNNFS_INT,           NFSMNT_INT },
  250         { SUNNFS_NOAC,          0 },                    /* Ignored */
  251         { SUNNFS_ACREGMIN,      0 },                    /* Ignored */
  252         { SUNNFS_ACREGMAX,      0 },                    /* Ignored */
  253         { SUNNFS_ACDIRMIN,      0 },                    /* Ignored */
  254         { SUNNFS_ACDIRMAX,      0 },                    /* Ignored */
  255         { SUNNFS_SECURE,        0 },                    /* Ignored */
  256         { SUNNFS_NOCTO,         0 },                    /* Ignored */
  257         { SUNNFS_POSIX,         0 }                     /* Ignored */
  258 };
  259 
  260 int
  261 sunos_sys_mount(p, v, retval)
  262         struct proc *p;
  263         void *v;
  264         register_t *retval;
  265 {
  266         struct sunos_sys_mount_args *uap = v;
  267         int oflags = SCARG(uap, flags), nflags, error;
  268         char fsname[MFSNAMELEN];
  269         caddr_t sg = stackgap_init(p->p_emul);
  270 
  271         if (oflags & (SUNM_NOSUB | SUNM_SYS5))
  272                 return (EINVAL);
  273         if ((oflags & SUNM_NEWTYPE) == 0)
  274                 return (EINVAL);
  275         nflags = 0;
  276         if (oflags & SUNM_RDONLY)
  277                 nflags |= MNT_RDONLY;
  278         if (oflags & SUNM_NOSUID)
  279                 nflags |= MNT_NOSUID;
  280         if (oflags & SUNM_REMOUNT)
  281                 nflags |= MNT_UPDATE;
  282         SCARG(uap, flags) = nflags;
  283 
  284         error = copyinstr((caddr_t)SCARG(uap, type), fsname,
  285             sizeof fsname, (size_t *)0);
  286         if (error)
  287                 return (error);
  288 
  289         if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
  290                 SCARG(uap, type) = stackgap_alloc(&sg, sizeof("ffs"));
  291                 error = copyout("ffs", SCARG(uap, type), sizeof("ffs"));
  292                 if (error)
  293                         return (error);
  294         } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
  295                 struct sunos_nfs_args sna;
  296                 struct sockaddr_in sain;
  297                 struct nfs_args na;
  298                 struct sockaddr sa;
  299                 int n;
  300 
  301                 error = copyin(SCARG(uap, data), &sna, sizeof sna);
  302                 if (error)
  303                         return (error);
  304                 error = copyin(sna.addr, &sain, sizeof sain);
  305                 if (error)
  306                         return (error);
  307                 bcopy(&sain, &sa, sizeof sa);
  308                 sa.sa_len = sizeof(sain);
  309                 SCARG(uap, data) = stackgap_alloc(&sg, sizeof(na));
  310                 na.version = NFS_ARGSVERSION;
  311                 na.addr = stackgap_alloc(&sg, sizeof(struct sockaddr));
  312                 na.addrlen = sizeof(struct sockaddr);
  313                 na.sotype = SOCK_DGRAM;
  314                 na.proto = IPPROTO_UDP;
  315                 na.fh = (void *)sna.fh;
  316                 na.fhsize = NFSX_V2FH;
  317                 na.flags = 0;
  318                 n = sizeof(sunnfs_flgtab) / sizeof(sunnfs_flgtab[0]);
  319                 while (--n >= 0)
  320                         if (sna.flags & sunnfs_flgtab[n].sun_flg)
  321                                 na.flags |= sunnfs_flgtab[n].bsd_flg;
  322                 na.wsize = sna.wsize;
  323                 na.rsize = sna.rsize;
  324                 if (na.flags & NFSMNT_RSIZE) {
  325                         na.flags |= NFSMNT_READDIRSIZE;
  326                         na.readdirsize = na.rsize;
  327                 }
  328                 na.timeo = sna.timeo;
  329                 na.retrans = sna.retrans;
  330                 na.hostname = sna.hostname;
  331 
  332                 error = copyout(&sa, na.addr, sizeof sa);
  333                 if (error)
  334                         return (error);
  335                 error = copyout(&na, SCARG(uap, data), sizeof na);
  336                 if (error)
  337                         return (error);
  338         }
  339         return (sys_mount(p, (struct sys_mount_args *)uap, retval));
  340 }
  341 
  342 #if defined(NFSCLIENT)
  343 int
  344 async_daemon(p, v, retval)
  345         struct proc *p;
  346         void *v;
  347         register_t *retval;
  348 {
  349         struct sys_nfssvc_args ouap;
  350 
  351         SCARG(&ouap, flag) = NFSSVC_BIOD;
  352         SCARG(&ouap, argp) = NULL;
  353 
  354         return (sys_nfssvc(p, &ouap, retval));
  355 }
  356 #endif /* NFSCLIENT */
  357 
  358 int
  359 sunos_sys_sigpending(p, v, retval)
  360         struct proc *p;
  361         void *v;
  362         register_t *retval;
  363 {
  364         struct sunos_sys_sigpending_args *uap = v;
  365         int mask = p->p_siglist & p->p_sigmask;
  366 
  367         return (copyout((caddr_t)&mask, (caddr_t)SCARG(uap, mask), sizeof(int)));
  368 }
  369 
  370 /*
  371  * Read Sun-style directory entries.  We suck them into kernel space so
  372  * that they can be massaged before being copied out to user code.  Like
  373  * SunOS, we squish out `empty' entries.
  374  *
  375  * This is quite ugly, but what do you expect from compatibility code?
  376  */
  377 int sunos_readdir_callback(void *, struct dirent *, off_t);
  378 
  379 struct sunos_readdir_callback_args {
  380         caddr_t outp;
  381         int     resid;
  382 };
  383 
  384 int
  385 sunos_readdir_callback(arg, bdp, cookie)
  386         void *arg;
  387         struct dirent *bdp;
  388         off_t cookie;
  389 {
  390         struct sunos_dirent idb;
  391         struct sunos_readdir_callback_args *cb = arg; 
  392         int sunos_reclen;
  393         int error;
  394 
  395         sunos_reclen = SUNOS_RECLEN(&idb, bdp->d_namlen);
  396         if (cb->resid < sunos_reclen)
  397                 return (ENOMEM);
  398         
  399         idb.d_fileno = bdp->d_fileno;
  400         idb.d_off = cookie;
  401         idb.d_reclen = sunos_reclen;
  402         idb.d_namlen = bdp->d_namlen;
  403         strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
  404 
  405         if ((error = copyout((caddr_t)&idb, cb->outp, sunos_reclen)))
  406                 return (error);
  407 
  408         cb->outp += sunos_reclen;
  409         cb->resid -= sunos_reclen;
  410 
  411         return (0);
  412 }
  413 
  414 int
  415 sunos_sys_getdents(p, v, retval)
  416         struct proc *p;
  417         void *v;
  418         register_t *retval;
  419 {
  420         struct sunos_sys_getdents_args /* {
  421                 syscallarg(int) fd;
  422                 syscallarg(char *) buf;
  423                 syscallarg(int) nbytes;
  424         } */ *uap = v;
  425         struct vnode *vp;
  426         struct file *fp;
  427         int error;
  428         struct sunos_readdir_callback_args args;
  429 
  430         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
  431                 return (error);
  432 
  433         vp = (struct vnode *)fp->f_data;
  434         /* SunOS returns ENOTDIR here, BSD would use EINVAL */
  435         if (vp->v_type != VDIR) {
  436                 error = ENOTDIR;
  437                 goto bad;
  438         }
  439 
  440         args.resid = SCARG(uap, nbytes);
  441         args.outp = (caddr_t)SCARG(uap, buf);
  442 
  443         error = readdir_with_callback(fp, &fp->f_offset, args.resid,
  444             sunos_readdir_callback, &args);
  445 bad:
  446         FRELE(fp);
  447         if (error)
  448                 return (error);
  449 
  450         *retval = SCARG(uap, nbytes) - args.resid;
  451 
  452         return (0);
  453 }
  454 
  455 
  456 #define SUNOS__MAP_NEW  0x80000000      /* if not, old mmap & cannot handle */
  457 
  458 int
  459 sunos_sys_mmap(p, v, retval)
  460         struct proc *p;
  461         void *v;
  462         register_t *retval;
  463 {
  464         struct sunos_sys_mmap_args *uap = v;
  465         struct sys_mmap_args ouap;
  466 
  467         /*
  468          * Verify the arguments.
  469          */
  470         if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
  471                 return (EINVAL);                        /* XXX still needed? */
  472 
  473         if ((SCARG(uap, flags) & SUNOS__MAP_NEW) == 0)
  474                 return (EINVAL);
  475 
  476         SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUNOS__MAP_NEW;
  477         SCARG(&ouap, addr) = SCARG(uap, addr);
  478 
  479         if ((SCARG(&ouap, flags) & MAP_FIXED) == 0 &&
  480             SCARG(&ouap, addr) != 0 &&
  481             SCARG(&ouap, addr) < (void *)round_page((vaddr_t)p->p_vmspace->vm_daddr+MAXDSIZ))
  482                 SCARG(&ouap, addr) = (void *)round_page((vaddr_t)p->p_vmspace->vm_daddr+MAXDSIZ);
  483 
  484         SCARG(&ouap, len) = SCARG(uap, len);
  485         SCARG(&ouap, prot) = SCARG(uap, prot);
  486         SCARG(&ouap, fd) = SCARG(uap, fd);
  487         SCARG(&ouap, pos) = SCARG(uap, pos);
  488 
  489         return (sys_mmap(p, &ouap, retval));
  490 }
  491 
  492 #define MC_SYNC         1
  493 #define MC_LOCK         2
  494 #define MC_UNLOCK       3
  495 #define MC_ADVISE       4
  496 #define MC_LOCKAS       5
  497 #define MC_UNLOCKAS     6
  498 
  499 int
  500 sunos_sys_mctl(p, v, retval)
  501         register struct proc *p;
  502         void *v;
  503         register_t *retval;
  504 {
  505         register struct sunos_sys_mctl_args *uap = v;
  506 
  507         switch (SCARG(uap, func)) {
  508         case MC_ADVISE:         /* ignore for now */
  509                 return (0);
  510         case MC_SYNC:           /* translate to msync */
  511                 return (sys_msync(p, uap, retval));
  512         default:
  513                 return (EINVAL);
  514         }
  515 }
  516 
  517 int
  518 sunos_sys_setsockopt(p, v, retval)
  519         struct proc *p;
  520         void *v;
  521         register_t *retval;
  522 {
  523         struct sunos_sys_setsockopt_args *uap = v;
  524         struct file *fp;
  525         struct mbuf *m = NULL;
  526         int error;
  527 
  528         if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
  529                 return (error);
  530 #define SO_DONTLINGER (~SO_LINGER)
  531         if (SCARG(uap, name) == SO_DONTLINGER) {
  532                 m = m_get(M_WAIT, MT_SOOPTS);
  533                 mtod(m, struct linger *)->l_onoff = 0;
  534                 m->m_len = sizeof(struct linger);
  535                 error = (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
  536                     SO_LINGER, m));
  537                 goto bad;
  538         }
  539         if (SCARG(uap, level) == IPPROTO_IP) {
  540 #define         SUNOS_IP_MULTICAST_IF           2
  541 #define         SUNOS_IP_MULTICAST_TTL          3
  542 #define         SUNOS_IP_MULTICAST_LOOP         4
  543 #define         SUNOS_IP_ADD_MEMBERSHIP         5
  544 #define         SUNOS_IP_DROP_MEMBERSHIP        6
  545                 static int ipoptxlat[] = {
  546                         IP_MULTICAST_IF,
  547                         IP_MULTICAST_TTL,
  548                         IP_MULTICAST_LOOP,
  549                         IP_ADD_MEMBERSHIP,
  550                         IP_DROP_MEMBERSHIP
  551                 };
  552                 if (SCARG(uap, name) >= SUNOS_IP_MULTICAST_IF &&
  553                     SCARG(uap, name) <= SUNOS_IP_DROP_MEMBERSHIP) {
  554                         SCARG(uap, name) =
  555                             ipoptxlat[SCARG(uap, name) - SUNOS_IP_MULTICAST_IF];
  556                 }
  557         }
  558         if (SCARG(uap, valsize) > MLEN) {
  559                 error = EINVAL;
  560                 goto bad;
  561         }
  562         if (SCARG(uap, val)) {
  563                 m = m_get(M_WAIT, MT_SOOPTS);
  564                 error = copyin(SCARG(uap, val), mtod(m, caddr_t),
  565                     (u_int)SCARG(uap, valsize));
  566                 if (error) {
  567                         (void) m_free(m);
  568                         goto bad;
  569                 }
  570                 m->m_len = SCARG(uap, valsize);
  571         }
  572         error = (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
  573             SCARG(uap, name), m));
  574 bad:
  575         FRELE(fp);
  576         return (error);
  577 }
  578 
  579 int
  580 sunos_sys_fchroot(p, v, retval)
  581         register struct proc *p;
  582         void *v;
  583         register_t *retval;
  584 {
  585         register struct sunos_sys_fchroot_args *uap = v;
  586         register struct filedesc *fdp = p->p_fd;
  587         register struct vnode *vp;
  588         struct file *fp;
  589         int error;
  590 
  591         if ((error = suser(p, 0)) != 0)
  592                 return (error);
  593         if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
  594                 return (error);
  595         vp = (struct vnode *)fp->f_data;
  596         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  597         if (vp->v_type != VDIR)
  598                 error = ENOTDIR;
  599         else
  600                 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
  601         VOP_UNLOCK(vp, 0, p);
  602         if (error) {
  603                 FRELE(fp);
  604                 return (error);
  605         }
  606         VREF(vp);
  607         if (fdp->fd_rdir != NULL)
  608                 vrele(fdp->fd_rdir);
  609         fdp->fd_rdir = vp;
  610         FRELE(fp);
  611         return (0);
  612 }
  613 
  614 /*
  615  * XXX: This needs cleaning up.
  616  */
  617 int
  618 sunos_sys_auditsys(p, v, retval)
  619         struct proc *p;
  620         void *v;
  621         register_t *retval;
  622 {
  623         return 0;
  624 }
  625 
  626 int
  627 sunos_sys_uname(p, v, retval)
  628         struct proc *p;
  629         void *v;
  630         register_t *retval;
  631 {
  632         struct sunos_sys_uname_args *uap = v;
  633         struct sunos_utsname sut;
  634         extern char machine[];
  635 
  636         bzero(&sut, sizeof(sut));
  637 
  638         bcopy(ostype, sut.sysname, sizeof(sut.sysname) - 1);
  639         bcopy(hostname, sut.nodename, sizeof(sut.nodename));
  640         sut.nodename[sizeof(sut.nodename)-1] = '\0';
  641         bcopy(osrelease, sut.release, sizeof(sut.release) - 1);
  642         strlcpy(sut.version, "1", sizeof(sut.version));
  643         bcopy(machine, sut.machine, sizeof(sut.machine) - 1);
  644 
  645         return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, name),
  646             sizeof(struct sunos_utsname));
  647 }
  648 
  649 int
  650 sunos_sys_setpgrp(p, v, retval)
  651         struct proc *p;
  652         void *v;
  653         register_t *retval;
  654 {
  655         struct sunos_sys_setpgrp_args *uap = v;
  656 
  657         /*
  658          * difference to our setpgid call is to include backwards
  659          * compatibility to pre-setsid() binaries. Do setsid()
  660          * instead of setpgid() in those cases where the process
  661          * tries to create a new session the old way.
  662          */
  663         if (!SCARG(uap, pgid) &&
  664             (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid))
  665                 return sys_setsid(p, uap, retval);
  666         else
  667                 return sys_setpgid(p, uap, retval);
  668 }
  669 
  670 int
  671 sunos_sys_open(p, v, retval)
  672         struct proc *p;
  673         void *v;
  674         register_t *retval;
  675 {
  676         struct sunos_sys_open_args *uap = v;
  677         int l, r;
  678         int noctty;
  679         int ret;
  680         
  681         caddr_t sg = stackgap_init(p->p_emul);
  682         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  683 
  684         /* convert mode into NetBSD mode */
  685         l = SCARG(uap, flags);
  686         noctty = l & 0x8000;
  687         r =     (l & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800));
  688         r |=    ((l & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
  689         r |=    ((l & 0x0080) ? O_SHLOCK : 0);
  690         r |=    ((l & 0x0100) ? O_EXLOCK : 0);
  691         r |=    ((l & 0x2000) ? O_SYNC : 0);
  692 
  693         SCARG(uap, flags) = r;
  694         ret = sys_open(p, (struct sys_open_args *)uap, retval);
  695 
  696         if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
  697                 struct filedesc *fdp = p->p_fd;
  698                 struct file *fp;
  699 
  700                 if ((fp = fd_getfile(fdp, *retval)) == NULL)
  701                         return (EBADF);
  702                 FREF(fp);
  703                 /* ignore any error, just give it a try */
  704                 if (fp->f_type == DTYPE_VNODE)
  705                         (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t)0, p);
  706                 FRELE(fp);
  707         }
  708         return ret;
  709 }
  710 
  711 #if defined (NFSSERVER)
  712 int
  713 sunos_sys_nfssvc(p, v, retval)
  714         struct proc *p;
  715         void *v;
  716         register_t *retval;
  717 {
  718 #if 0
  719         struct sunos_sys_nfssvc_args *uap = v;
  720         struct emul *e = p->p_emul;
  721         struct sys_nfssvc_args outuap;
  722         struct sockaddr sa;
  723         int error;
  724 
  725         bzero(&outuap, sizeof outuap);
  726         SCARG(&outuap, fd) = SCARG(uap, fd);
  727         SCARG(&outuap, mskval) = STACKGAPBASE;
  728         SCARG(&outuap, msklen) = sizeof sa;
  729         SCARG(&outuap, mtchval) = SCARG(&outuap, mskval) + sizeof sa;
  730         SCARG(&outuap, mtchlen) = sizeof sa;
  731 
  732         bzero(&sa, sizeof sa);
  733         if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen)))
  734                 return (error);
  735         if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen)))
  736                 return (error);
  737 
  738         return nfssvc(p, &outuap, retval);
  739 #else
  740         return (ENOSYS);
  741 #endif
  742 }
  743 #endif /* NFSSERVER */
  744 
  745 int
  746 sunos_sys_ustat(p, v, retval)
  747         struct proc *p;
  748         void *v;
  749         register_t *retval;
  750 {
  751         struct sunos_sys_ustat_args *uap = v;
  752         struct sunos_ustat us;
  753         int error;
  754 
  755         bzero(&us, sizeof us);
  756 
  757         /*
  758          * XXX: should set f_tfree and f_tinode at least
  759          * How do we translate dev -> fstat? (and then to sunos_ustat)
  760          */
  761 
  762         if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0)
  763                 return (error);
  764         return 0;
  765 }
  766 
  767 int
  768 sunos_sys_quotactl(p, v, retval)
  769         struct proc *p;
  770         void *v;
  771         register_t *retval;
  772 {
  773 
  774         return EINVAL;
  775 }
  776 
  777 int
  778 sunos_sys_vhangup(p, v, retval)
  779         struct proc *p;
  780         void *v;
  781         register_t *retval;
  782 {
  783         struct session *sp = p->p_session;
  784 
  785         if (sp->s_ttyvp == 0)
  786                 return 0;
  787 
  788         if (sp->s_ttyp && sp->s_ttyp->t_session == sp && sp->s_ttyp->t_pgrp)
  789                 pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
  790 
  791         (void) ttywait(sp->s_ttyp);
  792         if (sp->s_ttyvp)
  793                 VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
  794         if (sp->s_ttyvp)
  795                 vrele(sp->s_ttyvp);
  796         sp->s_ttyvp = NULL;
  797 
  798         return 0;
  799 }
  800 
  801 static int
  802 sunstatfs(sp, buf)
  803         struct statfs *sp;
  804         caddr_t buf;
  805 {
  806         struct sunos_statfs ssfs;
  807 
  808         bzero(&ssfs, sizeof ssfs);
  809         ssfs.f_type = 0;
  810         ssfs.f_bsize = sp->f_bsize;
  811         ssfs.f_blocks = sp->f_blocks;
  812         ssfs.f_bfree = sp->f_bfree;
  813         ssfs.f_bavail = sp->f_bavail;
  814         ssfs.f_files = sp->f_files;
  815         ssfs.f_ffree = sp->f_ffree;
  816         ssfs.f_fsid = sp->f_fsid;
  817         return copyout((caddr_t)&ssfs, buf, sizeof ssfs);
  818 }       
  819 
  820 int
  821 sunos_sys_statfs(p, v, retval)
  822         struct proc *p;
  823         void *v;
  824         register_t *retval;
  825 {
  826         struct sunos_sys_statfs_args *uap = v;
  827         register struct mount *mp;
  828         register struct statfs *sp;
  829         int error;
  830         struct nameidata nd;
  831 
  832         caddr_t sg = stackgap_init(p->p_emul);
  833         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  834 
  835         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  836         if ((error = namei(&nd)) != 0)
  837                 return (error);
  838         mp = nd.ni_vp->v_mount;
  839         sp = &mp->mnt_stat;
  840         vrele(nd.ni_vp);
  841         if ((error = VFS_STATFS(mp, sp, p)) != 0)
  842                 return (error);
  843         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  844         return sunstatfs(sp, (caddr_t)SCARG(uap, buf));
  845 }
  846 
  847 int
  848 sunos_sys_fstatfs(p, v, retval)
  849         struct proc *p;
  850         void *v;
  851         register_t *retval;
  852 {
  853         struct sunos_sys_fstatfs_args *uap = v;
  854         struct file *fp;
  855         struct mount *mp;
  856         struct statfs *sp;
  857         int error;
  858 
  859         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
  860                 return (error);
  861         mp = ((struct vnode *)fp->f_data)->v_mount;
  862         sp = &mp->mnt_stat;
  863         error = VFS_STATFS(mp, sp, p);
  864         FRELE(fp);
  865         if (error)
  866                 return (error);
  867         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  868         return sunstatfs(sp, (caddr_t)SCARG(uap, buf));
  869 }
  870 
  871 int
  872 sunos_sys_exportfs(p, v, retval)
  873         struct proc *p;
  874         void *v;
  875         register_t *retval;
  876 {
  877         /*
  878          * XXX: should perhaps translate into a mount(2)
  879          * with MOUNT_EXPORT?
  880          */
  881         return 0;
  882 }
  883 
  884 int
  885 sunos_sys_mknod(p, v, retval)
  886         struct proc *p;
  887         void *v;
  888         register_t *retval;
  889 {
  890         struct sunos_sys_mknod_args *uap = v;
  891 
  892         caddr_t sg = stackgap_init(p->p_emul);
  893         SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  894 
  895         if (S_ISFIFO(SCARG(uap, mode)))
  896                 return sys_mkfifo(p, uap, retval);
  897 
  898         return sys_mknod(p, (struct sys_mknod_args *)uap, retval);
  899 }
  900 
  901 #define SUNOS_SC_ARG_MAX        1
  902 #define SUNOS_SC_CHILD_MAX      2
  903 #define SUNOS_SC_CLK_TCK        3
  904 #define SUNOS_SC_NGROUPS_MAX    4
  905 #define SUNOS_SC_OPEN_MAX       5
  906 #define SUNOS_SC_JOB_CONTROL    6
  907 #define SUNOS_SC_SAVED_IDS      7
  908 #define SUNOS_SC_VERSION        8
  909 
  910 int
  911 sunos_sys_sysconf(p, v, retval)
  912         struct proc *p;
  913         void *v;
  914         register_t *retval;
  915 {
  916         struct sunos_sys_sysconf_args *uap = v;
  917         extern int maxfiles;
  918 
  919         switch(SCARG(uap, name)) {
  920         case SUNOS_SC_ARG_MAX:
  921                 *retval = ARG_MAX;
  922                 break;
  923         case SUNOS_SC_CHILD_MAX:
  924                 *retval = maxproc;
  925                 break;
  926         case SUNOS_SC_CLK_TCK:
  927                 *retval = 60;           /* should this be `hz', ie. 100? */
  928                 break;
  929         case SUNOS_SC_NGROUPS_MAX:
  930                 *retval = NGROUPS_MAX;
  931                 break;
  932         case SUNOS_SC_OPEN_MAX:
  933                 *retval = maxfiles;
  934                 break;
  935         case SUNOS_SC_JOB_CONTROL:
  936                 *retval = 1;
  937                 break;
  938         case SUNOS_SC_SAVED_IDS:
  939 #ifdef _POSIX_SAVED_IDS
  940                 *retval = 1;
  941 #else
  942                 *retval = 0;
  943 #endif
  944                 break;
  945         case SUNOS_SC_VERSION:
  946                 *retval = 198808;
  947                 break;
  948         default:
  949                 return EINVAL;
  950         }
  951         return 0;
  952 }
  953 
  954 #define SUNOS_RLIMIT_NOFILE     6       /* Other RLIMIT_* are the same */
  955 #define SUNOS_RLIM_NLIMITS      7
  956 
  957 int
  958 sunos_sys_getrlimit(p, v, retval)
  959         struct proc *p;
  960         void *v;
  961         register_t *retval;
  962 {
  963         struct sunos_sys_getrlimit_args *uap = v;
  964 
  965         if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
  966                 return EINVAL;
  967 
  968         if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
  969                 SCARG(uap, which) = RLIMIT_NOFILE;
  970 
  971         return compat_43_sys_getrlimit(p, uap, retval);
  972 }
  973 
  974 int
  975 sunos_sys_setrlimit(p, v, retval)
  976         struct proc *p;
  977         void *v;
  978         register_t *retval;
  979 {
  980         struct sunos_sys_getrlimit_args *uap = v;
  981 
  982         if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
  983                 return EINVAL;
  984 
  985         if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
  986                 SCARG(uap, which) = RLIMIT_NOFILE;
  987 
  988         return compat_43_sys_setrlimit(p, uap, retval);
  989 }
  990 
  991 #ifdef PTRACE
  992 
  993 static int sreq2breq[] = {
  994         PT_TRACE_ME,    PT_READ_I,      PT_READ_D,      -1,
  995         PT_WRITE_I,     PT_WRITE_D,     -1,             PT_CONTINUE,
  996         PT_KILL,        -1,             PT_ATTACH,      PT_DETACH,
  997         PT_GETREGS,     PT_SETREGS,     PT_GETFPREGS,   PT_SETFPREGS
  998 };
  999 static int nreqs = sizeof(sreq2breq) / sizeof(sreq2breq[0]);
 1000 
 1001 int
 1002 sunos_sys_ptrace(p, v, retval)
 1003         struct proc *p;
 1004         void *v;
 1005         register_t *retval;
 1006 {
 1007         struct sunos_sys_ptrace_args *uap = v;
 1008         struct sys_ptrace_args pa;
 1009         int req;
 1010 
 1011         req = SCARG(uap, req);
 1012 
 1013         if (req < 0 || req >= nreqs)
 1014                 return (EINVAL);
 1015 
 1016         req = sreq2breq[req];
 1017         if (req == -1)
 1018                 return (EINVAL);
 1019 
 1020         SCARG(&pa, req) = req;
 1021         SCARG(&pa, pid) = (pid_t)SCARG(uap, pid);
 1022         SCARG(&pa, addr) = (caddr_t)SCARG(uap, addr);
 1023         SCARG(&pa, data) = SCARG(uap, data);
 1024 
 1025         return sys_ptrace(p, &pa, retval);
 1026 }
 1027 
 1028 #endif  /* PTRACE */
 1029 
 1030 /*
 1031  * SunOS reboot system call (for compatibility).
 1032  * Sun lets you pass in a boot string which the PROM
 1033  * saves and provides to the next boot program.
 1034  */
 1035 static struct sunos_howto_conv {
 1036         int sun_howto;
 1037         int bsd_howto;
 1038 } sunos_howto_conv[] = {
 1039         { 0x001,        RB_ASKNAME },
 1040         { 0x002,        RB_SINGLE },
 1041         { 0x004,        RB_NOSYNC },
 1042         { 0x008,        RB_HALT },
 1043         { 0x080,        RB_DUMP },
 1044         { 0x000,        0 },
 1045 };
 1046 #define SUNOS_RB_STRING 0x200
 1047 
 1048 int
 1049 sunos_sys_reboot(p, v, retval)
 1050         struct proc *p;
 1051         void *v;
 1052         register_t *retval;
 1053 {
 1054         struct sunos_sys_reboot_args *uap = v;
 1055         struct sunos_howto_conv *convp;
 1056         int error, bsd_howto, sun_howto;
 1057 
 1058         if ((error = suser(p, 0)) != 0)
 1059                 return (error);
 1060 
 1061         /*
 1062          * Convert howto bits to BSD format.
 1063          */
 1064         sun_howto = SCARG(uap, howto);
 1065         bsd_howto = 0;
 1066         convp = sunos_howto_conv;
 1067         while (convp->sun_howto) {
 1068                 if (sun_howto &  convp->sun_howto)
 1069                         bsd_howto |= convp->bsd_howto;
 1070                 convp++;
 1071         }
 1072 
 1073 #ifdef sun3
 1074         /*
 1075          * Sun RB_STRING (Get user supplied bootstring.)
 1076          * If the machine supports passing a string to the
 1077          * next booted kernel, add the machine name above
 1078          * and provide a reboot2() function (see sun3).
 1079          */
 1080         if (sun_howto & SUNOS_RB_STRING) {
 1081                 char bs[128];
 1082 
 1083                 error = copyinstr(SCARG(uap, bootstr), bs, sizeof(bs), 0);
 1084                 if (error)
 1085                         return error;
 1086 
 1087                 return (reboot2(bsd_howto, bs));
 1088         }
 1089 #endif  /* sun3 */
 1090 
 1091         boot(bsd_howto);
 1092         return 0;
 1093 }
 1094 
 1095 /*
 1096  * Generalized interface signal handler, 4.3-compatible.
 1097  */
 1098 /* ARGSUSED */
 1099 int
 1100 sunos_sys_sigvec(p, v, retval)
 1101         struct proc *p;
 1102         void *v;
 1103         register_t *retval;
 1104 {
 1105         register struct sunos_sys_sigvec_args /* {
 1106                 syscallarg(int) signum;
 1107                 syscallarg(struct sigvec *) nsv;
 1108                 syscallarg(struct sigvec *) osv;
 1109         } */ *uap = v;
 1110         struct sigvec vec;
 1111         register struct sigacts *ps = p->p_sigacts;
 1112         register struct sigvec *sv;
 1113         register int signum;
 1114         int bit, error;
 1115 
 1116         signum = SCARG(uap, signum);
 1117         if (signum <= 0 || signum >= NSIG ||
 1118             signum == SIGKILL || signum == SIGSTOP)
 1119                 return (EINVAL);
 1120         sv = &vec;
 1121         if (SCARG(uap, osv)) {
 1122                 *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
 1123                 sv->sv_mask = ps->ps_catchmask[signum];
 1124                 bit = sigmask(signum);
 1125                 sv->sv_flags = 0;
 1126                 if ((ps->ps_sigonstack & bit) != 0)
 1127                         sv->sv_flags |= SV_ONSTACK;
 1128                 if ((ps->ps_sigintr & bit) != 0)
 1129                         sv->sv_flags |= SV_INTERRUPT;
 1130                 if ((ps->ps_sigreset & bit) != 0)
 1131                         sv->sv_flags |= SA_RESETHAND;
 1132                 sv->sv_mask &= ~bit;
 1133                 error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
 1134                     sizeof (vec));
 1135                 if (error)
 1136                         return (error);
 1137         }
 1138         if (SCARG(uap, nsv)) {
 1139                 error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
 1140                     sizeof (vec));
 1141                 if (error)
 1142                         return (error);
 1143                 /*
 1144                  * SunOS uses the mask 0x0004 as SV_RESETHAND
 1145                  * meaning: `reset to SIG_DFL on delivery'.
 1146                  * We support only the bits in: 0xF
 1147                  * (those bits are the same as ours)
 1148                  */
 1149                 if (sv->sv_flags & ~0xF)
 1150                         return (EINVAL);
 1151                 /* SunOS binaries have a user-mode trampoline. */
 1152                 sv->sv_flags |= SA_USERTRAMP;
 1153                 /* Convert sigvec:SV_INTERRUPT to sigaction:SA_RESTART */
 1154                 sv->sv_flags ^= SA_RESTART;     /* same bit, inverted */
 1155                 setsigvec(p, signum, (struct sigaction *)sv);
 1156         }
 1157         return (0);
 1158 }
 1159 
 1160 int
 1161 sunos_sys_ostime(p, v, retval)
 1162         struct proc *p;
 1163         void *v;
 1164         register_t *retval;
 1165 {
 1166         struct sunos_sys_ostime_args /* {
 1167                 syscallarg(int) time;
 1168         } */ *uap = v;
 1169         struct timespec ts;
 1170         int error;
 1171 
 1172         if ((error = suser(p, 0)) != 0)
 1173                 return (error);
 1174 
 1175         ts.tv_sec = SCARG(uap, time);
 1176         ts.tv_nsec = 0;
 1177         error = settime(&ts);
 1178         return (error);
 1179 }
 1180 
 1181 /*
 1182  * This code is partly stolen from src/lib/libc/gen/times.c
 1183  * XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
 1184  */
 1185 
 1186 #define CLK_TCK 100
 1187 #define CONVTCK(r)      (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
 1188 
 1189 int
 1190 sunos_sys_otimes(p, v, retval)
 1191         struct proc *p;
 1192         void *v;
 1193         register_t *retval;
 1194 {
 1195         struct sunos_sys_otimes_args /* {
 1196                 syscallarg(struct tms *) tp;
 1197         } */ *uap = v;
 1198         struct tms tms;
 1199         struct rusage ru, *rup;
 1200 
 1201         /* RUSAGE_SELF */
 1202         calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
 1203         tms.tms_utime = CONVTCK(ru.ru_utime);
 1204         tms.tms_stime = CONVTCK(ru.ru_stime);
 1205 
 1206         /* RUSAGE_CHILDREN */
 1207         rup = &p->p_stats->p_cru;
 1208         tms.tms_cutime = CONVTCK(rup->ru_utime);
 1209         tms.tms_cstime = CONVTCK(rup->ru_stime);
 1210 
 1211         return copyout(&tms, SCARG(uap, tp), sizeof(*(SCARG(uap, tp))));
 1212 }

/* [<][>][^][v][top][bottom][index][help] */