root/compat/common/vfs_syscalls_43.c

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

DEFINITIONS

This source file includes following definitions.
  1. cvtstat
  2. compat_43_sys_stat
  3. compat_43_sys_lstat
  4. compat_43_sys_fstat
  5. compat_43_sys_ftruncate
  6. compat_43_sys_truncate
  7. compat_43_sys_lseek
  8. compat_43_sys_creat
  9. compat_43_sys_quota
  10. compat_43_sys_getdirentries

    1 /*      $OpenBSD: vfs_syscalls_43.c,v 1.27 2005/05/26 01:15:12 pedro Exp $      */
    2 /*      $NetBSD: vfs_syscalls_43.c,v 1.4 1996/03/14 19:31:52 christos Exp $     */
    3 
    4 /*
    5  * Copyright (c) 1989, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)vfs_syscalls.c      8.28 (Berkeley) 12/10/94
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/filedesc.h>
   43 #include <sys/kernel.h>
   44 #include <sys/proc.h>
   45 #include <sys/file.h>
   46 #include <sys/vnode.h>
   47 #include <sys/namei.h>
   48 #include <sys/dirent.h>
   49 #include <sys/socket.h>
   50 #include <sys/socketvar.h>
   51 #include <sys/stat.h>
   52 #include <sys/ioctl.h>
   53 #include <sys/fcntl.h>
   54 #include <sys/malloc.h>
   55 #include <sys/syslog.h>
   56 #include <sys/unistd.h>
   57 #include <sys/resourcevar.h>
   58 
   59 #include <sys/mount.h>
   60 #include <sys/syscallargs.h>
   61 
   62 #include <uvm/uvm_extern.h>
   63 
   64 #include <sys/pipe.h>
   65 
   66 static void cvtstat(struct stat *, struct stat43 *);
   67 
   68 /*
   69  * Convert from a new to an old stat structure.
   70  */
   71 static void
   72 cvtstat(st, ost)
   73         struct stat *st;
   74         struct stat43 *ost;
   75 {
   76 
   77         ost->st_dev = st->st_dev;
   78         ost->st_ino = st->st_ino;
   79         ost->st_mode = st->st_mode;
   80         ost->st_nlink = st->st_nlink;
   81         ost->st_uid = st->st_uid;
   82         ost->st_gid = st->st_gid;
   83         ost->st_rdev = st->st_rdev;
   84         if (st->st_size < (quad_t)1 << 32)
   85                 ost->st_size = st->st_size;
   86         else
   87                 ost->st_size = -2;
   88         ost->st_atime = st->st_atime;
   89         ost->st_mtime = st->st_mtime;
   90         ost->st_ctime = st->st_ctime;
   91         ost->st_blksize = st->st_blksize;
   92         ost->st_blocks = st->st_blocks;
   93         ost->st_flags = st->st_flags;
   94         ost->st_gen = st->st_gen;
   95 }
   96 
   97 /*
   98  * Get file status; this version follows links.
   99  */
  100 /* ARGSUSED */
  101 int
  102 compat_43_sys_stat(p, v, retval)
  103         struct proc *p;
  104         void *v;
  105         register_t *retval;
  106 {
  107         register struct compat_43_sys_stat_args /* {
  108                 syscallarg(char *) path;
  109                 syscallarg(struct stat43 *) ub;
  110         } */ *uap = v;
  111         struct stat sb;
  112         struct stat43 osb;
  113         int error;
  114         struct nameidata nd;
  115 
  116         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  117             SCARG(uap, path), p);
  118         if ((error = namei(&nd)) != 0)
  119                 return (error);
  120         error = vn_stat(nd.ni_vp, &sb, p);
  121         vput(nd.ni_vp);
  122         if (error)
  123                 return (error);
  124         /* Don't let non-root see generation numbers (for NFS security) */
  125         if (suser(p, 0))
  126                 sb.st_gen = 0;
  127         cvtstat(&sb, &osb);
  128         error = copyout(&osb, SCARG(uap, ub), sizeof(osb));
  129         return (error);
  130 }
  131 
  132 
  133 /*
  134  * Get file status; this version does not follow links.
  135  */
  136 /* ARGSUSED */
  137 int
  138 compat_43_sys_lstat(p, v, retval)
  139         struct proc *p;
  140         void *v;
  141         register_t *retval;
  142 {
  143         register struct compat_43_sys_lstat_args /* {
  144                 syscallarg(char *) path;
  145                 syscallarg(struct stat43 *) ub;
  146         } */ *uap = v;
  147         struct stat sb;
  148         struct stat43 osb;
  149         int error;
  150         struct nameidata nd;
  151 
  152         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
  153             SCARG(uap, path), p);
  154         if ((error = namei(&nd)) != 0)
  155                 return (error);
  156         error = vn_stat(nd.ni_vp, &sb, p);
  157         vput(nd.ni_vp);
  158         if (error)
  159                 return (error);
  160         /* Don't let non-root see generation numbers (for NFS security) */
  161         if (suser(p, 0))
  162                 sb.st_gen = 0;
  163         cvtstat(&sb, &osb);
  164         error = copyout(&osb, SCARG(uap, ub), sizeof(osb));
  165         return (error);
  166 }
  167 
  168 /*
  169  * Return status information about a file descriptor.
  170  */
  171 /* ARGSUSED */
  172 int
  173 compat_43_sys_fstat(p, v, retval)
  174         struct proc *p;
  175         void *v;
  176         register_t *retval;
  177 {
  178         struct compat_43_sys_fstat_args /* {
  179                 syscallarg(int) fd;
  180                 syscallarg(struct stat43 *) sb;
  181         } */ *uap = v;
  182         int fd = SCARG(uap, fd);
  183         struct filedesc *fdp = p->p_fd;
  184         struct file *fp;
  185         struct stat ub;
  186         struct stat43 oub;
  187         int error;
  188 
  189         if ((fp = fd_getfile(fdp, fd)) == NULL)
  190                 return (EBADF);
  191         FREF(fp);
  192         error = (*fp->f_ops->fo_stat)(fp, &ub, p);
  193         FRELE(fp);
  194         if (error == 0) {
  195                 /* Don't let non-root see generation numbers
  196                    (for NFS security) */
  197                 if (suser(p, 0))
  198                         ub.st_gen = 0;
  199                 cvtstat(&ub, &oub);
  200                 error = copyout(&oub, SCARG(uap, sb), sizeof(oub));
  201         }
  202         return (error);
  203 }
  204 
  205 /*
  206  * Truncate a file given a file descriptor.
  207  */
  208 /* ARGSUSED */
  209 int
  210 compat_43_sys_ftruncate(p, v, retval)
  211         struct proc *p;
  212         void *v;
  213         register_t *retval;
  214 {
  215         register struct compat_43_sys_ftruncate_args /* {
  216                 syscallarg(int) fd;
  217                 syscallarg(long) length;
  218         } */ *uap = v;
  219         struct sys_ftruncate_args /* {
  220                 syscallarg(int) fd;
  221                 syscallarg(int) pad;
  222                 syscallarg(off_t) length;
  223         } */ nuap;
  224 
  225         SCARG(&nuap, fd) = SCARG(uap, fd);
  226         SCARG(&nuap, length) = SCARG(uap, length);
  227         return (sys_ftruncate(p, &nuap, retval));
  228 }
  229 
  230 /*
  231  * Truncate a file given its path name.
  232  */
  233 /* ARGSUSED */
  234 int
  235 compat_43_sys_truncate(p, v, retval)
  236         struct proc *p;
  237         void *v;
  238         register_t *retval;
  239 {
  240         register struct compat_43_sys_truncate_args /* {
  241                 syscallarg(char *) path;
  242                 syscallarg(long) length;
  243         } */ *uap = v;
  244         struct sys_truncate_args /* {
  245                 syscallarg(char *) path;
  246                 syscallarg(int) pad;
  247                 syscallarg(off_t) length;
  248         } */ nuap;
  249 
  250         SCARG(&nuap, path) = SCARG(uap, path);
  251         SCARG(&nuap, length) = SCARG(uap, length);
  252         return (sys_truncate(p, &nuap, retval));
  253 }
  254 
  255 
  256 /*
  257  * Reposition read/write file offset.
  258  */
  259 int
  260 compat_43_sys_lseek(p, v, retval)
  261         struct proc *p;
  262         void *v;
  263         register_t *retval;
  264 {
  265         register struct compat_43_sys_lseek_args /* {
  266                 syscallarg(int) fd;
  267                 syscallarg(long) offset;
  268                 syscallarg(int) whence;
  269         } */ *uap = v;
  270         struct sys_lseek_args /* {
  271                 syscallarg(int) fd;
  272                 syscallarg(int) pad;
  273                 syscallarg(off_t) offset;
  274                 syscallarg(int) whence;
  275         } */ nuap;
  276         off_t qret;
  277         int error;
  278 
  279         SCARG(&nuap, fd) = SCARG(uap, fd);
  280         SCARG(&nuap, offset) = SCARG(uap, offset);
  281         SCARG(&nuap, whence) = SCARG(uap, whence);
  282         error = sys_lseek(p, &nuap, (register_t *)&qret);
  283         *(long *)retval = qret;
  284         return (error);
  285 }
  286 
  287 
  288 /*
  289  * Create a file.
  290  */
  291 int
  292 compat_43_sys_creat(p, v, retval)
  293         struct proc *p;
  294         void *v;
  295         register_t *retval;
  296 {
  297         register struct compat_43_sys_creat_args /* {
  298                 syscallarg(char *) path;
  299                 syscallarg(mode_t) mode;
  300         } */ *uap = v;
  301         struct sys_open_args /* {
  302                 syscallarg(char *) path;
  303                 syscallarg(int) flags;
  304                 syscallarg(mode_t) mode;
  305         } */ nuap;
  306 
  307         SCARG(&nuap, path) = SCARG(uap, path);
  308         SCARG(&nuap, mode) = SCARG(uap, mode);
  309         SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
  310         return (sys_open(p, &nuap, retval));
  311 }
  312 
  313 /*ARGSUSED*/
  314 int
  315 compat_43_sys_quota(p, v, retval)
  316         struct proc *p;
  317         void *v;
  318         register_t *retval;
  319 {
  320 
  321         return (ENOSYS);
  322 }
  323 
  324 
  325 /*
  326  * Read a block of directory entries in a file system independent format.
  327  */
  328 int
  329 compat_43_sys_getdirentries(p, v, retval)
  330         struct proc *p;
  331         void *v;
  332         register_t *retval;
  333 {
  334         register struct compat_43_sys_getdirentries_args /* {
  335                 syscallarg(int) fd;
  336                 syscallarg(char *) buf;
  337                 syscallarg(int) count;
  338                 syscallarg(long *) basep;
  339         } */ *uap = v;
  340         struct vnode *vp;
  341         struct file *fp;
  342         struct uio auio, kuio;
  343         struct iovec aiov, kiov;
  344         struct dirent *dp, *edp;
  345         caddr_t dirbuf;
  346         int error, eofflag, readcnt;
  347         long loff;
  348 
  349         if (SCARG(uap, count) < 0)
  350                 return EINVAL;
  351         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
  352                 return (error);
  353         if ((fp->f_flag & FREAD) == 0) {
  354                 error = EBADF;
  355                 goto bad;
  356         }
  357         vp = (struct vnode *)fp->f_data;
  358         if (vp->v_type != VDIR) {
  359                 error = EINVAL;
  360                 goto bad;
  361         }
  362         aiov.iov_base = SCARG(uap, buf);
  363         aiov.iov_len = SCARG(uap, count);
  364         auio.uio_iov = &aiov;
  365         auio.uio_iovcnt = 1;
  366         auio.uio_rw = UIO_READ;
  367         auio.uio_segflg = UIO_USERSPACE;
  368         auio.uio_procp = p;
  369         auio.uio_resid = SCARG(uap, count);
  370        
  371         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
  372         loff = auio.uio_offset = fp->f_offset;
  373 #       if (BYTE_ORDER != LITTLE_ENDIAN)
  374                 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
  375                         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
  376                             (int *)0, (u_long **)0);
  377                         fp->f_offset = auio.uio_offset;
  378                 } else
  379 #       endif
  380         {
  381                 u_int  nbytes = SCARG(uap, count);
  382 
  383                 nbytes = min(nbytes, MAXBSIZE);
  384 
  385                 kuio = auio;
  386                 kuio.uio_iov = &kiov;
  387                 kuio.uio_segflg = UIO_SYSSPACE;
  388                 kiov.iov_len = nbytes;
  389                 dirbuf = (caddr_t)malloc(nbytes, M_TEMP, M_WAITOK);
  390                 kiov.iov_base = dirbuf;
  391 
  392                 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
  393                                     0, 0);
  394                 fp->f_offset = kuio.uio_offset;
  395                 if (error == 0) {
  396                         readcnt = nbytes - kuio.uio_resid;
  397                         edp = (struct dirent *)&dirbuf[readcnt];
  398                         for (dp = (struct dirent *)dirbuf; dp < edp; ) {
  399 #                               if (BYTE_ORDER == LITTLE_ENDIAN)
  400                                         /*
  401                                          * The expected low byte of
  402                                          * dp->d_namlen is our dp->d_type.
  403                                          * The high MBZ byte of dp->d_namlen
  404                                          * is our dp->d_namlen.
  405                                          */
  406                                         dp->d_type = dp->d_namlen;
  407                                         dp->d_namlen = 0;
  408 #                               else
  409                                         /*
  410                                          * The dp->d_type is the high byte
  411                                          * of the expected dp->d_namlen,
  412                                          * so must be zero'ed.
  413                                          */
  414                                         dp->d_type = 0;
  415 #                               endif
  416                                 if (dp->d_reclen > 0) {
  417                                         dp = (struct dirent *)
  418                                             ((char *)dp + dp->d_reclen);
  419                                 } else {
  420                                         error = EIO;
  421                                         break;
  422                                 }
  423                         }
  424                         if (dp >= edp)
  425                                 error = uiomove(dirbuf, readcnt, &auio);
  426                 }
  427                 FREE(dirbuf, M_TEMP);
  428         }
  429         VOP_UNLOCK(vp, 0, p);
  430         if (error)
  431                 goto bad;
  432         error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
  433             sizeof(long));
  434         *retval = SCARG(uap, count) - auio.uio_resid;
  435 bad:
  436         FRELE(fp);
  437         return (error);
  438 }

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