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/ibcs2/ibcs2_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: ibcs2_misc.c,v 1.104.6.1 2010/03/17 02:59:51 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  * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
   41  *
   42  *      @(#)sun_misc.c  8.1 (Berkeley) 6/18/93
   43  */
   44 
   45 /*
   46  * Copyright (c) 1994, 1995, 1998 Scott Bartram
   47  *
   48  * This software was developed by the Computer Systems Engineering group
   49  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
   50  * contributed to Berkeley.
   51  *
   52  * All advertising materials mentioning features or use of this software
   53  * must display the following acknowledgement:
   54  *      This product includes software developed by the University of
   55  *      California, Lawrence Berkeley Laboratory.
   56  *
   57  * Redistribution and use in source and binary forms, with or without
   58  * modification, are permitted provided that the following conditions
   59  * are met:
   60  * 1. Redistributions of source code must retain the above copyright
   61  *    notice, this list of conditions and the following disclaimer.
   62  * 2. Redistributions in binary form must reproduce the above copyright
   63  *    notice, this list of conditions and the following disclaimer in the
   64  *    documentation and/or other materials provided with the distribution.
   65  * 3. All advertising materials mentioning features or use of this software
   66  *    must display the following acknowledgement:
   67  *      This product includes software developed by the University of
   68  *      California, Berkeley and its contributors.
   69  * 4. Neither the name of the University nor the names of its contributors
   70  *    may be used to endorse or promote products derived from this software
   71  *    without specific prior written permission.
   72  *
   73  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   74  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   75  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   76  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   77  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   78  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   79  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   80  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   81  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   82  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   83  * SUCH DAMAGE.
   84  *
   85  * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
   86  *
   87  *      @(#)sun_misc.c  8.1 (Berkeley) 6/18/93
   88  */
   89 
   90 /*
   91  * IBCS2 compatibility module.
   92  *
   93  * IBCS2 system calls that are implemented differently in BSD are
   94  * handled here.
   95  */
   96 
   97 #include <sys/cdefs.h>
   98 __KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.104.6.1 2010/03/17 02:59:51 snj Exp $");
   99 
  100 #include <sys/param.h>
  101 #include <sys/systm.h>
  102 #include <sys/namei.h>
  103 #include <sys/dirent.h>
  104 #include <sys/proc.h>
  105 #include <sys/file.h>
  106 #include <sys/filedesc.h>
  107 #include <sys/ioctl.h>
  108 #include <sys/kernel.h>
  109 #include <sys/malloc.h>
  110 #include <sys/mbuf.h>
  111 #include <sys/mman.h>
  112 #include <sys/mount.h>
  113 #include <sys/prot.h>
  114 #include <sys/reboot.h>
  115 #include <sys/resource.h>
  116 #include <sys/resourcevar.h>
  117 #include <sys/socket.h>
  118 #include <sys/stat.h>
  119 #include <sys/syslog.h>
  120 #include <sys/time.h>
  121 #include <sys/times.h>
  122 #include <sys/vnode.h>
  123 #include <sys/uio.h>
  124 #include <sys/wait.h>
  125 #include <sys/utsname.h>
  126 #include <sys/unistd.h>
  127 #include <sys/kauth.h>
  128 #include <sys/vfs_syscalls.h>
  129 
  130 #include <netinet/in.h>
  131 #include <sys/syscallargs.h>
  132 
  133 #include <miscfs/specfs/specdev.h>
  134 
  135 #include <uvm/uvm_extern.h>
  136 #include <sys/sysctl.h>
  137 
  138 #if defined(__i386__)
  139 #include <i386/include/reg.h>
  140 #endif
  141 
  142 #include <compat/ibcs2/ibcs2_types.h>
  143 #include <compat/ibcs2/ibcs2_dirent.h>
  144 #include <compat/ibcs2/ibcs2_fcntl.h>
  145 #include <compat/ibcs2/ibcs2_mman.h>
  146 #include <compat/ibcs2/ibcs2_time.h>
  147 #include <compat/ibcs2/ibcs2_signal.h>
  148 #include <compat/ibcs2/ibcs2_timeb.h>
  149 #include <compat/ibcs2/ibcs2_unistd.h>
  150 #include <compat/ibcs2/ibcs2_utsname.h>
  151 #include <compat/ibcs2/ibcs2_util.h>
  152 #include <compat/ibcs2/ibcs2_utime.h>
  153 #include <compat/ibcs2/ibcs2_syscallargs.h>
  154 #include <compat/ibcs2/ibcs2_sysi86.h>
  155 #include <compat/ibcs2/ibcs2_exec.h>
  156 
  157 #include <compat/sys/mount.h>
  158 
  159 int
  160 ibcs2_sys_ulimit(struct lwp *l, const struct ibcs2_sys_ulimit_args *uap, register_t *retval)
  161 {
  162         /* {
  163                 syscallarg(int) cmd;
  164                 syscallarg(int) newlimit;
  165         } */
  166         struct proc *p = l->l_proc;
  167         struct ibcs2_sys_sysconf_args sysconf_ua;
  168 #ifdef notyet
  169         int error;
  170         struct rlimit rl;
  171         struct sys_setrlimit_args sra;
  172 #endif
  173 #define IBCS2_GETFSIZE          1
  174 #define IBCS2_SETFSIZE          2
  175 #define IBCS2_GETPSIZE          3
  176 #define IBCS2_GETDTABLESIZE     4
  177 
  178         switch (SCARG(uap, cmd)) {
  179         case IBCS2_GETFSIZE:
  180                 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
  181                 return 0;
  182         case IBCS2_SETFSIZE:    /* XXX - fix this */
  183 #ifdef notyet
  184                 rl.rlim_cur = SCARG(uap, newlimit);
  185                 SCARG(&sra, which) = RLIMIT_FSIZE;
  186                 SCARG(&sra, rlp) = &rl;
  187                 error = setrlimit(p, &sra, retval);
  188                 if (!error)
  189                         *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
  190                 else
  191                         DPRINTF(("failed "));
  192                 return error;
  193 #else
  194                 *retval = SCARG(uap, newlimit);
  195                 return 0;
  196 #endif
  197         case IBCS2_GETPSIZE:
  198                 *retval = p->p_rlimit[RLIMIT_RSS].rlim_cur; /* XXX */
  199                 return 0;
  200         case IBCS2_GETDTABLESIZE:
  201                 SCARG(&sysconf_ua, name) = IBCS2_SC_OPEN_MAX;
  202                 return ibcs2_sys_sysconf(l, &sysconf_ua, retval);
  203         default:
  204                 return ENOSYS;
  205         }
  206 }
  207 
  208 int
  209 ibcs2_sys_waitsys(struct lwp *l, const struct ibcs2_sys_waitsys_args *uap, register_t *retval)
  210 {
  211 #if defined(__i386__)
  212         /* {
  213                 syscallarg(int) a1;
  214                 syscallarg(int) a2;
  215                 syscallarg(int) a3;
  216         } */
  217 #endif
  218         int error;
  219         int pid, options, status, was_zombie;
  220 
  221 #if defined(__i386__)
  222 #define WAITPID_EFLAGS  0x8c4   /* OF, SF, ZF, PF */
  223         if ((l->l_md.md_regs->tf_eflags & WAITPID_EFLAGS) == WAITPID_EFLAGS) {
  224                 /* waitpid */
  225                 pid = SCARG(uap, a1);
  226                 options = SCARG(uap, a3);
  227         } else {
  228 #endif
  229                 /* wait */
  230                 pid = WAIT_ANY;
  231                 options = 0;
  232 #if defined(__i386__)
  233         }
  234 #endif
  235 
  236         error = do_sys_wait(l, &pid, &status, options, NULL, &was_zombie);
  237         retval[0] = pid;
  238         retval[1] = status;
  239         return error;
  240 }
  241 
  242 int
  243 ibcs2_sys_execv(struct lwp *l, const struct ibcs2_sys_execv_args *uap, register_t *retval)
  244 {
  245         /* {
  246                 syscallarg(const char *) path;
  247                 syscallarg(char **) argp;
  248         } */
  249         struct sys_execve_args ap;
  250 
  251         SCARG(&ap, path) = SCARG(uap, path);
  252         SCARG(&ap, argp) = SCARG(uap, argp);
  253         SCARG(&ap, envp) = NULL;
  254 
  255         return sys_execve(l, &ap, retval);
  256 }
  257 
  258 int
  259 ibcs2_sys_execve(struct lwp *l, const struct ibcs2_sys_execve_args *uap, register_t *retval)
  260 {
  261         /* {
  262                 syscallarg(const char *) path;
  263                 syscallarg(char **) argp;
  264                 syscallarg(char **) envp;
  265         } */
  266         struct sys_execve_args ap;
  267 
  268         SCARG(&ap, path) = SCARG(uap, path);
  269         SCARG(&ap, argp) = SCARG(uap, argp);
  270         SCARG(&ap, envp) = SCARG(uap, envp);
  271 
  272         return sys_execve(l, &ap, retval);
  273 }
  274 
  275 int
  276 ibcs2_sys_umount(struct lwp *l, const struct ibcs2_sys_umount_args *uap, register_t *retval)
  277 {
  278         /* {
  279                 syscallarg(char *) name;
  280         } */
  281         struct sys_unmount_args um;
  282 
  283         SCARG(&um, path) = SCARG(uap, name);
  284         SCARG(&um, flags) = 0;
  285         return sys_unmount(l, &um, retval);
  286 }
  287 
  288 int
  289 ibcs2_sys_mount(struct lwp *l, const struct ibcs2_sys_mount_args *uap, register_t *retval)
  290 {
  291 #ifdef notyet
  292         /* {
  293                 syscallarg(char *) special;
  294                 syscallarg(char *) dir;
  295                 syscallarg(int) flags;
  296                 syscallarg(int) fstype;
  297                 syscallarg(char *) data;
  298                 syscallarg(int) len;
  299         } */
  300         int oflags = SCARG(uap, flags), nflags, error;
  301         char fsname[MFSNAMELEN];
  302 
  303         if (oflags & (IBCS2_MS_NOSUB | IBCS2_MS_SYS5))
  304                 return EINVAL;
  305         if ((oflags & IBCS2_MS_NEWTYPE) == 0)
  306                 return EINVAL;
  307         nflags = 0;
  308         if (oflags & IBCS2_MS_RDONLY)
  309                 nflags |= MNT_RDONLY;
  310         if (oflags & IBCS2_MS_NOSUID)
  311                 nflags |= MNT_NOSUID;
  312         if (oflags & IBCS2_MS_REMOUNT)
  313                 nflags |= MNT_UPDATE;
  314         SCARG(uap, flags) = nflags;
  315 
  316         if (error = copyinstr(SCARG(uap, type), fsname, sizeof fsname, NULL))
  317                 return error;
  318 
  319         if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
  320                 SCARG(uap, type) = (void *)STACK_ALLOC();
  321                 if (error = copyout("ffs", SCARG(uap, type), sizeof("ffs")))
  322                         return error;
  323         } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
  324                 struct ibcs2_nfs_args sna;
  325                 struct sockaddr_in sain;
  326                 struct nfs_args na;
  327                 struct sockaddr sa;
  328 
  329                 if (error = copyin(SCARG(uap, data), &sna, sizeof sna))
  330                         return error;
  331                 if (error = copyin(sna.addr, &sain, sizeof sain))
  332                         return error;
  333                 memcpy(&sa, &sain, sizeof sa);
  334                 sa.sa_len = sizeof(sain);
  335                 SCARG(uap, data) = STACK_ALLOC();
  336                 na.addr = (void *)((unsigned long)SCARG(uap, data) + sizeof na);
  337                 na.sotype = SOCK_DGRAM;
  338                 na.proto = IPPROTO_UDP;
  339                 na.fh = (nfsv2fh_t *)sna.fh;
  340                 na.flags = sna.flags;
  341                 na.wsize = sna.wsize;
  342                 na.rsize = sna.rsize;
  343                 na.timeo = sna.timeo;
  344                 na.retrans = sna.retrans;
  345                 na.hostname = sna.hostname;
  346 
  347                 if (error = copyout(&sa, na.addr, sizeof sa))
  348                         return error;
  349                 if (error = copyout(&na, SCARG(uap, data), sizeof na))
  350                         return error;
  351         }
  352         return sys_mount(p, uap, retval);
  353 #else
  354         return EINVAL;
  355 #endif
  356 }
  357 
  358 /*
  359  * Read iBCS2-style directory entries.  We suck them into kernel space so
  360  * that they can be massaged before being copied out to user code.  Like
  361  * SunOS, we squish out `empty' entries.
  362  *
  363  * This is quite ugly, but what do you expect from compatibility code?
  364  */
  365 
  366 int
  367 ibcs2_sys_getdents(struct lwp *l, const struct ibcs2_sys_getdents_args *uap, register_t *retval)
  368 {
  369         /* {
  370                 syscallarg(int) fd;
  371                 syscallarg(char *) buf;
  372                 syscallarg(int) nbytes;
  373         } */
  374         struct dirent *bdp;
  375         struct vnode *vp;
  376         char *inp, *tbuf;       /* BSD-format */
  377         int len, reclen;        /* BSD-format */
  378         char *outp;             /* iBCS2-format */
  379         int resid, ibcs2_reclen;/* iBCS2-format */
  380         file_t *fp;
  381         struct uio auio;
  382         struct iovec aiov;
  383         struct ibcs2_dirent idb;
  384         off_t off;                      /* true file offset */
  385         size_t buflen;
  386         int error, eofflag;
  387         off_t *cookiebuf = NULL, *cookie;
  388         int ncookies;
  389 
  390         /* fd_getvnode() will use the descriptor for us */
  391         if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
  392                 return (error);
  393         if ((fp->f_flag & FREAD) == 0) {
  394                 error = EBADF;
  395                 goto out1;
  396         }
  397         vp = fp->f_data;
  398         if (vp->v_type != VDIR) {
  399                 error = EINVAL;
  400                 goto out1;
  401         }
  402         buflen = min(MAXBSIZE, (size_t)SCARG(uap, nbytes));
  403         tbuf = malloc(buflen, M_TEMP, M_WAITOK);
  404         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  405         off = fp->f_offset;
  406 again:
  407         aiov.iov_base = tbuf;
  408         aiov.iov_len = buflen;
  409         auio.uio_iov = &aiov;
  410         auio.uio_iovcnt = 1;
  411         auio.uio_rw = UIO_READ;
  412         auio.uio_resid = buflen;
  413         auio.uio_offset = off;
  414         UIO_SETUP_SYSSPACE(&auio);
  415         /*
  416          * First we read into the malloc'ed buffer, then
  417          * we massage it into user space, one record at a time.
  418          */
  419         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
  420             &ncookies);
  421         if (error)
  422                 goto out;
  423         inp = tbuf;
  424         outp = SCARG(uap, buf);
  425         resid = SCARG(uap, nbytes);
  426         if ((len = buflen - auio.uio_resid) == 0)
  427                 goto eof;
  428         for (cookie = cookiebuf; len > 0; len -= reclen) {
  429                 bdp = (struct dirent *)inp;
  430                 reclen = bdp->d_reclen;
  431                 if (reclen & 3)
  432                         panic("ibcs2_getdents: bad reclen");
  433                 if (cookie && (*cookie >> 32) != 0) {
  434                         compat_offseterr(vp, "ibcs2_getdents");
  435                         error = EINVAL;
  436                         goto out;
  437                 }
  438                 if (bdp->d_fileno == 0) {
  439                         inp += reclen;  /* it is a hole; squish it out */
  440                         if (cookie)
  441                                 off = *cookie++;
  442                         else
  443                                 off += reclen;
  444                         continue;
  445                 }
  446                 ibcs2_reclen = IBCS2_RECLEN(&idb, bdp->d_namlen);
  447                 if (reclen > len || resid < ibcs2_reclen) {
  448                         /* entry too big for buffer, so just stop */
  449                         outp++;
  450                         break;
  451                 }
  452                 if (cookie)
  453                         off = *cookie++; /* each entry points to the next */
  454                 else
  455                         off += reclen;
  456                 /*
  457                  * Massage in place to make a iBCS2-shaped dirent (otherwise
  458                  * we have to worry about touching user memory outside of
  459                  * the copyout() call).
  460                  */
  461                 idb.d_ino = (ibcs2_ino_t)bdp->d_fileno;
  462                 idb.d_off = (ibcs2_off_t)off;
  463                 idb.d_reclen = (u_short)ibcs2_reclen;
  464                 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
  465                 error = copyout(&idb, outp, ibcs2_reclen);
  466                 if (error)
  467                         goto out;
  468                 /* advance past this real entry */
  469                 inp += reclen;
  470                 /* advance output past iBCS2-shaped entry */
  471                 outp += ibcs2_reclen;
  472                 resid -= ibcs2_reclen;
  473         }
  474 
  475         /* if we squished out the whole block, try again */
  476         if (outp == SCARG(uap, buf)) {
  477                 if (cookiebuf)
  478                         free(cookiebuf, M_TEMP);
  479                 cookiebuf = NULL;
  480                 goto again;
  481         }
  482         fp->f_offset = off;     /* update the vnode offset */
  483 
  484 eof:
  485         *retval = SCARG(uap, nbytes) - resid;
  486 out:
  487         VOP_UNLOCK(vp, 0);
  488         if (cookiebuf)
  489                 free(cookiebuf, M_TEMP);
  490         free(tbuf, M_TEMP);
  491 out1:
  492         fd_putfile(SCARG(uap, fd));
  493         return (error);
  494 }
  495 
  496 int
  497 ibcs2_sys_read(struct lwp *l, const struct ibcs2_sys_read_args *uap, register_t *retval)
  498 {
  499         /* {
  500                 syscallarg(int) fd;
  501                 syscallarg(char *) buf;
  502                 syscallarg(u_int) nbytes;
  503         } */
  504         struct dirent *bdp;
  505         struct vnode *vp;
  506         char *inp, *tbuf;       /* BSD-format */
  507         int len, reclen;        /* BSD-format */
  508         char *outp;             /* iBCS2-format */
  509         int resid, ibcs2_reclen;/* iBCS2-format */
  510         file_t *fp;
  511         struct uio auio;
  512         struct iovec aiov;
  513         struct ibcs2_direct {
  514                 ibcs2_ino_t ino;
  515                 char name[14];
  516         } idb;
  517         size_t buflen;
  518         int error, eofflag;
  519         size_t size;
  520         off_t *cookiebuf = NULL, *cookie;
  521         off_t off;                      /* true file offset */
  522         int ncookies;
  523 
  524         /* fd_getvnode() will use the descriptor for us */
  525         if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) {
  526                 if (error == EINVAL)
  527                         return sys_read(l, (const void *)uap, retval);
  528                 else
  529                         return error;
  530         }
  531         if ((fp->f_flag & FREAD) == 0) {
  532                 error = EBADF;
  533                 goto out1;
  534         }
  535         vp = fp->f_data;
  536         if (vp->v_type != VDIR) {
  537                 fd_putfile(SCARG(uap, fd));
  538                 return sys_read(l, (const void *)uap, retval);
  539         }
  540         buflen = min(MAXBSIZE, max(DEV_BSIZE, (size_t)SCARG(uap, nbytes)));
  541         tbuf = malloc(buflen, M_TEMP, M_WAITOK);
  542         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  543         off = fp->f_offset;
  544 again:
  545         aiov.iov_base = tbuf;
  546         aiov.iov_len = buflen;
  547         auio.uio_iov = &aiov;
  548         auio.uio_iovcnt = 1;
  549         auio.uio_rw = UIO_READ;
  550         auio.uio_resid = buflen;
  551         auio.uio_offset = off;
  552         UIO_SETUP_SYSSPACE(&auio);
  553         /*
  554          * First we read into the malloc'ed buffer, then
  555          * we massage it into user space, one record at a time.
  556          */
  557         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
  558             &ncookies);
  559         if (error)
  560                 goto out;
  561         inp = tbuf;
  562         outp = SCARG(uap, buf);
  563         resid = SCARG(uap, nbytes);
  564         if ((len = buflen - auio.uio_resid) == 0)
  565                 goto eof;
  566         for (cookie = cookiebuf; len > 0 && resid > 0; len -= reclen) {
  567                 bdp = (struct dirent *)inp;
  568                 reclen = bdp->d_reclen;
  569                 if (reclen & 3)
  570                         panic("ibcs2_sys_read");
  571                 if (cookie)
  572                         off = *cookie++; /* each entry points to the next */
  573                 else
  574                         off += reclen;
  575                 if ((off >> 32) != 0) {
  576                         error = EINVAL;
  577                         goto out;
  578                 }
  579                 if (bdp->d_fileno == 0) {
  580                         inp += reclen;  /* it is a hole; squish it out */
  581                         continue;
  582                 }
  583                 ibcs2_reclen = 16;
  584                 if (reclen > len || resid < ibcs2_reclen) {
  585                         /* entry too big for buffer, so just stop */
  586                         outp++;
  587                         break;
  588                 }
  589                 /*
  590                  * Massage in place to make a iBCS2-shaped dirent (otherwise
  591                  * we have to worry about touching user memory outside of
  592                  * the copyout() call).
  593                  *
  594                  * TODO: if length(filename) > 14, then break filename into
  595                  * multiple entries and set inode = 0xffff except last
  596                  */
  597                 idb.ino = (bdp->d_fileno > 0xfffe) ? 0xfffe : bdp->d_fileno;
  598                 (void)copystr(bdp->d_name, idb.name, 14, &size);
  599                 memset(idb.name + size, 0, 14 - size);
  600                 error = copyout(&idb, outp, ibcs2_reclen);
  601                 if (error)
  602                         goto out;
  603                 /* advance past this real entry */
  604                 inp += reclen;
  605                 /* advance output past iBCS2-shaped entry */
  606                 outp += ibcs2_reclen;
  607                 resid -= ibcs2_reclen;
  608         }
  609         /* if we squished out the whole block, try again */
  610         if (outp == SCARG(uap, buf)) {
  611                 if (cookiebuf)
  612                         free(cookiebuf, M_TEMP);
  613                 cookiebuf = NULL;
  614                 goto again;
  615         }
  616         fp->f_offset = off;             /* update the vnode offset */
  617 eof:
  618         *retval = SCARG(uap, nbytes) - resid;
  619 out:
  620         VOP_UNLOCK(vp, 0);
  621         if (cookiebuf)
  622                 free(cookiebuf, M_TEMP);
  623         free(tbuf, M_TEMP);
  624 out1:
  625         fd_putfile(SCARG(uap, fd));
  626         return (error);
  627 }
  628 
  629 int
  630 ibcs2_sys_mknod(struct lwp *l, const struct ibcs2_sys_mknod_args *uap, register_t *retval)
  631 {
  632         /* {
  633                 syscallarg(const char *) path;
  634                 syscallarg(int) mode;
  635                 syscallarg(int) dev;
  636         } */
  637 
  638         if (S_ISFIFO(SCARG(uap, mode))) {
  639                 struct sys_mkfifo_args ap;
  640                 SCARG(&ap, path) = SCARG(uap, path);
  641                 SCARG(&ap, mode) = SCARG(uap, mode);
  642                 return sys_mkfifo(l, &ap, retval);
  643         } else {
  644                 struct sys_mknod_args ap;
  645                 SCARG(&ap, path) = SCARG(uap, path);
  646                 SCARG(&ap, mode) = SCARG(uap, mode);
  647                 SCARG(&ap, dev) = SCARG(uap, dev);
  648                 return sys_mknod(l, &ap, retval);
  649         }
  650 }
  651 
  652 int
  653 ibcs2_sys_getgroups(struct lwp *l, const struct ibcs2_sys_getgroups_args *uap, register_t *retval)
  654 {
  655         /* {
  656                 syscallarg(int) gidsetsize;
  657                 syscallarg(ibcs2_gid_t *) gidset;
  658         } */
  659         ibcs2_gid_t iset[16];
  660         ibcs2_gid_t *gidset;
  661         unsigned int ngrps;
  662         int i, n, j;
  663         int error;
  664 
  665         ngrps = kauth_cred_ngroups(l->l_cred);
  666         *retval = ngrps;
  667         if (SCARG(uap, gidsetsize) == 0)
  668                 return 0;
  669         if (SCARG(uap, gidsetsize) < ngrps)
  670                 return EINVAL;
  671 
  672         gidset = SCARG(uap, gidset);
  673         for (i = 0; i < (n = ngrps); i += n, gidset += n) {
  674                 n -= i;
  675                 if (n > __arraycount(iset))
  676                         n = __arraycount(iset);
  677                 for (j = 0; j < n; j++)
  678                         iset[j] = kauth_cred_group(l->l_cred, i + j);
  679                 error = copyout(iset, gidset, n * sizeof(iset[0]));
  680                 if (error != 0)
  681                         return error;
  682         }
  683 
  684         return 0;
  685 }
  686 
  687 /*
  688  * It is very unlikly that any problem using 16bit groups is written
  689  * to allow for more than 16 of them, so don't bother trying to
  690  * support that.
  691  */
  692 #define COMPAT_NGROUPS16 16
  693 
  694 int
  695 ibcs2_sys_setgroups(struct lwp *l, const struct ibcs2_sys_setgroups_args *uap, register_t *retval)
  696 {
  697         /* {
  698                 syscallarg(int) gidsetsize;
  699                 syscallarg(ibcs2_gid_t *) gidset;
  700         } */
  701 
  702         ibcs2_gid_t iset[COMPAT_NGROUPS16];
  703         kauth_cred_t ncred;
  704         int error;
  705         gid_t grbuf[COMPAT_NGROUPS16];
  706         unsigned int i, ngroups = SCARG(uap, gidsetsize);
  707 
  708         if (ngroups > COMPAT_NGROUPS16)
  709                 return EINVAL;
  710         error = copyin(SCARG(uap, gidset), iset, ngroups);
  711         if (error != 0)
  712                 return error;
  713 
  714         for (i = 0; i < ngroups; i++)
  715                 grbuf[i] = iset[i];
  716 
  717         ncred = kauth_cred_alloc();
  718         error = kauth_cred_setgroups(ncred, grbuf, SCARG(uap, gidsetsize),
  719             -1, UIO_SYSSPACE);
  720         if (error != 0) {
  721                 kauth_cred_free(ncred);
  722                 return error;
  723         }
  724 
  725         return kauth_proc_setgroups(l, ncred);
  726 }
  727 
  728 int
  729 ibcs2_sys_setuid(struct lwp *l, const struct ibcs2_sys_setuid_args *uap, register_t *retval)
  730 {
  731         /* {
  732                 syscallarg(int) uid;
  733         } */
  734         struct sys_setuid_args sa;
  735 
  736         SCARG(&sa, uid) = (uid_t)SCARG(uap, uid);
  737         return sys_setuid(l, &sa, retval);
  738 }
  739 
  740 int
  741 ibcs2_sys_setgid(struct lwp *l, const struct ibcs2_sys_setgid_args *uap, register_t *retval)
  742 {
  743         /* {
  744                 syscallarg(int) gid;
  745         } */
  746         struct sys_setgid_args sa;
  747 
  748         SCARG(&sa, gid) = (gid_t)SCARG(uap, gid);
  749         return sys_setgid(l, &sa, retval);
  750 }
  751 
  752 int
  753 xenix_sys_ftime(struct lwp *l, const struct xenix_sys_ftime_args *uap, register_t *retval)
  754 {
  755         /* {
  756                 syscallarg(struct xenix_timeb *) tp;
  757         } */
  758         struct timeval tv;
  759         struct xenix_timeb itb;
  760 
  761         microtime(&tv);
  762         itb.time = tv.tv_sec;
  763         itb.millitm = (tv.tv_usec / 1000);
  764         /* NetBSD has no kernel notion of timezone -- fake it. */
  765         itb.timezone = 0;
  766         itb.dstflag = 0;
  767         return copyout(&itb, SCARG(uap, tp), xenix_timeb_len);
  768 }
  769 
  770 int
  771 ibcs2_sys_time(struct lwp *l, const struct ibcs2_sys_time_args *uap, register_t *retval)
  772 {
  773         /* {
  774                 syscallarg(ibcs2_time_t *) tp;
  775         } */
  776         struct proc *p = l->l_proc;
  777         struct timeval tv;
  778 
  779         microtime(&tv);
  780         *retval = tv.tv_sec;
  781         if (p->p_emuldata == IBCS2_EXEC_XENIX && SCARG(uap, tp))
  782                 return copyout(&tv.tv_sec, SCARG(uap, tp),
  783                     sizeof(ibcs2_time_t));
  784         else
  785                 return 0;
  786 }
  787 
  788 int
  789 ibcs2_sys_pathconf(struct lwp *l, const struct ibcs2_sys_pathconf_args *uap, register_t *retval)
  790 {
  791         /* {
  792                 syscallarg(char *) path;
  793                 syscallarg(int) name;
  794         } */
  795         struct sys_pathconf_args bsd_ua;
  796 
  797         SCARG(&bsd_ua, path) = SCARG(uap, path);
  798         /* iBCS2 _PC_* defines are offset by one */
  799         SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
  800         return sys_pathconf(l, &bsd_ua, retval);
  801 }
  802 
  803 int
  804 ibcs2_sys_fpathconf(struct lwp *l, const struct ibcs2_sys_fpathconf_args *uap, register_t *retval)
  805 {
  806         /* {
  807                 syscallarg(int) fd;
  808                 syscallarg(int) name;
  809         } */
  810         struct sys_fpathconf_args bsd_ua;
  811 
  812         SCARG(&bsd_ua, fd) = SCARG(uap, fd);
  813         /* iBCS2 _PC_* defines are offset by one */
  814         SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
  815         return sys_fpathconf(l, &bsd_ua, retval);
  816 }
  817 
  818 int
  819 ibcs2_sys_sysconf(struct lwp *l, const struct ibcs2_sys_sysconf_args *uap, register_t *retval)
  820 {
  821         /* {
  822                 syscallarg(int) name;
  823         } */
  824         struct proc *p = l->l_proc;
  825         int mib[2], value, error;
  826         size_t len;
  827 
  828         switch(SCARG(uap, name)) {
  829         case IBCS2_SC_ARG_MAX:
  830                 mib[1] = KERN_ARGMAX;
  831                 break;
  832 
  833         case IBCS2_SC_CHILD_MAX:
  834                 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
  835                 return 0;
  836 
  837         case IBCS2_SC_CLK_TCK:
  838                 *retval = hz;
  839                 return 0;
  840 
  841         case IBCS2_SC_NGROUPS_MAX:
  842                 mib[1] = KERN_NGROUPS;
  843                 break;
  844 
  845         case IBCS2_SC_OPEN_MAX:
  846                 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
  847                 return 0;
  848 
  849         case IBCS2_SC_JOB_CONTROL:
  850                 mib[1] = KERN_JOB_CONTROL;
  851                 break;
  852 
  853         case IBCS2_SC_SAVED_IDS:
  854                 mib[1] = KERN_SAVED_IDS;
  855                 break;
  856 
  857         case IBCS2_SC_VERSION:
  858                 mib[1] = KERN_POSIX1;
  859                 break;
  860 
  861         case IBCS2_SC_PASS_MAX:
  862                 *retval = 128;          /* XXX - should we create PASS_MAX ? */
  863                 return 0;
  864 
  865         case IBCS2_SC_XOPEN_VERSION:
  866                 *retval = 2;            /* XXX: What should that be? */
  867                 return 0;
  868 
  869         default:
  870                 return EINVAL;
  871         }
  872 
  873         mib[0] = CTL_KERN;
  874         len = sizeof(value);
  875         /*
  876          * calling into sysctl with superuser privs, but we don't mind,
  877          * 'cause we're only querying a value.
  878          */
  879         error = old_sysctl(&mib[0], 2, &value, &len, NULL, 0, NULL);
  880         if (error)
  881                 return (error);
  882         *retval = value;
  883         return 0;
  884 }
  885 
  886 int
  887 ibcs2_sys_alarm(struct lwp *l, const struct ibcs2_sys_alarm_args *uap, register_t *retval)
  888 {
  889         /* {
  890                 syscallarg(unsigned) sec;
  891         } */
  892         struct proc *p = l->l_proc;
  893         struct itimerval it, oit;
  894         int error;
  895 
  896         error = dogetitimer(p, ITIMER_REAL, &oit);
  897         if (error != 0)
  898                 return error;
  899 
  900         timerclear(&it.it_interval);
  901         it.it_value.tv_sec = SCARG(uap, sec);
  902         it.it_value.tv_usec = 0;
  903 
  904         error = dosetitimer(p, ITIMER_REAL, &it);
  905         if (error)
  906                 return error;
  907 
  908         if (oit.it_value.tv_usec)
  909                 oit.it_value.tv_sec++;
  910         *retval = oit.it_value.tv_sec;
  911         return 0;
  912 }
  913 
  914 int
  915 ibcs2_sys_getmsg(struct lwp *l, const struct ibcs2_sys_getmsg_args *uap, register_t *retval)
  916 {
  917 #ifdef notyet
  918         /* {
  919                 syscallarg(int) fd;
  920                 syscallarg(struct ibcs2_stropts *) ctl;
  921                 syscallarg(struct ibcs2_stropts *) dat;
  922                 syscallarg(int *) flags;
  923         } */
  924 #endif
  925 
  926         return 0;
  927 }
  928 
  929 int
  930 ibcs2_sys_putmsg(struct lwp *l, const struct ibcs2_sys_putmsg_args *uap, register_t *retval)
  931 {
  932 #ifdef notyet
  933         /* {
  934                 syscallarg(int) fd;
  935                 syscallarg(struct ibcs2_stropts *) ctl;
  936                 syscallarg(struct ibcs2_stropts *) dat;
  937                 syscallarg(int) flags;
  938         } */
  939 #endif
  940 
  941         return 0;
  942 }
  943 
  944 int
  945 ibcs2_sys_times(struct lwp *l, const struct ibcs2_sys_times_args *uap, register_t *retval)
  946 {
  947         /* {
  948                 syscallarg(struct tms *) tp;
  949         } */
  950         struct tms tms;
  951         struct timeval t;
  952         struct rusage ru, *rup;
  953 #define CONVTCK(r)      (r.tv_sec * hz + r.tv_usec / (1000000 / hz))
  954 
  955         ru = l->l_proc->p_stats->p_ru;
  956         mutex_enter(l->l_proc->p_lock);
  957         calcru(l->l_proc, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
  958         rulwps(l->l_proc, &ru);
  959         mutex_exit(l->l_proc->p_lock);
  960         tms.tms_utime = CONVTCK(ru.ru_utime);
  961         tms.tms_stime = CONVTCK(ru.ru_stime);
  962 
  963         rup = &l->l_proc->p_stats->p_cru;
  964         tms.tms_cutime = CONVTCK(rup->ru_utime);
  965         tms.tms_cstime = CONVTCK(rup->ru_stime);
  966 
  967         microtime(&t);
  968         *retval = CONVTCK(t);
  969 
  970         return copyout(&tms, SCARG(uap, tp), sizeof(tms));
  971 }
  972 
  973 int
  974 ibcs2_sys_stime(struct lwp *l, const struct ibcs2_sys_stime_args *uap, register_t *retval)
  975 {
  976         /* {
  977                 syscallarg(long *) timep;
  978         } */
  979         struct timeval tv;
  980         int error;
  981 
  982         error = copyin(SCARG(uap, timep), &tv.tv_sec, sizeof(long));
  983         if (error)
  984                 return error;
  985         tv.tv_usec = 0;
  986         return settimeofday1(&tv, false, NULL, l, true);
  987 }
  988 
  989 int
  990 ibcs2_sys_utime(struct lwp *l, const struct ibcs2_sys_utime_args *uap, register_t *retval)
  991 {
  992         /* {
  993                 syscallarg(const char *) path;
  994                 syscallarg(struct ibcs2_utimbuf *) buf;
  995         } */
  996         int error;
  997         struct timeval *tptr;
  998         struct timeval tp[2];
  999 
 1000         if (SCARG(uap, buf)) {
 1001                 struct ibcs2_utimbuf ubuf;
 1002 
 1003                 error = copyin(SCARG(uap, buf), &ubuf, sizeof(ubuf));
 1004                 if (error)
 1005                         return error;
 1006                 tp[0].tv_sec = ubuf.actime;
 1007                 tp[0].tv_usec = 0;
 1008                 tp[1].tv_sec = ubuf.modtime;
 1009                 tp[1].tv_usec = 0;
 1010                 tptr = tp;
 1011         } else
 1012                 tptr = NULL;
 1013 
 1014         return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
 1015                             tptr, UIO_SYSSPACE);
 1016 }
 1017 
 1018 int
 1019 ibcs2_sys_nice(struct lwp *l, const struct ibcs2_sys_nice_args *uap, register_t *retval)
 1020 {
 1021         /* {
 1022                 syscallarg(int) incr;
 1023         } */
 1024         struct proc *p = l->l_proc;
 1025         struct sys_setpriority_args sa;
 1026 
 1027         SCARG(&sa, which) = PRIO_PROCESS;
 1028         SCARG(&sa, who) = 0;
 1029         SCARG(&sa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
 1030         if (sys_setpriority(l, &sa, retval) != 0)
 1031                 return EPERM;
 1032         *retval = p->p_nice - NZERO;
 1033         return 0;
 1034 }
 1035 
 1036 /*
 1037  * iBCS2 getpgrp, setpgrp, setsid, and setpgid
 1038  */
 1039 
 1040 int
 1041 ibcs2_sys_pgrpsys(struct lwp *l, const struct ibcs2_sys_pgrpsys_args *uap, register_t *retval)
 1042 {
 1043         /* {
 1044                 syscallarg(int) type;
 1045                 syscallarg(void *) dummy;
 1046                 syscallarg(int) pid;
 1047                 syscallarg(int) pgid;
 1048         } */
 1049         struct proc *p = l->l_proc;
 1050 
 1051         switch (SCARG(uap, type)) {
 1052         case 0:                 /* getpgrp */
 1053                 mutex_enter(proc_lock);
 1054                 *retval = p->p_pgrp->pg_id;
 1055                 mutex_exit(proc_lock);
 1056                 return 0;
 1057 
 1058         case 1:                 /* setpgrp */
 1059             {
 1060                 struct sys_setpgid_args sa;
 1061 
 1062                 SCARG(&sa, pid) = 0;
 1063                 SCARG(&sa, pgid) = 0;
 1064                 sys_setpgid(l, &sa, retval);
 1065                 mutex_enter(proc_lock);
 1066                 *retval = p->p_pgrp->pg_id;
 1067                 mutex_exit(proc_lock);
 1068                 return 0;
 1069             }
 1070 
 1071         case 2:                 /* setpgid */
 1072             {
 1073                 struct sys_setpgid_args sa;
 1074 
 1075                 SCARG(&sa, pid) = SCARG(uap, pid);
 1076                 SCARG(&sa, pgid) = SCARG(uap, pgid);
 1077                 return sys_setpgid(l, &sa, retval);
 1078             }
 1079 
 1080         case 3:                 /* setsid */
 1081                 return sys_setsid(l, NULL, retval);
 1082 
 1083         default:
 1084                 return EINVAL;
 1085         }
 1086 }
 1087 
 1088 /*
 1089  * XXX - need to check for nested calls
 1090  */
 1091 
 1092 int
 1093 ibcs2_sys_plock(struct lwp *l, const struct ibcs2_sys_plock_args *uap, register_t *retval)
 1094 {
 1095         /* {
 1096                 syscallarg(int) cmd;
 1097         } */
 1098 #define IBCS2_UNLOCK    0
 1099 #define IBCS2_PROCLOCK  1
 1100 #define IBCS2_TEXTLOCK  2
 1101 #define IBCS2_DATALOCK  4
 1102 
 1103         if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
 1104             NULL) != 0)
 1105                 return EPERM;
 1106         switch(SCARG(uap, cmd)) {
 1107         case IBCS2_UNLOCK:
 1108         case IBCS2_PROCLOCK:
 1109         case IBCS2_TEXTLOCK:
 1110         case IBCS2_DATALOCK:
 1111                 return 0;       /* XXX - TODO */
 1112         }
 1113         return EINVAL;
 1114 }
 1115 
 1116 int
 1117 ibcs2_sys_uadmin(struct lwp *l, const struct ibcs2_sys_uadmin_args *uap, register_t *retval)
 1118 {
 1119         /* {
 1120                 syscallarg(int) cmd;
 1121                 syscallarg(int) func;
 1122                 syscallarg(void *) data;
 1123         } */
 1124         int error;
 1125 
 1126 #define SCO_A_REBOOT        1
 1127 #define SCO_A_SHUTDOWN      2
 1128 #define SCO_A_REMOUNT       4
 1129 #define SCO_A_CLOCK         8
 1130 #define SCO_A_SETCONFIG     128
 1131 #define SCO_A_GETDEV        130
 1132 
 1133 #define SCO_AD_HALT         0
 1134 #define SCO_AD_BOOT         1
 1135 #define SCO_AD_IBOOT        2
 1136 #define SCO_AD_PWRDOWN      3
 1137 #define SCO_AD_PWRNAP       4
 1138 
 1139 #define SCO_AD_PANICBOOT    1
 1140 
 1141 #define SCO_AD_GETBMAJ      0
 1142 #define SCO_AD_GETCMAJ      1
 1143 
 1144 
 1145         switch(SCARG(uap, cmd)) {
 1146         case SCO_A_REBOOT:
 1147         case SCO_A_SHUTDOWN:
 1148                 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_REBOOT,
 1149                     0, NULL, NULL, NULL);
 1150                 if (error)
 1151                         return (error);
 1152 
 1153                 switch(SCARG(uap, func)) {
 1154                 case SCO_AD_HALT:
 1155                 case SCO_AD_PWRDOWN:
 1156                 case SCO_AD_PWRNAP:
 1157                         cpu_reboot(RB_HALT, NULL);
 1158                 case SCO_AD_BOOT:
 1159                 case SCO_AD_IBOOT:
 1160                         cpu_reboot(RB_AUTOBOOT, NULL);
 1161                 }
 1162                 return EINVAL;
 1163         case SCO_A_REMOUNT:
 1164         case SCO_A_CLOCK:
 1165         case SCO_A_SETCONFIG:
 1166         case SCO_A_GETDEV:
 1167                 /* XXX Use proper kauth(9) requests when updating this. */
 1168                 error = kauth_authorize_generic(l->l_cred,
 1169                     KAUTH_GENERIC_ISSUSER, NULL);
 1170                 if (error)
 1171                         return (error);
 1172 
 1173                 if (SCARG(uap, cmd) != SCO_A_GETDEV)
 1174                         return 0;
 1175                 else
 1176                         return EINVAL;  /* XXX - TODO */
 1177         }
 1178         return EINVAL;
 1179 }
 1180 
 1181 int
 1182 ibcs2_sys_sysfs(struct lwp *l, const struct ibcs2_sys_sysfs_args *uap, register_t *retval)
 1183 {
 1184         /* {
 1185                 syscallarg(int) cmd;
 1186                 syscallarg(void *) d1;
 1187                 syscallarg(char *) buf;
 1188         } */
 1189 
 1190 #define IBCS2_GETFSIND        1
 1191 #define IBCS2_GETFSTYP        2
 1192 #define IBCS2_GETNFSTYP       3
 1193 
 1194         switch(SCARG(uap, cmd)) {
 1195         case IBCS2_GETFSIND:
 1196         case IBCS2_GETFSTYP:
 1197         case IBCS2_GETNFSTYP:
 1198                 break;
 1199         }
 1200         return EINVAL;          /* XXX - TODO */
 1201 }
 1202 
 1203 int
 1204 xenix_sys_rdchk(struct lwp *l, const struct xenix_sys_rdchk_args *uap, register_t *retval)
 1205 {
 1206         /* {
 1207                 syscallarg(int) fd;
 1208         } */
 1209         file_t *fp;
 1210         int nbytes;
 1211         int error;
 1212 
 1213         if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
 1214                 return (EBADF);
 1215         error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD, &nbytes);
 1216         fd_putfile(SCARG(uap, fd));
 1217 
 1218         if (error != 0)
 1219                 return error;
 1220 
 1221         *retval = nbytes ? 1 : 0;
 1222         return 0;
 1223 }
 1224 
 1225 int
 1226 xenix_sys_chsize(struct lwp *l, const struct xenix_sys_chsize_args *uap, register_t *retval)
 1227 {
 1228         /* {
 1229                 syscallarg(int) fd;
 1230                 syscallarg(long) size;
 1231         } */
 1232         struct sys_ftruncate_args sa;
 1233 
 1234         SCARG(&sa, fd) = SCARG(uap, fd);
 1235         SCARG(&sa, pad) = 0;
 1236         SCARG(&sa, length) = SCARG(uap, size);
 1237         return sys_ftruncate(l, &sa, retval);
 1238 }
 1239 
 1240 int
 1241 xenix_sys_nap(struct lwp *l, const struct xenix_sys_nap_args *uap, register_t *retval)
 1242 {
 1243         /* {
 1244                 syscallarg(long) millisec;
 1245         } */
 1246         int error;
 1247         struct timespec rqt;
 1248         struct timespec rmt;
 1249 
 1250         rqt.tv_sec = 0;
 1251         rqt.tv_nsec = SCARG(uap, millisec) * 1000;
 1252         error = nanosleep1(l, &rqt, &rmt);
 1253         /* If interrupted we can either report EINTR, or the time left */
 1254         if (error != 0 && error != EINTR)
 1255                 return error;
 1256         *retval = rmt.tv_nsec / 1000;
 1257         return 0;
 1258 }
 1259 
 1260 /*
 1261  * mmap compat code borrowed from svr4/svr4_misc.c
 1262  */
 1263 
 1264 int
 1265 ibcs2_sys_mmap(struct lwp *l, const struct ibcs2_sys_mmap_args *uap, register_t *retval)
 1266 {
 1267         /* {
 1268                 syscallarg(ibcs2_void *) addr;
 1269                 syscallarg(ibcs2_size_t) len;
 1270                 syscallarg(int) prot;
 1271                 syscallarg(int) flags;
 1272                 syscallarg(int) fd;
 1273                 syscallarg(ibcs2_off_t) off;
 1274         } */
 1275         struct sys_mmap_args mm;
 1276 
 1277 #define _MAP_NEW        0x80000000 /* XXX why? */
 1278 
 1279         if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
 1280                 return EINVAL;
 1281         if (SCARG(uap, len) == 0)
 1282                 return EINVAL;
 1283 
 1284         SCARG(&mm, prot) = SCARG(uap, prot);
 1285         SCARG(&mm, len) = SCARG(uap, len);
 1286         SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
 1287         SCARG(&mm, fd) = SCARG(uap, fd);
 1288         SCARG(&mm, addr) = SCARG(uap, addr);
 1289         SCARG(&mm, pos) = SCARG(uap, off);
 1290 
 1291         return sys_mmap(l, &mm, retval);
 1292 }
 1293 
 1294 int
 1295 ibcs2_sys_memcntl(struct lwp *l, const struct ibcs2_sys_memcntl_args *uap, register_t *retval)
 1296 {
 1297         /* {
 1298                 syscallarg(ibcs2_void *) addr;
 1299                 syscallarg(ibcs2_size_t) len;
 1300                 syscallarg(int) cmd;
 1301                 syscallarg(ibcs2_void *) arg;
 1302                 syscallarg(int) attr;
 1303                 syscallarg(int) mask;
 1304         } */
 1305 
 1306         switch (SCARG(uap, cmd)) {
 1307         case IBCS2_MC_SYNC:
 1308                 {
 1309                         struct sys___msync13_args msa;
 1310 
 1311                         SCARG(&msa, addr) = SCARG(uap, addr);
 1312                         SCARG(&msa, len) = SCARG(uap, len);
 1313                         SCARG(&msa, flags) = (int)SCARG(uap, arg);
 1314 
 1315                         return sys___msync13(l, &msa, retval);
 1316                 }
 1317 #ifdef IBCS2_MC_ADVISE          /* supported? */
 1318         case IBCS2_MC_ADVISE:
 1319                 {
 1320                         struct sys_madvise_args maa;
 1321 
 1322                         SCARG(&maa, addr) = SCARG(uap, addr);
 1323                         SCARG(&maa, len) = SCARG(uap, len);
 1324                         SCARG(&maa, behav) = (int)SCARG(uap, arg);
 1325 
 1326                         return sys_madvise(l, &maa, retval);
 1327                 }
 1328 #endif
 1329         case IBCS2_MC_LOCK:
 1330         case IBCS2_MC_UNLOCK:
 1331         case IBCS2_MC_LOCKAS:
 1332         case IBCS2_MC_UNLOCKAS:
 1333                 return EOPNOTSUPP;
 1334         default:
 1335                 return ENOSYS;
 1336         }
 1337 }
 1338 
 1339 int
 1340 ibcs2_sys_gettimeofday(struct lwp *l, const struct ibcs2_sys_gettimeofday_args *uap, register_t *retval)
 1341 {
 1342         /* {
 1343                 syscallarg(struct timeval *) tp;
 1344         } */
 1345 
 1346         if (SCARG(uap, tp)) {
 1347                 struct timeval atv;
 1348 
 1349                 microtime(&atv);
 1350                 return copyout(&atv, SCARG(uap, tp), sizeof (atv));
 1351         }
 1352 
 1353         return 0;
 1354 }
 1355 
 1356 int
 1357 ibcs2_sys_settimeofday(struct lwp *l, const struct ibcs2_sys_settimeofday_args *uap, register_t *retval)
 1358 {
 1359         /* {
 1360                 syscallarg(struct timeval *) tp;
 1361         } */
 1362         struct sys_settimeofday_args ap;
 1363 
 1364         SCARG(&ap, tv) = SCARG(uap, tp);
 1365         SCARG(&ap, tzp) = NULL;
 1366         return sys_settimeofday(l, &ap, retval);
 1367 }
 1368 
 1369 int
 1370 ibcs2_sys_scoinfo(struct lwp *l, const struct ibcs2_sys_scoinfo_args *uap, register_t *retval)
 1371 {
 1372         /* {
 1373                 syscallarg(struct scoutsname *) bp;
 1374                 syscallarg(int) len;
 1375         } */
 1376         struct scoutsname uts;
 1377 
 1378         (void)memset(&uts, 0, sizeof(uts));
 1379         (void)strncpy(uts.sysname, ostype, 8);
 1380         (void)strncpy(uts.nodename, hostname, 8);
 1381         (void)strncpy(uts.release, osrelease, 15);
 1382         (void)strncpy(uts.kid, "kernel id 1", 19);
 1383         (void)strncpy(uts.machine, machine, 8);
 1384         (void)strncpy(uts.bustype, "pci", 8);
 1385         (void)strncpy(uts.serial, "1234", 9);
 1386         uts.origin = 0;
 1387         uts.oem = 0;
 1388         (void)strncpy(uts.nusers, "unlim", 8);
 1389         uts.ncpu = 1;
 1390 
 1391         return copyout(&uts, SCARG(uap, bp), sizeof(uts));
 1392 }
 1393 
 1394 #define X_LK_UNLCK  0
 1395 #define X_LK_LOCK   1
 1396 #define X_LK_NBLCK 20
 1397 #define X_LK_RLCK   3
 1398 #define X_LK_NBRLCK 4
 1399 #define X_LK_GETLK  5
 1400 #define X_LK_SETLK  6
 1401 #define X_LK_SETLKW 7
 1402 #define X_LK_TESTLK 8
 1403 
 1404 int
 1405 xenix_sys_locking(struct lwp *l, const struct xenix_sys_locking_args *uap, register_t *retval)
 1406 {
 1407         /* {
 1408               syscallarg(int) fd;
 1409               syscallarg(int) blk;
 1410               syscallarg(int) size;
 1411         } */
 1412         struct flock fl;
 1413         int cmd;
 1414 
 1415         switch SCARG(uap, blk) {
 1416         case X_LK_GETLK:
 1417         case X_LK_SETLK:
 1418         case X_LK_SETLKW:
 1419                 return ibcs2_sys_fcntl(l, (const void *)uap, retval);
 1420         }
 1421 
 1422         switch SCARG(uap, blk) {
 1423         case X_LK_UNLCK:
 1424                 cmd = F_SETLK;
 1425                 fl.l_type = F_UNLCK;
 1426                 break;
 1427         case X_LK_LOCK:
 1428                 cmd = F_SETLKW;
 1429                 fl.l_type = F_WRLCK;
 1430                 break;
 1431         case X_LK_RLCK:
 1432                 cmd = F_SETLKW;
 1433                 fl.l_type = F_RDLCK;
 1434                 break;
 1435         case X_LK_NBRLCK:
 1436                 cmd = F_SETLK;
 1437                 fl.l_type = F_RDLCK;
 1438                 break;
 1439         case X_LK_NBLCK:
 1440                 cmd = F_SETLK;
 1441                 fl.l_type = F_WRLCK;
 1442                 break;
 1443         default:
 1444                 return EINVAL;
 1445         }
 1446         fl.l_len = SCARG(uap, size);
 1447         fl.l_start = 0;
 1448         fl.l_whence = SEEK_CUR;
 1449 
 1450         return do_fcntl_lock(SCARG(uap, fd), cmd, &fl);
 1451 }

Cache object: aa371be5fc169a3488461ec15a1b3ed2


[ 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.