[BACK]Return to netbsd32_fs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / netbsd32

Annotation of src/sys/compat/netbsd32/netbsd32_fs.c, Revision 1.51

1.51    ! ad          1: /*     $NetBSD: netbsd32_fs.c,v 1.50 2008/01/05 19:14:08 dsl Exp $     */
1.1       mrg         2:
                      3: /*
                      4:  * Copyright (c) 1998, 2001 Matthew R. Green
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
                     23:  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     24:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
                     25:  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     26:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     28:  * SUCH DAMAGE.
                     29:  */
1.7       lukem      30:
                     31: #include <sys/cdefs.h>
1.51    ! ad         32: __KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.50 2008/01/05 19:14:08 dsl Exp $");
1.1       mrg        33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/malloc.h>
                     37: #include <sys/mount.h>
                     38: #include <sys/socket.h>
                     39: #include <sys/socketvar.h>
                     40: #include <sys/stat.h>
                     41: #include <sys/time.h>
                     42: #include <sys/ktrace.h>
                     43: #include <sys/resourcevar.h>
                     44: #include <sys/vnode.h>
                     45: #include <sys/file.h>
                     46: #include <sys/filedesc.h>
                     47: #include <sys/namei.h>
1.18      cube       48: #include <sys/statvfs.h>
1.1       mrg        49: #include <sys/syscallargs.h>
                     50: #include <sys/proc.h>
1.22      christos   51: #include <sys/dirent.h>
1.27      elad       52: #include <sys/kauth.h>
1.37      dsl        53: #include <sys/vfs_syscalls.h>
1.1       mrg        54:
                     55: #include <compat/netbsd32/netbsd32.h>
                     56: #include <compat/netbsd32/netbsd32_syscallargs.h>
                     57: #include <compat/netbsd32/netbsd32_conv.h>
1.28      martin     58: #include <compat/sys/mount.h>
1.1       mrg        59:
                     60:
1.51    ! ad         61: static int dofilereadv32(int, struct file *, struct netbsd32_iovec *,
1.47      dsl        62:                              int, off_t *, int, register_t *);
1.51    ! ad         63: static int dofilewritev32(int, struct file *, struct netbsd32_iovec *,
1.47      dsl        64:                               int,  off_t *, int, register_t *);
1.1       mrg        65:
1.45      dsl        66: struct iovec *
                     67: netbsd32_get_iov(struct netbsd32_iovec *iov32, int iovlen, struct iovec *aiov,
                     68:     int aiov_len)
                     69: {
                     70: #define N_IOV32 8
                     71:        struct netbsd32_iovec aiov32[N_IOV32];
                     72:        struct iovec *iov = aiov;
                     73:        struct iovec *iovp;
                     74:        int i, n, j;
                     75:        int error;
                     76:
                     77:        if (iovlen < 0 || iovlen > IOV_MAX)
                     78:                return NULL;
                     79:
                     80:        if (iovlen > aiov_len)
                     81:                iov = malloc(iovlen * sizeof (*iov), M_TEMP, M_WAITOK);
                     82:
                     83:        iovp = iov;
                     84:        for (i = 0; i < iovlen; iov32 += N_IOV32, i += N_IOV32) {
                     85:                n = iovlen - i;
                     86:                if (n > N_IOV32)
                     87:                        n = N_IOV32;
                     88:                error = copyin(iov32, aiov32, n * sizeof (*iov32));
                     89:                if (error != 0) {
                     90:                        if (iov != aiov)
                     91:                                free(iov, M_TEMP);
                     92:                        return NULL;
                     93:                }
                     94:                for (j = 0; j < n; iovp++, j++) {
                     95:                        iovp->iov_base = NETBSD32PTR64(aiov32[j].iov_base);
                     96:                        iovp->iov_len = aiov32[j].iov_len;
                     97:                }
                     98:        }
                     99:        return iov;
                    100: #undef N_IOV32
                    101: }
                    102:
1.1       mrg       103: int
1.49      dsl       104: netbsd32_readv(struct lwp *l, const struct netbsd32_readv_args *uap, register_t *retval)
1.1       mrg       105: {
1.49      dsl       106:        /* {
1.1       mrg       107:                syscallarg(int) fd;
                    108:                syscallarg(const netbsd32_iovecp_t) iovp;
                    109:                syscallarg(int) iovcnt;
1.49      dsl       110:        } */
1.1       mrg       111:        int fd = SCARG(uap, fd);
1.51    ! ad        112:        file_t *fp;
1.1       mrg       113:
1.51    ! ad        114:        if ((fp = fd_getfile(fd)) == NULL)
1.6       thorpej   115:                return (EBADF);
                    116:
1.50      dsl       117:        if ((fp->f_flag & FREAD) == 0) {
1.51    ! ad        118:                fd_putfile(fd);
1.1       mrg       119:                return (EBADF);
1.50      dsl       120:        }
1.1       mrg       121:
1.51    ! ad        122:        return (dofilereadv32(fd, fp,
1.39      dsl       123:            (struct netbsd32_iovec *)SCARG_P32(uap, iovp),
1.10      scw       124:            SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
1.1       mrg       125: }
                    126:
                    127: /* Damn thing copies in the iovec! */
                    128: int
1.51    ! ad        129: dofilereadv32(int fd, struct file *fp, struct netbsd32_iovec *iovp, int iovcnt, off_t *offset, int flags, register_t *retval)
1.1       mrg       130: {
                    131:        struct uio auio;
                    132:        struct iovec *iov;
                    133:        struct iovec *needfree;
                    134:        struct iovec aiov[UIO_SMALLIOV];
                    135:        long i, cnt, error = 0;
                    136:        u_int iovlen;
                    137:        struct iovec *ktriov = NULL;
                    138:
                    139:        /* note: can't use iovlen until iovcnt is validated */
                    140:        iovlen = iovcnt * sizeof(struct iovec);
                    141:        if ((u_int)iovcnt > UIO_SMALLIOV) {
1.9       jdolecek  142:                if ((u_int)iovcnt > IOV_MAX) {
                    143:                        error = EINVAL;
                    144:                        goto out;
                    145:                }
                    146:                iov = malloc(iovlen, M_IOV, M_WAITOK);
1.1       mrg       147:                needfree = iov;
                    148:        } else if ((u_int)iovcnt > 0) {
                    149:                iov = aiov;
                    150:                needfree = NULL;
1.9       jdolecek  151:        } else {
                    152:                error = EINVAL;
                    153:                goto out;
                    154:        }
1.1       mrg       155:
                    156:        auio.uio_iov = iov;
                    157:        auio.uio_iovcnt = iovcnt;
                    158:        auio.uio_rw = UIO_READ;
1.51    ! ad        159:        auio.uio_vmspace = curproc->p_vmspace;
1.1       mrg       160:        error = netbsd32_to_iovecin(iovp, iov, iovcnt);
                    161:        if (error)
                    162:                goto done;
                    163:        auio.uio_resid = 0;
                    164:        for (i = 0; i < iovcnt; i++) {
                    165:                auio.uio_resid += iov->iov_len;
                    166:                /*
                    167:                 * Reads return ssize_t because -1 is returned on error.
                    168:                 * Therefore we must restrict the length to SSIZE_MAX to
                    169:                 * avoid garbage return values.
                    170:                 */
                    171:                if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
                    172:                        error = EINVAL;
                    173:                        goto done;
                    174:                }
                    175:                iov++;
                    176:        }
1.46      ad        177:
1.1       mrg       178:        /*
                    179:         * if tracing, save a copy of iovec
                    180:         */
1.46      ad        181:        if (ktrpoint(KTR_GENIO)) {
1.9       jdolecek  182:                ktriov = malloc(iovlen, M_TEMP, M_WAITOK);
1.36      christos  183:                memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen);
1.1       mrg       184:        }
1.46      ad        185:
1.1       mrg       186:        cnt = auio.uio_resid;
                    187:        error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
                    188:        if (error)
                    189:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    190:                    error == EINTR || error == EWOULDBLOCK))
                    191:                        error = 0;
                    192:        cnt -= auio.uio_resid;
1.46      ad        193:
                    194:        if (ktriov != NULL) {
                    195:                ktrgeniov(fd, UIO_READ, ktriov, cnt, error);
1.9       jdolecek  196:                free(ktriov, M_TEMP);
1.1       mrg       197:        }
1.46      ad        198:
1.1       mrg       199:        *retval = cnt;
                    200: done:
                    201:        if (needfree)
1.9       jdolecek  202:                free(needfree, M_IOV);
                    203: out:
1.51    ! ad        204:        fd_putfile(fd);
1.1       mrg       205:        return (error);
                    206: }
                    207:
                    208: int
1.49      dsl       209: netbsd32_writev(struct lwp *l, const struct netbsd32_writev_args *uap, register_t *retval)
1.1       mrg       210: {
1.49      dsl       211:        /* {
1.1       mrg       212:                syscallarg(int) fd;
                    213:                syscallarg(const netbsd32_iovecp_t) iovp;
                    214:                syscallarg(int) iovcnt;
1.49      dsl       215:        } */
1.1       mrg       216:        int fd = SCARG(uap, fd);
1.51    ! ad        217:        file_t *fp;
1.1       mrg       218:
1.51    ! ad        219:        if ((fp = fd_getfile(fd)) == NULL)
1.6       thorpej   220:                return (EBADF);
                    221:
1.50      dsl       222:        if ((fp->f_flag & FWRITE) == 0) {
1.51    ! ad        223:                fd_putfile(fd);
1.1       mrg       224:                return (EBADF);
1.50      dsl       225:        }
1.1       mrg       226:
1.51    ! ad        227:        return (dofilewritev32(fd, fp,
1.39      dsl       228:            (struct netbsd32_iovec *)SCARG_P32(uap, iovp),
1.10      scw       229:            SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
1.1       mrg       230: }
                    231:
                    232: int
1.51    ! ad        233: dofilewritev32(int fd, struct file *fp, struct netbsd32_iovec *iovp, int iovcnt, off_t *offset, int flags, register_t *retval)
1.1       mrg       234: {
                    235:        struct uio auio;
                    236:        struct iovec *iov;
                    237:        struct iovec *needfree;
                    238:        struct iovec aiov[UIO_SMALLIOV];
                    239:        long i, cnt, error = 0;
                    240:        u_int iovlen;
                    241:        struct iovec *ktriov = NULL;
                    242:
                    243:        /* note: can't use iovlen until iovcnt is validated */
                    244:        iovlen = iovcnt * sizeof(struct iovec);
                    245:        if ((u_int)iovcnt > UIO_SMALLIOV) {
1.9       jdolecek  246:                if ((u_int)iovcnt > IOV_MAX) {
                    247:                        error = EINVAL;
                    248:                        goto out;
                    249:                }
                    250:                iov = malloc(iovlen, M_IOV, M_WAITOK);
1.1       mrg       251:                needfree = iov;
                    252:        } else if ((u_int)iovcnt > 0) {
                    253:                iov = aiov;
                    254:                needfree = NULL;
1.9       jdolecek  255:        } else {
                    256:                error = EINVAL;
                    257:                goto out;
                    258:        }
1.1       mrg       259:
                    260:        auio.uio_iov = iov;
                    261:        auio.uio_iovcnt = iovcnt;
                    262:        auio.uio_rw = UIO_WRITE;
1.51    ! ad        263:        auio.uio_vmspace = curproc->p_vmspace;
1.1       mrg       264:        error = netbsd32_to_iovecin(iovp, iov, iovcnt);
                    265:        if (error)
                    266:                goto done;
                    267:        auio.uio_resid = 0;
                    268:        for (i = 0; i < iovcnt; i++) {
                    269:                auio.uio_resid += iov->iov_len;
                    270:                /*
                    271:                 * Writes return ssize_t because -1 is returned on error.
                    272:                 * Therefore we must restrict the length to SSIZE_MAX to
                    273:                 * avoid garbage return values.
                    274:                 */
                    275:                if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
                    276:                        error = EINVAL;
                    277:                        goto done;
                    278:                }
                    279:                iov++;
                    280:        }
1.46      ad        281:
1.1       mrg       282:        /*
                    283:         * if tracing, save a copy of iovec
                    284:         */
1.46      ad        285:        if (ktrpoint(KTR_GENIO))  {
1.9       jdolecek  286:                ktriov = malloc(iovlen, M_TEMP, M_WAITOK);
1.36      christos  287:                memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen);
1.1       mrg       288:        }
1.46      ad        289:
1.1       mrg       290:        cnt = auio.uio_resid;
                    291:        error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
                    292:        if (error) {
                    293:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    294:                    error == EINTR || error == EWOULDBLOCK))
                    295:                        error = 0;
1.44      ad        296:                if (error == EPIPE) {
                    297:                        mutex_enter(&proclist_mutex);
1.51    ! ad        298:                        psignal(curproc, SIGPIPE);
1.44      ad        299:                        mutex_exit(&proclist_mutex);
                    300:                }
1.1       mrg       301:        }
                    302:        cnt -= auio.uio_resid;
1.46      ad        303:        if (ktriov != NULL) {
                    304:                ktrgenio(fd, UIO_WRITE, ktriov, cnt, error);
1.9       jdolecek  305:                free(ktriov, M_TEMP);
1.1       mrg       306:        }
                    307:        *retval = cnt;
                    308: done:
                    309:        if (needfree)
1.9       jdolecek  310:                free(needfree, M_IOV);
                    311: out:
1.51    ! ad        312:        fd_putfile(fd);
1.1       mrg       313:        return (error);
                    314: }
                    315:
1.43      dsl       316: /*
                    317:  * Common routine to set access and modification times given a vnode.
                    318:  */
                    319: static int
                    320: get_utimes32(const netbsd32_timevalp_t *tptr, struct timeval *tv,
                    321:     struct timeval **tvp)
                    322: {
                    323:        int error;
                    324:        struct netbsd32_timeval tv32[2];
                    325:
                    326:        if (tptr == NULL) {
                    327:                *tvp = NULL;
                    328:                return 0;
                    329:        }
                    330:
                    331:        error = copyin(tptr, tv32, sizeof(tv32));
                    332:        if (error)
                    333:                return error;
                    334:        netbsd32_to_timeval(&tv32[0], &tv[0]);
                    335:        netbsd32_to_timeval(&tv32[1], &tv[1]);
                    336:
                    337:        *tvp = tv;
                    338:        return 0;
                    339: }
                    340:
1.1       mrg       341: int
1.49      dsl       342: netbsd32_utimes(struct lwp *l, const struct netbsd32_utimes_args *uap, register_t *retval)
1.1       mrg       343: {
1.49      dsl       344:        /* {
1.1       mrg       345:                syscallarg(const netbsd32_charp) path;
                    346:                syscallarg(const netbsd32_timevalp_t) tptr;
1.49      dsl       347:        } */
1.1       mrg       348:        int error;
1.43      dsl       349:        struct timeval tv[2], *tvp;
1.1       mrg       350:
1.43      dsl       351:        error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
                    352:        if (error != 0)
                    353:                return error;
1.1       mrg       354:
1.43      dsl       355:        return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW,
                    356:                            tvp, UIO_SYSSPACE);
1.1       mrg       357: }
                    358:
1.42      dsl       359: static int
                    360: netbds32_copyout_statvfs(const void *kp, void *up, size_t len)
                    361: {
                    362:        struct netbsd32_statvfs *sbuf_32;
                    363:        int error;
                    364:
                    365:        sbuf_32 = malloc(sizeof *sbuf_32, M_TEMP, M_WAITOK);
                    366:        netbsd32_from_statvfs(kp, sbuf_32);
                    367:        error = copyout(sbuf_32, up, sizeof(*sbuf_32));
                    368:        free(sbuf_32, M_TEMP);
                    369:
                    370:        return error;
                    371: }
                    372:
1.1       mrg       373: int
1.49      dsl       374: netbsd32_statvfs1(struct lwp *l, const struct netbsd32_statvfs1_args *uap, register_t *retval)
1.1       mrg       375: {
1.49      dsl       376:        /* {
1.1       mrg       377:                syscallarg(const netbsd32_charp) path;
1.18      cube      378:                syscallarg(netbsd32_statvfsp_t) buf;
                    379:                syscallarg(int) flags;
1.49      dsl       380:        } */
1.42      dsl       381:        struct statvfs *sb;
1.1       mrg       382:        int error;
                    383:
1.42      dsl       384:        sb = STATVFSBUF_GET();
                    385:        error = do_sys_pstatvfs(l, SCARG_P32(uap, path), SCARG(uap, flags), sb);
                    386:        if (error == 0)
                    387:                error = netbds32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0);
                    388:        STATVFSBUF_PUT(sb);
                    389:        return error;
1.1       mrg       390: }
                    391:
                    392: int
1.49      dsl       393: netbsd32_fstatvfs1(struct lwp *l, const struct netbsd32_fstatvfs1_args *uap, register_t *retval)
1.1       mrg       394: {
1.49      dsl       395:        /* {
1.1       mrg       396:                syscallarg(int) fd;
1.18      cube      397:                syscallarg(netbsd32_statvfsp_t) buf;
                    398:                syscallarg(int) flags;
1.49      dsl       399:        } */
1.42      dsl       400:        struct statvfs *sb;
1.1       mrg       401:        int error;
                    402:
1.42      dsl       403:        sb = STATVFSBUF_GET();
                    404:        error = do_sys_fstatvfs(l, SCARG(uap, fd), SCARG(uap, flags), sb);
                    405:        if (error == 0)
                    406:                error = netbds32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0);
                    407:        STATVFSBUF_PUT(sb);
1.18      cube      408:        return error;
                    409: }
                    410:
                    411: int
1.49      dsl       412: netbsd32_getvfsstat(struct lwp *l, const struct netbsd32_getvfsstat_args *uap, register_t *retval)
1.18      cube      413: {
1.49      dsl       414:        /* {
1.18      cube      415:                syscallarg(netbsd32_statvfsp_t) buf;
                    416:                syscallarg(netbsd32_size_t) bufsize;
                    417:                syscallarg(int) flags;
1.49      dsl       418:        } */
1.18      cube      419:
1.42      dsl       420:        return do_sys_getvfsstat(l, SCARG_P32(uap, buf), SCARG(uap, bufsize),
                    421:            SCARG(uap, flags), netbds32_copyout_statvfs,
                    422:            sizeof (struct netbsd32_statvfs), retval);
1.18      cube      423: }
                    424:
                    425: int
1.49      dsl       426: netbsd32___fhstatvfs140(struct lwp *l, const struct netbsd32___fhstatvfs140_args *uap, register_t *retval)
1.18      cube      427: {
1.49      dsl       428:        /* {
1.32      martin    429:                syscallarg(const netbsd32_pointer_t) fhp;
                    430:                syscallarg(netbsd32_size_t) fh_size;
1.18      cube      431:                syscallarg(netbsd32_statvfsp_t) buf;
                    432:                syscallarg(int) flags;
1.49      dsl       433:        } */
1.42      dsl       434:        struct statvfs *sb;
1.18      cube      435:        int error;
                    436:
1.42      dsl       437:        sb = STATVFSBUF_GET();
                    438:        error = do_fhstatvfs(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), sb,
                    439:            SCARG(uap, flags));
                    440:
                    441:        if (error == 0)
                    442:                error = netbds32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0);
                    443:        STATVFSBUF_PUT(sb);
1.18      cube      444:
1.42      dsl       445:        return error;
1.1       mrg       446: }
                    447:
                    448: int
1.49      dsl       449: netbsd32_futimes(struct lwp *l, const struct netbsd32_futimes_args *uap, register_t *retval)
1.1       mrg       450: {
1.49      dsl       451:        /* {
1.1       mrg       452:                syscallarg(int) fd;
                    453:                syscallarg(const netbsd32_timevalp_t) tptr;
1.49      dsl       454:        } */
1.1       mrg       455:        int error;
1.51    ! ad        456:        file_t *fp;
1.43      dsl       457:        struct timeval tv[2], *tvp;
                    458:
                    459:        error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
                    460:        if (error != 0)
                    461:                return error;
1.1       mrg       462:
                    463:        /* getvnode() will use the descriptor for us */
1.51    ! ad        464:        if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
1.1       mrg       465:                return (error);
                    466:
1.43      dsl       467:        error = do_sys_utimes(l, fp->f_data, NULL, 0, tvp, UIO_SYSSPACE);
                    468:
1.51    ! ad        469:        fd_putfile(SCARG(uap, fd));
1.1       mrg       470:        return (error);
                    471: }
                    472:
                    473: int
