[BACK]Return to vfs_syscalls_43.c CVS log [TXT][DIR] Up to [local] / sys / compat / common

Annotation of sys/compat/common/vfs_syscalls_43.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb