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/i386/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 /*
    2  * Copyright (c) 1995 Steven Wallace
    3  * Copyright (c) 1994, 1995 Scott Bartram
    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. All advertising materials mentioning features or use of this software
   25  *    must display the following acknowledgement:
   26  *      This product includes software developed by the University of
   27  *      California, Berkeley and its contributors.
   28  * 4. Neither the name of the University nor the names of its contributors
   29  *    may be used to endorse or promote products derived from this software
   30  *    without specific prior written permission.
   31  *
   32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   42  * SUCH DAMAGE.
   43  *
   44  * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp 
   45  *
   46  *      @(#)sun_misc.c  8.1 (Berkeley) 6/18/93
   47  *
   48  * $FreeBSD: src/sys/i386/ibcs2/ibcs2_misc.c,v 1.10.2.4 1999/09/05 08:11:25 peter Exp $
   49  */
   50 
   51 /*
   52  * IBCS2 compatibility module.
   53  *
   54  * IBCS2 system calls that are implemented differently in BSD are
   55  * handled here.
   56  */
   57 #include <sys/param.h>
   58 #include <sys/systm.h>
   59 #include <sys/namei.h>
   60 #include <sys/proc.h>
   61 #include <sys/file.h>
   62 #include <sys/filedesc.h>
   63 #include <sys/ioctl.h>
   64 #include <sys/kernel.h>
   65 #include <sys/malloc.h>
   66 #include <sys/mbuf.h>
   67 #include <sys/mman.h>
   68 #include <sys/mount.h>
   69 #include <sys/reboot.h>
   70 #include <sys/resource.h>
   71 #include <sys/resourcevar.h>
   72 #include <sys/socket.h>
   73 #include <sys/stat.h>
   74 #include <sys/dirent.h>
   75 #include <sys/time.h>
   76 #include <sys/times.h>
   77 #include <sys/vnode.h>
   78 #include <sys/uio.h>
   79 #include <sys/wait.h>
   80 #include <sys/utsname.h>
   81 #include <sys/unistd.h>
   82 
   83 #include <netinet/in.h>
   84 #include <sys/sysproto.h>
   85 
   86 #include <miscfs/specfs/specdev.h>
   87 
   88 #include <vm/vm.h>
   89 #include <sys/sysctl.h>         /* must be included after vm.h */
   90 
   91 #include <machine/cpu.h>
   92 #include <machine/psl.h>
   93 #include <machine/reg.h>
   94 
   95 #include <i386/ibcs2/ibcs2_types.h>
   96 #include <i386/ibcs2/ibcs2_dirent.h>
   97 #include <i386/ibcs2/ibcs2_fcntl.h>
   98 #include <i386/ibcs2/ibcs2_time.h>
   99 #include <i386/ibcs2/ibcs2_signal.h>
  100 #include <i386/ibcs2/ibcs2_unistd.h>
  101 #include <i386/ibcs2/ibcs2_utsname.h>
  102 #include <i386/ibcs2/ibcs2_util.h>
  103 #include <i386/ibcs2/ibcs2_utime.h>
  104 #include <i386/ibcs2/ibcs2_proto.h>
  105 #include <i386/ibcs2/ibcs2_xenix.h>
  106 
  107 
  108 int
  109 ibcs2_ulimit(p, uap, retval)
  110         struct proc *p;
  111         struct ibcs2_ulimit_args *uap;
  112         int *retval;
  113 {
  114 #ifdef notyet
  115         int error;
  116         struct rlimit rl;
  117         struct setrlimit_args {
  118                 int resource;
  119                 struct rlimit *rlp;
  120         } sra;
  121 #endif
  122 #define IBCS2_GETFSIZE          1
  123 #define IBCS2_SETFSIZE          2
  124 #define IBCS2_GETPSIZE          3
  125 #define IBCS2_GETDTABLESIZE     4
  126         
  127         switch (SCARG(uap, cmd)) {
  128         case IBCS2_GETFSIZE:
  129                 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
  130                 if (*retval == -1) *retval = 0x7fffffff;
  131                 return 0;
  132         case IBCS2_SETFSIZE:    /* XXX - fix this */
  133 #ifdef notyet
  134                 rl.rlim_cur = SCARG(uap, newlimit);
  135                 sra.resource = RLIMIT_FSIZE;
  136                 sra.rlp = &rl;
  137                 error = setrlimit(p, &sra, retval);
  138                 if (!error)
  139                         *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
  140                 else
  141                         DPRINTF(("failed "));
  142                 return error;
  143 #else
  144                 *retval = SCARG(uap, newlimit);
  145                 return 0;
  146 #endif
  147         case IBCS2_GETPSIZE:
  148                 *retval = p->p_rlimit[RLIMIT_RSS].rlim_cur; /* XXX */
  149                 return 0;
  150         case IBCS2_GETDTABLESIZE:
  151                 uap->cmd = IBCS2_SC_OPEN_MAX;
  152                 return ibcs2_sysconf(p, (struct ibcs2_sysconf_args *)uap,
  153                                      retval);
  154         default:
  155                 return ENOSYS;
  156         }
  157 }
  158 
  159 #define IBCS2_WSTOPPED       0177
  160 #define IBCS2_STOPCODE(sig)  ((sig) << 8 | IBCS2_WSTOPPED)
  161 int
  162 ibcs2_wait(p, uap, retval)
  163         struct proc *p;
  164         struct ibcs2_wait_args *uap;
  165         int *retval;
  166 {
  167         int error, status;
  168         struct wait_args w4;
  169         struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
  170         
  171         SCARG(&w4, rusage) = NULL;
  172         if ((tf->tf_eflags & (PSL_Z|PSL_PF|PSL_N|PSL_V))
  173             == (PSL_Z|PSL_PF|PSL_N|PSL_V)) {
  174                 /* waitpid */
  175                 SCARG(&w4, pid) = SCARG(uap, a1);
  176                 SCARG(&w4, status) = (int *)SCARG(uap, a2);
  177                 SCARG(&w4, options) = SCARG(uap, a3);
  178         } else {
  179                 /* wait */
  180                 SCARG(&w4, pid) = WAIT_ANY;
  181                 SCARG(&w4, status) = (int *)SCARG(uap, a1);
  182                 SCARG(&w4, options) = 0;
  183         }
  184         if ((error = wait4(p, &w4, retval)) != 0)
  185                 return error;
  186         if (SCARG(&w4, status)) {       /* this is real iBCS brain-damage */
  187                 error = copyin((caddr_t)SCARG(&w4, status), (caddr_t)&status,
  188                                sizeof(SCARG(&w4, status)));
  189                 if(error)
  190                   return error;
  191 
  192                 /* convert status/signal result */
  193                 if(WIFSTOPPED(status))
  194                         status =
  195                           IBCS2_STOPCODE(bsd_to_ibcs2_sig[WSTOPSIG(status)]);
  196                 else if(WIFSIGNALED(status))
  197                         status = bsd_to_ibcs2_sig[WTERMSIG(status)];
  198                 /* else exit status -- identical */
  199 
  200                 /* record result/status */
  201                 retval[1] = status;
  202                 return copyout((caddr_t)&status, (caddr_t)SCARG(&w4, status),
  203                                sizeof(SCARG(&w4, status)));
  204         }
  205 
  206         return 0;
  207 }
  208 
  209 int
  210 ibcs2_execv(p, uap, retval)
  211         struct proc *p;
  212         struct ibcs2_execv_args *uap;
  213         int *retval;
  214 {
  215         struct execve_args ea;
  216         caddr_t sg = stackgap_init();
  217 
  218         CHECKALTEXIST(p, &sg, SCARG(uap, path));
  219         SCARG(&ea, fname) = SCARG(uap, path);
  220         SCARG(&ea, argv) = SCARG(uap, argp);
  221         SCARG(&ea, envv) = NULL;
  222         return execve(p, &ea, retval);
  223 }
  224 
  225 int
  226 ibcs2_execve(p, uap, retval) 
  227         struct proc *p;
  228         struct ibcs2_execve_args *uap;
  229         int *retval;
  230 {
  231         caddr_t sg = stackgap_init();
  232         CHECKALTEXIST(p, &sg, SCARG(uap, path));
  233         return execve(p, (struct execve_args *)uap, retval);
  234 }
  235 
  236 int
  237 ibcs2_umount(p, uap, retval)
  238         struct proc *p;
  239         struct ibcs2_umount_args *uap;
  240         int *retval;
  241 {
  242         struct unmount_args um;
  243 
  244         SCARG(&um, path) = SCARG(uap, name);
  245         SCARG(&um, flags) = 0;
  246         return unmount(p, &um, retval);
  247 }
  248 
  249 int
  250 ibcs2_mount(p, uap, retval)
  251         struct proc *p;
  252         struct ibcs2_mount_args *uap;
  253         int *retval;
  254 {
  255 #ifdef notyet
  256         int oflags = SCARG(uap, flags), nflags, error;
  257         char fsname[MFSNAMELEN];
  258 
  259         if (oflags & (IBCS2_MS_NOSUB | IBCS2_MS_SYS5))
  260                 return (EINVAL);
  261         if ((oflags & IBCS2_MS_NEWTYPE) == 0)
  262                 return (EINVAL);
  263         nflags = 0;
  264         if (oflags & IBCS2_MS_RDONLY)
  265                 nflags |= MNT_RDONLY;
  266         if (oflags & IBCS2_MS_NOSUID)
  267                 nflags |= MNT_NOSUID;
  268         if (oflags & IBCS2_MS_REMOUNT)
  269                 nflags |= MNT_UPDATE;
  270         SCARG(uap, flags) = nflags;
  271 
  272         if (error = copyinstr((caddr_t)SCARG(uap, type), fsname, sizeof fsname,
  273                               (u_int *)0))
  274                 return (error);
  275 
  276         if (strcmp(fsname, "4.2") == 0) {
  277                 SCARG(uap, type) = (caddr_t)STACK_ALLOC();
  278                 if (error = copyout("ufs", SCARG(uap, type), sizeof("ufs")))
  279                         return (error);
  280         } else if (strcmp(fsname, "nfs") == 0) {
  281                 struct ibcs2_nfs_args sna;
  282                 struct sockaddr_in sain;
  283                 struct nfs_args na;
  284                 struct sockaddr sa;
  285 
  286                 if (error = copyin(SCARG(uap, data), &sna, sizeof sna))
  287                         return (error);
  288                 if (error = copyin(sna.addr, &sain, sizeof sain))
  289                         return (error);
  290                 bcopy(&sain, &sa, sizeof sa);
  291                 sa.sa_len = sizeof(sain);
  292                 SCARG(uap, data) = (caddr_t)STACK_ALLOC();
  293                 na.addr = (struct sockaddr *)((int)SCARG(uap, data) + sizeof na);
  294                 na.sotype = SOCK_DGRAM;
  295                 na.proto = IPPROTO_UDP;
  296                 na.fh = (nfsv2fh_t *)sna.fh;
  297                 na.flags = sna.flags;
  298                 na.wsize = sna.wsize;
  299                 na.rsize = sna.rsize;
  300                 na.timeo = sna.timeo;
  301                 na.retrans = sna.retrans;
  302                 na.hostname = sna.hostname;
  303 
  304                 if (error = copyout(&sa, na.addr, sizeof sa))
  305                         return (error);
  306                 if (error = copyout(&na, SCARG(uap, data), sizeof na))
  307                         return (error);
  308         }
  309         return (mount(p, uap, retval));
  310 #else
  311         return EINVAL;
  312 #endif
  313 }
  314 
  315 /*
  316  * Read iBCS2-style directory entries.  We suck them into kernel space so
  317  * that they can be massaged before being copied out to user code.  Like
  318  * SunOS, we squish out `empty' entries.
  319  *
  320  * This is quite ugly, but what do you expect from compatibility code?
  321  */
  322 
  323 int
  324 ibcs2_getdents(p, uap, retval)
  325         struct proc *p;
  326         register struct ibcs2_getdents_args *uap;
  327         int *retval;
  328 {
  329         register struct vnode *vp;
  330         register caddr_t inp, buf;      /* BSD-format */
  331         register int len, reclen;       /* BSD-format */
  332         register caddr_t outp;          /* iBCS2-format */
  333         register int resid;             /* iBCS2-format */
  334         struct file *fp;
  335         struct uio auio;
  336         struct iovec aiov;
  337         struct ibcs2_dirent idb;
  338         off_t off;                      /* true file offset */
  339         int buflen, error, eofflag;
  340         u_int *cookies = NULL, *cookiep;
  341         int ncookies;
  342 #define BSD_DIRENT(cp)          ((struct dirent *)(cp))
  343 #define IBCS2_RECLEN(reclen)    (reclen + sizeof(u_short))
  344 
  345         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
  346                 return (error);
  347         if ((fp->f_flag & FREAD) == 0)
  348                 return (EBADF);
  349         vp = (struct vnode *)fp->f_data;
  350         if (vp->v_type != VDIR) /* XXX  vnode readdir op should do this */
  351                 return (EINVAL);
  352 
  353         off = fp->f_offset;
  354 #define DIRBLKSIZ       512             /* XXX we used to use ufs's DIRBLKSIZ */
  355         buflen = max(DIRBLKSIZ, SCARG(uap, nbytes));
  356         buflen = min(buflen, MAXBSIZE);
  357         buf = malloc(buflen, M_TEMP, M_WAITOK);
  358         VOP_LOCK(vp);
  359 again:
  360         aiov.iov_base = buf;
  361         aiov.iov_len = buflen;
  362         auio.uio_iov = &aiov;
  363         auio.uio_iovcnt = 1;
  364         auio.uio_rw = UIO_READ;
  365         auio.uio_segflg = UIO_SYSSPACE;
  366         auio.uio_procp = p;
  367         auio.uio_resid = buflen;
  368         auio.uio_offset = off;
  369 
  370         if (cookies) {
  371                 free(cookies, M_TEMP);
  372                 cookies = NULL;
  373         }
  374 
  375         /*
  376          * First we read into the malloc'ed buffer, then
  377          * we massage it into user space, one record at a time.
  378          */
  379         if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies))
  380                 goto out;
  381         inp = buf;
  382         outp = SCARG(uap, buf);
  383         resid = SCARG(uap, nbytes);
  384         if ((len = buflen - auio.uio_resid) <= 0)
  385                 goto eof;
  386 
  387         cookiep = cookies;
  388 
  389         if (cookies) {
  390                 /*
  391                  * When using cookies, the vfs has the option of reading from
  392                  * a different offset than that supplied (UFS truncates the
  393                  * offset to a block boundary to make sure that it never reads
  394                  * partway through a directory entry, even if the directory
  395                  * has been compacted).
  396                  */
  397                 while (len > 0 && ncookies > 0 && *cookiep <= off) {
  398                         len -= BSD_DIRENT(inp)->d_reclen;
  399                         inp += BSD_DIRENT(inp)->d_reclen;
  400                         cookiep++;
  401                         ncookies--;
  402                 }
  403         }
  404 
  405         for (; len > 0; len -= reclen) {
  406                 if (cookiep && ncookies == 0)
  407                         break;
  408                 reclen = BSD_DIRENT(inp)->d_reclen;
  409                 if (reclen & 3) {
  410                         printf("ibcs2_getdents: reclen=%d\n", reclen);
  411                         error = EFAULT;
  412                         goto out;
  413                 }
  414                 if (BSD_DIRENT(inp)->d_fileno == 0) {
  415                         inp += reclen;  /* it is a hole; squish it out */
  416                         if (cookiep) {
  417                                 off = *cookiep++;
  418                                 ncookies--;
  419                         } else
  420                                 off += reclen;
  421                         continue;
  422                 }
  423                 if (reclen > len || resid < IBCS2_RECLEN(reclen)) {
  424                         /* entry too big for buffer, so just stop */
  425                         outp++;
  426                         break;
  427                 }
  428                 /*
  429                  * Massage in place to make a iBCS2-shaped dirent (otherwise
  430                  * we have to worry about touching user memory outside of
  431                  * the copyout() call).
  432                  */
  433                 idb.d_ino = (ibcs2_ino_t)BSD_DIRENT(inp)->d_fileno;
  434                 idb.d_off = (ibcs2_off_t)off;
  435                 idb.d_reclen = (u_short)IBCS2_RECLEN(reclen);
  436                 if ((error = copyout((caddr_t)&idb, outp, 10)) != 0 ||
  437                     (error = copyout(BSD_DIRENT(inp)->d_name, outp + 10,
  438                                      BSD_DIRENT(inp)->d_namlen + 1)) != 0)
  439                         goto out;
  440                 /* advance past this real entry */
  441                 if (cookiep) {
  442                         off = *cookiep++;
  443                         ncookies--;
  444                 } else
  445                         off += reclen;
  446                 inp += reclen;
  447                 /* advance output past iBCS2-shaped entry */
  448                 outp += IBCS2_RECLEN(reclen);
  449                 resid -= IBCS2_RECLEN(reclen);
  450         }
  451         /* if we squished out the whole block, try again */
  452         if (outp == SCARG(uap, buf))
  453                 goto again;
  454         fp->f_offset = off;             /* update the vnode offset */
  455 eof:
  456         *retval = SCARG(uap, nbytes) - resid;
  457 out:
  458         if (cookies)
  459                 free(cookies, M_TEMP);
  460         VOP_UNLOCK(vp);
  461         free(buf, M_TEMP);
  462         return (error);
  463 }
  464 
  465 int
  466 ibcs2_read(p, uap, retval)
  467         struct proc *p;
  468         struct ibcs2_read_args *uap;
  469         int *retval;
  470 {
  471         register struct vnode *vp;
  472         register caddr_t inp, buf;      /* BSD-format */
  473         register int len, reclen;       /* BSD-format */
  474         register caddr_t outp;          /* iBCS2-format */
  475         register int resid;             /* iBCS2-format */
  476         struct file *fp;
  477         struct uio auio;
  478         struct iovec aiov;
  479         struct ibcs2_direct {
  480                 ibcs2_ino_t ino;
  481                 char name[14];
  482         } idb;
  483         off_t off;                      /* true file offset */
  484         int buflen, error, eofflag, size;
  485         u_int *cookies = NULL, *cookiep;
  486         int ncookies;
  487 
  488         if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) {
  489                 if (error == EINVAL)
  490                         return read(p, (struct read_args *)uap, retval);
  491                 else
  492                         return error;
  493         }
  494         if ((fp->f_flag & FREAD) == 0)
  495                 return (EBADF);
  496         vp = (struct vnode *)fp->f_data;
  497         if (vp->v_type != VDIR)
  498                 return read(p, (struct read_args *)uap, retval);
  499 
  500         DPRINTF(("ibcs2_read: read directory\n"));
  501 
  502         off = fp->f_offset;
  503         buflen = max(DIRBLKSIZ, SCARG(uap, nbytes));
  504         buflen = min(buflen, MAXBSIZE);
  505         buf = malloc(buflen, M_TEMP, M_WAITOK);
  506         VOP_LOCK(vp);
  507 again:
  508         aiov.iov_base = buf;
  509         aiov.iov_len = buflen;
  510         auio.uio_iov = &aiov;
  511         auio.uio_iovcnt = 1;
  512         auio.uio_rw = UIO_READ;
  513         auio.uio_segflg = UIO_SYSSPACE;
  514         auio.uio_procp = p;
  515         auio.uio_resid = buflen;
  516         auio.uio_offset = off;
  517 
  518         if (cookies) {
  519                 free(cookies, M_TEMP);
  520                 cookies = NULL;
  521         }
  522 
  523         /*
  524          * First we read into the malloc'ed buffer, then
  525          * we massage it into user space, one record at a time.
  526          */
  527         if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies)) {
  528                 DPRINTF(("VOP_READDIR failed: %d\n", error));
  529                 goto out;
  530         }
  531         inp = buf;
  532         outp = SCARG(uap, buf);
  533         resid = SCARG(uap, nbytes);
  534         if ((len = buflen - auio.uio_resid) <= 0)
  535                 goto eof;
  536 
  537         cookiep = cookies;
  538 
  539         if (cookies) {
  540                 /*
  541                  * When using cookies, the vfs has the option of reading from
  542                  * a different offset than that supplied (UFS truncates the
  543                  * offset to a block boundary to make sure that it never reads
  544                  * partway through a directory entry, even if the directory
  545                  * has been compacted).
  546                  */
  547                 while (len > 0 && ncookies > 0 && *cookiep <= off) {
  548                         len -= BSD_DIRENT(inp)->d_reclen;
  549                         inp += BSD_DIRENT(inp)->d_reclen;
  550                         cookiep++;
  551                         ncookies--;
  552                 }
  553         }
  554 
  555         for (; len > 0 && resid > 0; len -= reclen) {
  556                 if (cookiep && ncookies == 0)
  557                         break;
  558                 reclen = BSD_DIRENT(inp)->d_reclen;
  559                 if (reclen & 3) {
  560                         printf("ibcs2_read: reclen=%d\n", reclen);
  561                         error = EFAULT;
  562                         goto out;
  563                 }
  564                 if (BSD_DIRENT(inp)->d_fileno == 0) {
  565                         inp += reclen;  /* it is a hole; squish it out */
  566                         if (cookiep) {
  567                                 off = *cookiep++;
  568                                 ncookies--;
  569                         } else
  570                                 off += reclen;
  571                         continue;
  572                 }
  573                 if (reclen > len || resid < sizeof(struct ibcs2_direct)) {
  574                         /* entry too big for buffer, so just stop */
  575                         outp++;
  576                         break;
  577                 }
  578                 /*
  579                  * Massage in place to make a iBCS2-shaped dirent (otherwise
  580                  * we have to worry about touching user memory outside of
  581                  * the copyout() call).
  582                  *
  583                  * TODO: if length(filename) > 14, then break filename into
  584                  * multiple entries and set inode = 0xffff except last
  585                  */
  586                 idb.ino = (BSD_DIRENT(inp)->d_fileno > 0xfffe) ? 0xfffe :
  587                         BSD_DIRENT(inp)->d_fileno;
  588                 (void)copystr(BSD_DIRENT(inp)->d_name, idb.name, 14, &size);
  589                 bzero(idb.name + size, 14 - size);
  590                 if (error = copyout(&idb, outp, sizeof(struct ibcs2_direct)))
  591                         goto out;
  592                 /* advance past this real entry */
  593                 if (cookiep) {
  594                         off = *cookiep++;
  595                         ncookies--;
  596                 } else
  597                         off += reclen;
  598                 inp += reclen;
  599                 /* advance output past iBCS2-shaped entry */
  600                 outp += sizeof(struct ibcs2_direct);
  601                 resid -= sizeof(struct ibcs2_direct);
  602         }
  603         /* if we squished out the whole block, try again */
  604         if (outp == SCARG(uap, buf))
  605                 goto again;
  606         fp->f_offset = off;             /* update the vnode offset */
  607 eof:
  608         *retval = SCARG(uap, nbytes) - resid;
  609 out:
  610         if (cookies)
  611                 free(cookies, M_TEMP);
  612         VOP_UNLOCK(vp);
  613         free(buf, M_TEMP);
  614         return (error);
  615 }
  616 
  617 int
  618 ibcs2_mknod(p, uap, retval)
  619         struct proc *p;
  620         struct ibcs2_mknod_args *uap;
  621         int *retval;
  622 {
  623         caddr_t sg = stackgap_init();
  624 
  625         CHECKALTCREAT(p, &sg, SCARG(uap, path));
  626         if (S_ISFIFO(SCARG(uap, mode))) {
  627                 struct mkfifo_args ap;
  628                 SCARG(&ap, path) = SCARG(uap, path);
  629                 SCARG(&ap, mode) = SCARG(uap, mode);
  630                 return mkfifo(p, &ap, retval);
  631         } else {
  632                 struct mknod_args ap;
  633                 SCARG(&ap, path) = SCARG(uap, path);
  634                 SCARG(&ap, mode) = SCARG(uap, mode);
  635                 SCARG(&ap, dev) = SCARG(uap, dev);
  636                 return mknod(p, &ap, retval);
  637         }
  638 }
  639 
  640 int
  641 ibcs2_getgroups(p, uap, retval)
  642         struct proc *p;
  643         struct ibcs2_getgroups_args *uap;
  644         int *retval;
  645 {
  646         int error, i;
  647         ibcs2_gid_t *iset;
  648         struct getgroups_args sa;
  649         gid_t *gp;
  650         caddr_t sg = stackgap_init();
  651 
  652         SCARG(&sa, gidsetsize) = SCARG(uap, gidsetsize);
  653         if (SCARG(uap, gidsetsize)) {
  654                 SCARG(&sa, gidset) = stackgap_alloc(&sg, NGROUPS_MAX *
  655                                                     sizeof(gid_t *));
  656         }
  657         iset = stackgap_alloc(&sg, SCARG(uap, gidsetsize) *
  658                               sizeof(ibcs2_gid_t));
  659         if (error = getgroups(p, &sa, retval))
  660                 return error;
  661         if (SCARG(uap, gidsetsize) == 0)
  662                 return 0;
  663         for (i = 0, gp = SCARG(&sa, gidset); i < retval[0]; i++)
  664                 iset[i] = (ibcs2_gid_t)*gp++;
  665         if (retval[0] && (error = copyout((caddr_t)iset,
  666                                           (caddr_t)SCARG(uap, gidset),
  667                                           sizeof(ibcs2_gid_t) * retval[0])))
  668                 return error;
  669         return 0;
  670 }
  671 
  672 int
  673 ibcs2_setgroups(p, uap, retval)
  674         struct proc *p;
  675         struct ibcs2_setgroups_args *uap;
  676         int *retval;
  677 {
  678         int error, i;
  679         ibcs2_gid_t *iset;
  680         struct setgroups_args sa;
  681         gid_t *gp;
  682         caddr_t sg = stackgap_init();
  683 
  684         SCARG(&sa, gidsetsize) = SCARG(uap, gidsetsize);
  685         SCARG(&sa, gidset) = stackgap_alloc(&sg, SCARG(&sa, gidsetsize) *
  686                                             sizeof(gid_t *));
  687         iset = stackgap_alloc(&sg, SCARG(&sa, gidsetsize) *
  688                               sizeof(ibcs2_gid_t *));
  689         if (SCARG(&sa, gidsetsize)) {
  690                 if (error = copyin((caddr_t)SCARG(uap, gidset), (caddr_t)iset, 
  691                                    sizeof(ibcs2_gid_t *) *
  692                                    SCARG(uap, gidsetsize)))
  693                         return error;
  694         }
  695         for (i = 0, gp = SCARG(&sa, gidset); i < SCARG(&sa, gidsetsize); i++)
  696                 *gp++ = (gid_t)iset[i];
  697         return setgroups(p, &sa, retval);
  698 }
  699 
  700 int
  701 ibcs2_setuid(p, uap, retval)
  702         struct proc *p;
  703         struct ibcs2_setuid_args *uap;
  704         int *retval;
  705 {
  706         struct setuid_args sa;
  707 
  708         SCARG(&sa, uid) = (uid_t)SCARG(uap, uid);
  709         return setuid(p, &sa, retval);
  710 }
  711 
  712 int
  713 ibcs2_setgid(p, uap, retval)
  714         struct proc *p;
  715         struct ibcs2_setgid_args *uap;
  716         int *retval;
  717 {
  718         struct setgid_args sa;
  719 
  720         SCARG(&sa, gid) = (gid_t)SCARG(uap, gid);
  721         return setgid(p, &sa, retval);
  722 }
  723 
  724 int
  725 ibcs2_time(p, uap, retval)
  726         struct proc *p;
  727         struct ibcs2_time_args *uap;
  728         int *retval;
  729 {
  730         struct timeval tv;
  731 
  732         microtime(&tv);
  733         *retval = tv.tv_sec;
  734         if (SCARG(uap, tp))
  735                 return copyout((caddr_t)&tv.tv_sec, (caddr_t)SCARG(uap, tp),
  736                                sizeof(ibcs2_time_t));
  737         else
  738                 return 0;
  739 }
  740 
  741 int
  742 ibcs2_pathconf(p, uap, retval)
  743         struct proc *p;
  744         struct ibcs2_pathconf_args *uap;
  745         int *retval;
  746 {
  747         SCARG(uap, name)++;     /* iBCS2 _PC_* defines are offset by one */
  748         return pathconf(p, (struct pathconf_args *)uap, retval);
  749 }
  750 
  751 int
  752 ibcs2_fpathconf(p, uap, retval)
  753         struct proc *p;
  754         struct ibcs2_fpathconf_args *uap;
  755         int *retval;
  756 {
  757         SCARG(uap, name)++;     /* iBCS2 _PC_* defines are offset by one */
  758         return fpathconf(p, (struct fpathconf_args *)uap, retval);
  759 }
  760 
  761 int
  762 ibcs2_sysconf(p, uap, retval)
  763         struct proc *p;
  764         struct ibcs2_sysconf_args *uap;
  765         int *retval;
  766 {
  767         int mib[2], value, len, error;
  768         struct sysctl_args sa;
  769         struct __getrlimit_args ga;
  770 
  771         switch(SCARG(uap, name)) {
  772         case IBCS2_SC_ARG_MAX:
  773                 mib[1] = KERN_ARGMAX;
  774                 break;
  775 
  776         case IBCS2_SC_CHILD_MAX:
  777             {
  778                 caddr_t sg = stackgap_init();
  779 
  780                 SCARG(&ga, which) = RLIMIT_NPROC;
  781                 SCARG(&ga, rlp) = stackgap_alloc(&sg, sizeof(struct rlimit *));
  782                 if (error = getrlimit(p, &ga, retval))
  783                         return error;
  784                 *retval = SCARG(&ga, rlp)->rlim_cur;
  785                 return 0;
  786             }
  787 
  788         case IBCS2_SC_CLK_TCK:
  789                 *retval = hz;
  790                 return 0;
  791 
  792         case IBCS2_SC_NGROUPS_MAX:
  793                 mib[1] = KERN_NGROUPS;
  794                 break;
  795 
  796         case IBCS2_SC_OPEN_MAX:
  797             {
  798                 caddr_t sg = stackgap_init();
  799 
  800                 SCARG(&ga, which) = RLIMIT_NOFILE;
  801                 SCARG(&ga, rlp) = stackgap_alloc(&sg, sizeof(struct rlimit *));
  802                 if (error = getrlimit(p, &ga, retval))
  803                         return error;
  804                 *retval = SCARG(&ga, rlp)->rlim_cur;
  805                 return 0;
  806             }
  807                 
  808         case IBCS2_SC_JOB_CONTROL:
  809                 mib[1] = KERN_JOB_CONTROL;
  810                 break;
  811                 
  812         case IBCS2_SC_SAVED_IDS:
  813                 mib[1] = KERN_SAVED_IDS;
  814                 break;
  815                 
  816         case IBCS2_SC_VERSION:
  817                 mib[1] = KERN_POSIX1;
  818                 break;
  819                 
  820         case IBCS2_SC_PASS_MAX:
  821                 *retval = 128;          /* XXX - should we create PASS_MAX ? */
  822                 return 0;
  823 
  824         case IBCS2_SC_XOPEN_VERSION:
  825                 *retval = 2;            /* XXX: What should that be? */
  826                 return 0;
  827                 
  828         default:
  829                 return EINVAL;
  830         }
  831 
  832         mib[0] = CTL_KERN;
  833         len = sizeof(value);
  834         SCARG(&sa, name) = mib;
  835         SCARG(&sa, namelen) = 2;
  836         SCARG(&sa, old) = &value;
  837         SCARG(&sa, oldlenp) = &len;
  838         SCARG(&sa, new) = NULL;
  839         SCARG(&sa, newlen) = 0;
  840         if (error = __sysctl(p, &sa, retval))
  841                 return error;
  842         *retval = value;
  843         return 0;
  844 }
  845 
  846 int
  847 ibcs2_alarm(p, uap, retval)
  848         struct proc *p;
  849         struct ibcs2_alarm_args *uap;
  850         int *retval;
  851 {
  852         int error;
  853         struct itimerval *itp, *oitp;
  854         struct setitimer_args sa;
  855         caddr_t sg = stackgap_init();
  856 
  857         itp = stackgap_alloc(&sg, sizeof(*itp));
  858         oitp = stackgap_alloc(&sg, sizeof(*oitp));
  859         timerclear(&itp->it_interval);
  860         itp->it_value.tv_sec = SCARG(uap, sec);
  861         itp->it_value.tv_usec = 0;
  862 
  863         SCARG(&sa, which) = ITIMER_REAL;
  864         SCARG(&sa, itv) = itp;
  865         SCARG(&sa, oitv) = oitp;
  866         error = setitimer(p, &sa, retval);
  867         if (error)
  868                 return error;
  869         if (oitp->it_value.tv_usec)
  870                 oitp->it_value.tv_sec++;
  871         *retval = oitp->it_value.tv_sec;
  872         return 0;
  873 }
  874 
  875 int
  876 ibcs2_times(p, uap, retval)
  877         struct proc *p;
  878         struct ibcs2_times_args *uap;
  879         int *retval;
  880 {
  881         int error;
  882         struct getrusage_args ga;
  883         struct tms tms;
  884         struct timeval t;
  885         caddr_t sg = stackgap_init();
  886         struct rusage *ru = stackgap_alloc(&sg, sizeof(*ru));
  887 #define CONVTCK(r)      (r.tv_sec * hz + r.tv_usec / (1000000 / hz))
  888 
  889         SCARG(&ga, who) = RUSAGE_SELF;
  890         SCARG(&ga, rusage) = ru;
  891         error = getrusage(p, &ga, retval);
  892         if (error)
  893                 return error;
  894         tms.tms_utime = CONVTCK(ru->ru_utime);
  895         tms.tms_stime = CONVTCK(ru->ru_stime);
  896 
  897         SCARG(&ga, who) = RUSAGE_CHILDREN;
  898         error = getrusage(p, &ga, retval);
  899         if (error)
  900                 return error;
  901         tms.tms_cutime = CONVTCK(ru->ru_utime);
  902         tms.tms_cstime = CONVTCK(ru->ru_stime);
  903 
  904         microtime(&t);
  905         *retval = CONVTCK(t);
  906         
  907         return copyout((caddr_t)&tms, (caddr_t)SCARG(uap, tp),
  908                        sizeof(struct tms));
  909 }
  910 
  911 int
  912 ibcs2_stime(p, uap, retval)
  913         struct proc *p;
  914         struct ibcs2_stime_args *uap;
  915         int *retval;
  916 {
  917         int error;
  918         struct settimeofday_args sa;
  919         caddr_t sg = stackgap_init();
  920 
  921         SCARG(&sa, tv) = stackgap_alloc(&sg, sizeof(*SCARG(&sa, tv)));
  922         SCARG(&sa, tzp) = NULL;
  923         if (error = copyin((caddr_t)SCARG(uap, timep),
  924                            &(SCARG(&sa, tv)->tv_sec), sizeof(long)))
  925                 return error;
  926         SCARG(&sa, tv)->tv_usec = 0;
  927         if (error = settimeofday(p, &sa, retval))
  928                 return EPERM;
  929         return 0;
  930 }
  931 
  932 int
  933 ibcs2_utime(p, uap, retval)
  934         struct proc *p;
  935         struct ibcs2_utime_args *uap;
  936         int *retval;
  937 {
  938         int error;
  939         struct utimes_args sa;
  940         struct timeval *tp;
  941         caddr_t sg = stackgap_init();
  942 
  943         CHECKALTEXIST(p, &sg, SCARG(uap, path));
  944         SCARG(&sa, path) = SCARG(uap, path);
  945         if (SCARG(uap, buf)) {
  946                 struct ibcs2_utimbuf ubuf;
  947 
  948                 if (error = copyin((caddr_t)SCARG(uap, buf), (caddr_t)&ubuf,
  949                                    sizeof(ubuf)))
  950                         return error;
  951                 SCARG(&sa, tptr) = stackgap_alloc(&sg,
  952                                                   2 * sizeof(struct timeval *));
  953                 tp = (struct timeval *)SCARG(&sa, tptr);
  954                 tp->tv_sec = ubuf.actime;
  955                 tp->tv_usec = 0;
  956                 tp++;
  957                 tp->tv_sec = ubuf.modtime;
  958                 tp->tv_usec = 0;
  959         } else
  960                 SCARG(&sa, tptr) = NULL;
  961         return utimes(p, &sa, retval);
  962 }
  963 
  964 int
  965 ibcs2_nice(p, uap, retval)
  966         struct proc *p;
  967         struct ibcs2_nice_args *uap;
  968         int *retval;
  969 {
  970         int error;
  971         struct setpriority_args sa;
  972 
  973         SCARG(&sa, which) = PRIO_PROCESS;
  974         SCARG(&sa, who) = 0;
  975         SCARG(&sa, prio) = p->p_nice + SCARG(uap, incr);
  976         if (error = setpriority(p, &sa, retval))
  977                 return EPERM;
  978         *retval = p->p_nice;
  979         return 0;
  980 }
  981 
  982 /*
  983  * iBCS2 getpgrp, setpgrp, setsid, and setpgid
  984  */
  985 
  986 int
  987 ibcs2_pgrpsys(p, uap, retval)
  988         struct proc *p;
  989         struct ibcs2_pgrpsys_args *uap;
  990         int *retval;
  991 {
  992         switch (SCARG(uap, type)) {
  993         case 0:                 /* getpgrp */
  994                 *retval = p->p_pgrp->pg_id;
  995                 return 0;
  996 
  997         case 1:                 /* setpgrp */
  998             {
  999                 struct setpgid_args sa;
 1000 
 1001                 SCARG(&sa, pid) = 0;
 1002                 SCARG(&sa, pgid) = 0;
 1003                 setpgid(p, &sa, retval);
 1004                 *retval = p->p_pgrp->pg_id;
 1005                 return 0;
 1006             }
 1007 
 1008         case 2:                 /* setpgid */
 1009             {
 1010                 struct setpgid_args sa;
 1011 
 1012                 SCARG(&sa, pid) = SCARG(uap, pid);
 1013                 SCARG(&sa, pgid) = SCARG(uap, pgid);
 1014                 return setpgid(p, &sa, retval);
 1015             }
 1016 
 1017         case 3:                 /* setsid */
 1018                 return setsid(p, NULL, retval);
 1019 
 1020         default:
 1021                 return EINVAL;
 1022         }
 1023 }
 1024 
 1025 /*
 1026  * XXX - need to check for nested calls
 1027  */
 1028 
 1029 int
 1030 ibcs2_plock(p, uap, retval)
 1031         struct proc *p;
 1032         struct ibcs2_plock_args *uap;
 1033         int *retval;
 1034 {
 1035         int error;
 1036 #define IBCS2_UNLOCK    0
 1037 #define IBCS2_PROCLOCK  1
 1038 #define IBCS2_TEXTLOCK  2
 1039 #define IBCS2_DATALOCK  4
 1040 
 1041         
 1042         if (error = suser(p->p_ucred, &p->p_acflag))
 1043                 return EPERM;
 1044         switch(SCARG(uap, cmd)) {
 1045         case IBCS2_UNLOCK:
 1046         case IBCS2_PROCLOCK:
 1047         case IBCS2_TEXTLOCK:
 1048         case IBCS2_DATALOCK:
 1049                 return 0;       /* XXX - TODO */
 1050         }
 1051         return EINVAL;
 1052 }
 1053 
 1054 int
 1055 ibcs2_uadmin(p, uap, retval)
 1056         struct proc *p;
 1057         struct ibcs2_uadmin_args *uap;
 1058         int *retval;
 1059 {
 1060 #define SCO_A_REBOOT        1
 1061 #define SCO_A_SHUTDOWN      2
 1062 #define SCO_A_REMOUNT       4
 1063 #define SCO_A_CLOCK         8
 1064 #define SCO_A_SETCONFIG     128
 1065 #define SCO_A_GETDEV        130
 1066 
 1067 #define SCO_AD_HALT         0
 1068 #define SCO_AD_BOOT         1
 1069 #define SCO_AD_IBOOT        2
 1070 #define SCO_AD_PWRDOWN      3
 1071 #define SCO_AD_PWRNAP       4
 1072 
 1073 #define SCO_AD_PANICBOOT    1
 1074 
 1075 #define SCO_AD_GETBMAJ      0
 1076 #define SCO_AD_GETCMAJ      1
 1077 
 1078         if (suser(p->p_ucred, &p->p_acflag))
 1079                 return EPERM;
 1080 
 1081         switch(SCARG(uap, cmd)) {
 1082         case SCO_A_REBOOT:
 1083         case SCO_A_SHUTDOWN:
 1084                 switch(SCARG(uap, func)) {
 1085                         struct reboot_args r;
 1086                 case SCO_AD_HALT:
 1087                 case SCO_AD_PWRDOWN:
 1088                 case SCO_AD_PWRNAP:
 1089                         r.opt = RB_HALT;
 1090                         reboot(p, &r, retval);
 1091                 case SCO_AD_BOOT:
 1092                 case SCO_AD_IBOOT:
 1093                         r.opt = RB_AUTOBOOT;
 1094                         reboot(p, &r, retval);
 1095                 }
 1096                 return EINVAL;
 1097         case SCO_A_REMOUNT:
 1098         case SCO_A_CLOCK:
 1099         case SCO_A_SETCONFIG:
 1100                 return 0;
 1101         case SCO_A_GETDEV:
 1102                 return EINVAL;  /* XXX - TODO */
 1103         }
 1104         return EINVAL;
 1105 }
 1106 
 1107 int
 1108 ibcs2_sysfs(p, uap, retval)
 1109         struct proc *p;
 1110         struct ibcs2_sysfs_args *uap;
 1111         int *retval;
 1112 {
 1113 #define IBCS2_GETFSIND        1
 1114 #define IBCS2_GETFSTYP        2
 1115 #define IBCS2_GETNFSTYP       3
 1116 
 1117         switch(SCARG(uap, cmd)) {
 1118         case IBCS2_GETFSIND:
 1119         case IBCS2_GETFSTYP:
 1120         case IBCS2_GETNFSTYP:
 1121         }
 1122         return EINVAL;          /* XXX - TODO */
 1123 }
 1124 
 1125 int
 1126 ibcs2_unlink(p, uap, retval)
 1127         struct proc *p;
 1128         struct ibcs2_unlink_args *uap;
 1129         int *retval;
 1130 {
 1131         caddr_t sg = stackgap_init();
 1132 
 1133         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1134         return unlink(p, (struct unlink_args *)uap, retval);
 1135 }
 1136 
 1137 int
 1138 ibcs2_chdir(p, uap, retval)
 1139         struct proc *p;
 1140         struct ibcs2_chdir_args *uap;
 1141         int *retval;
 1142 {
 1143         caddr_t sg = stackgap_init();
 1144 
 1145         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1146         return chdir(p, (struct chdir_args *)uap, retval);
 1147 }
 1148 
 1149 int
 1150 ibcs2_chmod(p, uap, retval)
 1151         struct proc *p;
 1152         struct ibcs2_chmod_args *uap;
 1153         int *retval;
 1154 {
 1155         caddr_t sg = stackgap_init();
 1156 
 1157         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1158         return chmod(p, (struct chmod_args *)uap, retval);
 1159 }
 1160 
 1161 int
 1162 ibcs2_chown(p, uap, retval)
 1163         struct proc *p;
 1164         struct ibcs2_chown_args *uap;
 1165         int *retval;
 1166 {
 1167         caddr_t sg = stackgap_init();
 1168 
 1169         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1170         return chown(p, (struct chown_args *)uap, retval);
 1171 }
 1172 
 1173 int
 1174 ibcs2_rmdir(p, uap, retval)
 1175         struct proc *p;
 1176         struct ibcs2_rmdir_args *uap;
 1177         int *retval;
 1178 {
 1179         caddr_t sg = stackgap_init();
 1180 
 1181         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1182         return rmdir(p, (struct rmdir_args *)uap, retval);
 1183 }
 1184 
 1185 int
 1186 ibcs2_mkdir(p, uap, retval)
 1187         struct proc *p;
 1188         struct ibcs2_mkdir_args *uap;
 1189         int *retval;
 1190 {
 1191         caddr_t sg = stackgap_init();
 1192 
 1193         CHECKALTCREAT(p, &sg, SCARG(uap, path));
 1194         return mkdir(p, (struct mkdir_args *)uap, retval);
 1195 }
 1196 
 1197 int
 1198 ibcs2_symlink(p, uap, retval)
 1199         struct proc *p;
 1200         struct ibcs2_symlink_args *uap;
 1201         int *retval;
 1202 {
 1203         caddr_t sg = stackgap_init();
 1204 
 1205         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1206         CHECKALTCREAT(p, &sg, SCARG(uap, link));
 1207         return symlink(p, (struct symlink_args *)uap, retval);
 1208 }
 1209 
 1210 int
 1211 ibcs2_rename(p, uap, retval)
 1212         struct proc *p;
 1213         struct ibcs2_rename_args *uap;
 1214         int *retval;
 1215 {
 1216         caddr_t sg = stackgap_init();
 1217 
 1218         CHECKALTEXIST(p, &sg, SCARG(uap, from));
 1219         CHECKALTCREAT(p, &sg, SCARG(uap, to));
 1220         return rename(p, (struct rename_args *)uap, retval);
 1221 }
 1222 
 1223 int
 1224 ibcs2_readlink(p, uap, retval)
 1225         struct proc *p;
 1226         struct ibcs2_readlink_args *uap;
 1227         int *retval;
 1228 {
 1229         caddr_t sg = stackgap_init();
 1230 
 1231         CHECKALTEXIST(p, &sg, SCARG(uap, path));
 1232         return readlink(p, (struct readlink_args *) uap, retval);
 1233 }

Cache object: 3fa14910682f9b3d677f4a43082948f7


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