1.49      dsl       474: netbsd32_sys___getdents30(struct lwp *l, const struct netbsd32_sys___getdents30_args *uap, register_t *retval)
1.1       mrg       475: {
1.49      dsl       476:        /* {
1.1       mrg       477:                syscallarg(int) fd;
                    478:                syscallarg(netbsd32_charp) buf;
                    479:                syscallarg(netbsd32_size_t) count;
1.49      dsl       480:        } */
1.51    ! ad        481:        file_t *fp;
1.1       mrg       482:        int error, done;
                    483:
                    484:        /* getvnode() will use the descriptor for us */
1.51    ! ad        485:        if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
1.1       mrg       486:                return (error);
                    487:        if ((fp->f_flag & FREAD) == 0) {
                    488:                error = EBADF;
                    489:                goto out;
                    490:        }
1.39      dsl       491:        error = vn_readdir(fp, SCARG_P32(uap, buf),
1.23      christos  492:            UIO_USERSPACE, SCARG(uap, count), &done, l, 0, 0);
1.1       mrg       493:        *retval = done;
                    494:  out:
1.51    ! ad        495:        fd_putfile(SCARG(uap, fd));
1.1       mrg       496:        return (error);
                    497: }
                    498:
                    499: int
1.49      dsl       500: netbsd32_lutimes(struct lwp *l, const struct netbsd32_lutimes_args *uap, register_t *retval)
1.1       mrg       501: {
1.49      dsl       502:        /* {
1.1       mrg       503:                syscallarg(const netbsd32_charp) path;
                    504:                syscallarg(const netbsd32_timevalp_t) tptr;
1.49      dsl       505:        } */
1.1       mrg       506:        int error;
1.43      dsl       507:        struct timeval tv[2], *tvp;
1.1       mrg       508:
1.43      dsl       509:        error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
                    510:        if (error != 0)
                    511:                return error;
1.1       mrg       512:
1.43      dsl       513:        return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW,
                    514:                            tvp, UIO_SYSSPACE);
1.1       mrg       515: }
                    516:
                    517: int
1.49      dsl       518: netbsd32_sys___stat30(struct lwp *l, const struct netbsd32_sys___stat30_args *uap, register_t *retval)
1.1       mrg       519: {
1.49      dsl       520:        /* {
1.1       mrg       521:                syscallarg(const netbsd32_charp) path;
                    522:                syscallarg(netbsd32_statp_t) ub;
1.49      dsl       523:        } */
1.1       mrg       524:        struct netbsd32_stat sb32;
                    525:        struct stat sb;
                    526:        int error;
                    527:        const char *path;
                    528:
1.39      dsl       529:        path = SCARG_P32(uap, path);
1.1       mrg       530:
1.51    ! ad        531:        error = do_sys_stat(path, FOLLOW, &sb);
1.41      dsl       532:        if (error)
                    533:                return (error);
1.22      christos  534:        netbsd32_from___stat30(&sb, &sb32);
1.39      dsl       535:        error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
1.1       mrg       536:        return (error);
                    537: }
                    538:
                    539: int
1.49      dsl       540: netbsd32_sys___fstat30(struct lwp *l, const struct netbsd32_sys___fstat30_args *uap, register_t *retval)
1.1       mrg       541: {
1.49      dsl       542:        /* {
1.1       mrg       543:                syscallarg(int) fd;
                    544:                syscallarg(netbsd32_statp_t) sb;
1.49      dsl       545:        } */
1.1       mrg       546:        int fd = SCARG(uap, fd);
1.51    ! ad        547:        file_t *fp;
1.1       mrg       548:        struct netbsd32_stat sb32;
                    549:        struct stat ub;
                    550:        int error = 0;
                    551:
1.51    ! ad        552:        if ((fp = fd_getfile(fd)) == NULL)
1.1       mrg       553:                return (EBADF);
1.51    ! ad        554:        error = (*fp->f_ops->fo_stat)(fp, &ub);
        !           555:        fd_putfile(fd);
1.1       mrg       556:        if (error == 0) {
1.22      christos  557:                netbsd32_from___stat30(&ub, &sb32);
1.39      dsl       558:                error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32));
1.1       mrg       559:        }
                    560:        return (error);
                    561: }
                    562:
                    563: int
1.49      dsl       564: netbsd32_sys___lstat30(struct lwp *l, const struct netbsd32_sys___lstat30_args *uap, register_t *retval)
1.1       mrg       565: {
1.49      dsl       566:        /* {
1.1       mrg       567:                syscallarg(const netbsd32_charp) path;
                    568:                syscallarg(netbsd32_statp_t) ub;
1.49      dsl       569:        } */
1.1       mrg       570:        struct netbsd32_stat sb32;
                    571:        struct stat sb;
                    572:        int error;
                    573:        const char *path;
                    574:
1.39      dsl       575:        path = SCARG_P32(uap, path);
1.1       mrg       576:
1.51    ! ad        577:        error = do_sys_stat(path, NOFOLLOW, &sb);
1.1       mrg       578:        if (error)
                    579:                return (error);
1.22      christos  580:        netbsd32_from___stat30(&sb, &sb32);
1.39      dsl       581:        error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
1.1       mrg       582:        return (error);
                    583: }
                    584:
1.49      dsl       585: int
                    586: netbsd32___fhstat40(struct lwp *l, const struct netbsd32___fhstat40_args *uap, register_t *retval)
1.26      cube      587: {
1.49      dsl       588:        /* {
1.32      martin    589:                syscallarg(const netbsd32_pointer_t) fhp;
                    590:                syscallarg(netbsd32_size_t) fh_size;
1.26      cube      591:                syscallarg(netbsd32_statp_t) sb;
1.49      dsl       592:        } */
1.26      cube      593:        struct stat sb;
                    594:        struct netbsd32_stat sb32;
                    595:        int error;
                    596:
1.42      dsl       597:        error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb);
                    598:        if (error != 0) {
                    599:                netbsd32_from___stat30(&sb, &sb32);
                    600:                error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb));
                    601:        }
1.29      martin    602:        return error;
1.26      cube      603: }
                    604:
1.1       mrg       605: int
1.49      dsl       606: netbsd32_preadv(struct lwp *l, const struct netbsd32_preadv_args *uap, register_t *retval)
1.1       mrg       607: {
1.49      dsl       608:        /* {
1.1       mrg       609:                syscallarg(int) fd;
                    610:                syscallarg(const netbsd32_iovecp_t) iovp;
                    611:                syscallarg(int) iovcnt;
                    612:                syscallarg(int) pad;
                    613:                syscallarg(off_t) offset;
1.49      dsl       614:        } */
1.51    ! ad        615:        file_t *fp;
1.1       mrg       616:        struct vnode *vp;
                    617:        off_t offset;
                    618:        int error, fd = SCARG(uap, fd);
                    619:
1.51    ! ad        620:        if ((fp = fd_getfile(fd)) == NULL)
1.6       thorpej   621:                return (EBADF);
                    622:
1.50      dsl       623:        if ((fp->f_flag & FREAD) == 0) {
1.51    ! ad        624:                fd_putfile(fd);
1.1       mrg       625:                return (EBADF);
1.50      dsl       626:        }
1.1       mrg       627:
1.51    ! ad        628:        vp = fp->f_data;
1.9       jdolecek  629:        if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
                    630:                error = ESPIPE;
                    631:                goto out;
                    632:        }
1.1       mrg       633:
                    634:        offset = SCARG(uap, offset);
                    635:
                    636:        /*
                    637:         * XXX This works because no file systems actually
                    638:         * XXX take any action on the seek operation.
                    639:         */
                    640:        if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
1.9       jdolecek  641:                goto out;
1.1       mrg       642:
1.51    ! ad        643:        return (dofilereadv32(fd, fp, SCARG_P32(uap, iovp),
1.10      scw       644:            SCARG(uap, iovcnt), &offset, 0, retval));
1.9       jdolecek  645:
                    646: out:
1.51    ! ad        647:        fd_putfile(fd);
1.9       jdolecek  648:        return (error);
1.1       mrg       649: }
                    650:
                    651: int
1.49      dsl       652: netbsd32_pwritev(struct lwp *l, const struct netbsd32_pwritev_args *uap, register_t *retval)
1.1       mrg       653: {
1.49      dsl       654:        /* {
1.1       mrg       655:                syscallarg(int) fd;
                    656:                syscallarg(const netbsd32_iovecp_t) iovp;
                    657:                syscallarg(int) iovcnt;
                    658:                syscallarg(int) pad;
                    659:                syscallarg(off_t) offset;
1.49      dsl       660:        } */
1.51    ! ad        661:        file_t *fp;
1.1       mrg       662:        struct vnode *vp;
                    663:        off_t offset;
                    664:        int error, fd = SCARG(uap, fd);
                    665:
1.51    ! ad        666:        if ((fp = fd_getfile(fd)) == NULL)
1.6       thorpej   667:                return (EBADF);
                    668:
1.50      dsl       669:        if ((fp->f_flag & FWRITE) == 0) {
1.51    ! ad        670:                fd_putfile(fd);
1.1       mrg       671:                return (EBADF);
1.50      dsl       672:        }
1.1       mrg       673:
1.51    ! ad        674:        vp = fp->f_data;
1.9       jdolecek  675:        if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
                    676:                error = ESPIPE;
                    677:                goto out;
                    678:        }
1.1       mrg       679:
                    680:        offset = SCARG(uap, offset);
                    681:
                    682:        /*
                    683:         * XXX This works because no file systems actually
                    684:         * XXX take any action on the seek operation.
                    685:         */
                    686:        if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
1.9       jdolecek  687:                goto out;
1.1       mrg       688:
1.51    ! ad        689:        return (dofilewritev32(fd, fp, SCARG_P32(uap, iovp),
1.10      scw       690:            SCARG(uap, iovcnt), &offset, 0, retval));
1.9       jdolecek  691:
                    692: out:
1.51    ! ad        693:        fd_putfile(fd);
1.9       jdolecek  694:        return (error);
1.1       mrg       695: }
                    696:
                    697: /*
                    698:  * Find pathname of process's current directory.
                    699:  *
                    700:  * Use vfs vnode-to-name reverse cache; if that fails, fall back
                    701:  * to reading directory contents.
                    702:  */
1.23      christos  703: /* XXX NH Why does this exist */
1.14      fvdl      704: int
1.47      dsl       705: getcwd_common(struct vnode *, struct vnode *,
                    706:                   char **, char *, int, int, struct lwp *);
1.14      fvdl      707:
1.49      dsl       708: int
                    709: netbsd32___getcwd(struct lwp *l, const struct netbsd32___getcwd_args *uap, register_t *retval)
1.1       mrg       710: {
1.49      dsl       711:        /* {
1.1       mrg       712:                syscallarg(char *) bufp;
                    713:                syscallarg(size_t) length;
1.49      dsl       714:        } */
1.11      thorpej   715:        struct proc *p = l->l_proc;
1.1       mrg       716:        int     error;
                    717:        char   *path;
                    718:        char   *bp, *bend;
                    719:        int     len = (int)SCARG(uap, length);
                    720:        int     lenused;
                    721:
                    722:        if (len > MAXPATHLEN*4)
                    723:                len = MAXPATHLEN*4;
                    724:        else if (len < 2)
                    725:                return ERANGE;
                    726:
                    727:        path = (char *)malloc(len, M_TEMP, M_WAITOK);
                    728:        if (!path)
                    729:                return ENOMEM;
                    730:
                    731:        bp = &path[len];
                    732:        bend = bp;
                    733:        *(--bp) = '\0';
                    734:
                    735:        /*
                    736:         * 5th argument here is "max number of vnodes to traverse".
                    737:         * Since each entry takes up at least 2 bytes in the output buffer,
                    738:         * limit it to N/2 vnodes for an N byte buffer.
                    739:         */
                    740: #define GETCWD_CHECK_ACCESS 0x0001
                    741:        error = getcwd_common (p->p_cwdi->cwdi_cdir, NULL, &bp, path, len/2,
1.23      christos  742:                               GETCWD_CHECK_ACCESS, l);
1.1       mrg       743:
                    744:        if (error)
                    745:                goto out;
                    746:        lenused = bend - bp;
                    747:        *retval = lenused;
                    748:        /* put the result into user buffer */
1.39      dsl       749:        error = copyout(bp, SCARG_P32(uap, bufp), lenused);
1.1       mrg       750:
                    751: out:
                    752:        free(path, M_TEMP);
                    753:        return error;
                    754: }

CVSweb <webmaster@jp.NetBSD.org>