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

Annotation of sys/compat/linux/linux_file.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: linux_file.c,v 1.23 2006/09/25 07:12:57 otto Exp $    */
                      2: /*     $NetBSD: linux_file.c,v 1.15 1996/05/20 01:59:09 fvdl Exp $     */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Frank van der Linden
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed for the NetBSD Project
                     19:  *      by Frank van der Linden
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/namei.h>
                     38: #include <sys/proc.h>
                     39: #include <sys/file.h>
                     40: #include <sys/stat.h>
                     41: #include <sys/filedesc.h>
                     42: #include <sys/ioctl.h>
                     43: #include <sys/kernel.h>
                     44: #include <sys/mount.h>
                     45: #include <sys/signalvar.h>
                     46: #include <sys/uio.h>
                     47: #include <sys/malloc.h>
                     48: #include <sys/vnode.h>
                     49: #include <sys/tty.h>
                     50: #include <sys/conf.h>
                     51:
                     52: #include <sys/syscallargs.h>
                     53:
                     54: #include <compat/linux/linux_types.h>
                     55: #include <compat/linux/linux_signal.h>
                     56: #include <compat/linux/linux_syscallargs.h>
                     57: #include <compat/linux/linux_fcntl.h>
                     58: #include <compat/linux/linux_util.h>
                     59:
                     60: #include <machine/linux_machdep.h>
                     61:
                     62: static int linux_to_bsd_ioflags(int);
                     63: static int bsd_to_linux_ioflags(int);
                     64: static void bsd_to_linux_flock(struct flock *, struct linux_flock *);
                     65: static void linux_to_bsd_flock(struct linux_flock *, struct flock *);
                     66: static void bsd_to_linux_stat(struct stat *, struct linux_stat *);
                     67: static int linux_stat1(struct proc *, void *, register_t *, int);
                     68:
                     69:
                     70: /*
                     71:  * Some file-related calls are handled here. The usual flag conversion
                     72:  * an structure conversion is done, and alternate emul path searching.
                     73:  */
                     74:
                     75: /*
                     76:  * The next two functions convert between the Linux and OpenBSD values
                     77:  * of the flags used in open(2) and fcntl(2).
                     78:  */
                     79: static int
                     80: linux_to_bsd_ioflags(lflags)
                     81:        int lflags;
                     82: {
                     83:        int res = 0;
                     84:
                     85:        res |= cvtto_bsd_mask(lflags, LINUX_O_WRONLY, O_WRONLY);
                     86:        res |= cvtto_bsd_mask(lflags, LINUX_O_RDONLY, O_RDONLY);
                     87:        res |= cvtto_bsd_mask(lflags, LINUX_O_RDWR, O_RDWR);
                     88:        res |= cvtto_bsd_mask(lflags, LINUX_O_CREAT, O_CREAT);
                     89:        res |= cvtto_bsd_mask(lflags, LINUX_O_EXCL, O_EXCL);
                     90:        res |= cvtto_bsd_mask(lflags, LINUX_O_NOCTTY, O_NOCTTY);
                     91:        res |= cvtto_bsd_mask(lflags, LINUX_O_TRUNC, O_TRUNC);
                     92:        res |= cvtto_bsd_mask(lflags, LINUX_O_NDELAY, O_NDELAY);
                     93:        res |= cvtto_bsd_mask(lflags, LINUX_O_SYNC, O_SYNC);
                     94:        res |= cvtto_bsd_mask(lflags, LINUX_FASYNC, O_ASYNC);
                     95:        res |= cvtto_bsd_mask(lflags, LINUX_O_APPEND, O_APPEND);
                     96:
                     97:        return res;
                     98: }
                     99:
                    100: static int
                    101: bsd_to_linux_ioflags(bflags)
                    102:        int bflags;
                    103: {
                    104:        int res = 0;
                    105:
                    106:        res |= cvtto_linux_mask(bflags, O_WRONLY, LINUX_O_WRONLY);
                    107:        res |= cvtto_linux_mask(bflags, O_RDONLY, LINUX_O_RDONLY);
                    108:        res |= cvtto_linux_mask(bflags, O_RDWR, LINUX_O_RDWR);
                    109:        res |= cvtto_linux_mask(bflags, O_CREAT, LINUX_O_CREAT);
                    110:        res |= cvtto_linux_mask(bflags, O_EXCL, LINUX_O_EXCL);
                    111:        res |= cvtto_linux_mask(bflags, O_NOCTTY, LINUX_O_NOCTTY);
                    112:        res |= cvtto_linux_mask(bflags, O_TRUNC, LINUX_O_TRUNC);
                    113:        res |= cvtto_linux_mask(bflags, O_NDELAY, LINUX_O_NDELAY);
                    114:        res |= cvtto_linux_mask(bflags, O_SYNC, LINUX_O_SYNC);
                    115:        res |= cvtto_linux_mask(bflags, O_ASYNC, LINUX_FASYNC);
                    116:        res |= cvtto_linux_mask(bflags, O_APPEND, LINUX_O_APPEND);
                    117:
                    118:        return res;
                    119: }
                    120:
                    121: /*
                    122:  * creat(2) is an obsolete function, but it's present as a Linux
                    123:  * system call, so let's deal with it.
                    124:  *
                    125:  * Just call open(2) with the TRUNC, CREAT and WRONLY flags.
                    126:  */
                    127: int
                    128: linux_sys_creat(p, v, retval)
                    129:        struct proc *p;
                    130:        void *v;
                    131:        register_t *retval;
                    132: {
                    133:        struct linux_sys_creat_args /* {
                    134:                syscallarg(char *) path;
                    135:                syscallarg(int) mode;
                    136:        } */ *uap = v;
                    137:        struct sys_open_args oa;
                    138:        caddr_t sg;
                    139:
                    140:        sg = stackgap_init(p->p_emul);
                    141:        LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
                    142:
                    143:        SCARG(&oa, path) = SCARG(uap, path);
                    144:        SCARG(&oa, flags) = O_CREAT | O_TRUNC | O_WRONLY;
                    145:        SCARG(&oa, mode) = SCARG(uap, mode);
                    146:
                    147:        return sys_open(p, &oa, retval);
                    148: }
                    149:
                    150: /*
                    151:  * open(2). Take care of the different flag values, and let the
                    152:  * OpenBSD syscall do the real work. See if this operation
                    153:  * gives the current process a controlling terminal.
                    154:  * (XXX is this necessary?)
                    155:  */
                    156: int
                    157: linux_sys_open(p, v, retval)
                    158:        struct proc *p;
                    159:        void *v;
                    160:        register_t *retval;
                    161: {
                    162:        struct linux_sys_open_args /* {
                    163:                syscallarg(char *) path;
                    164:                syscallarg(int) flags;
                    165:                syscallarg(int) mode;
                    166:        } */ *uap = v;
                    167:        int error, fl;
                    168:        struct sys_open_args boa;
                    169:        caddr_t sg;
                    170:
                    171:        sg = stackgap_init(p->p_emul);
                    172:
                    173:        fl = linux_to_bsd_ioflags(SCARG(uap, flags));
                    174:
                    175:        if (fl & O_CREAT)
                    176:                LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
                    177:        else
                    178:                LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    179:
                    180:        SCARG(&boa, path) = SCARG(uap, path);
                    181:        SCARG(&boa, flags) = fl;
                    182:        SCARG(&boa, mode) = SCARG(uap, mode);
                    183:
                    184:        if ((error = sys_open(p, &boa, retval)))
                    185:                return error;
                    186:
                    187:        /*
                    188:         * this bit from sunos_misc.c (and svr4_fcntl.c).
                    189:         * If we are a session leader, and we don't have a controlling
                    190:         * terminal yet, and the O_NOCTTY flag is not set, try to make
                    191:         * this the controlling terminal.
                    192:         */
                    193:         if (!(fl & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
                    194:                 struct filedesc *fdp = p->p_fd;
                    195:                 struct file     *fp;
                    196:
                    197:                if ((fp = fd_getfile(fdp, *retval)) == NULL)
                    198:                        return (EBADF);
                    199:                FREF(fp);
                    200:                 if (fp->f_type == DTYPE_VNODE)
                    201:                         (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, p);
                    202:                FRELE(fp);
                    203:         }
                    204:        return 0;
                    205: }
                    206:
                    207: /*
                    208:  * This appears to be part of a Linux attempt to switch to 64 bits file sizes.
                    209:  */
                    210: int
                    211: linux_sys_llseek(p, v, retval)
                    212:        struct proc *p;
                    213:        void *v;
                    214:        register_t *retval;
                    215: {
                    216:        struct linux_sys_llseek_args /* {
                    217:                syscallarg(int) fd;
                    218:                syscallarg(uint32_t) ohigh;
                    219:                syscallarg(uint32_t) olow;
                    220:                syscallarg(caddr_t) res;
                    221:                syscallarg(int) whence;
                    222:        } */ *uap = v;
                    223:        struct sys_lseek_args bla;
                    224:        int error;
                    225:        off_t off;
                    226:
                    227:        off = SCARG(uap, olow) | (((off_t) SCARG(uap, ohigh)) << 32);
                    228:
                    229:        SCARG(&bla, fd) = SCARG(uap, fd);
                    230:        SCARG(&bla, offset) = off;
                    231:        SCARG(&bla, whence) = SCARG(uap, whence);
                    232:
                    233:        if ((error = sys_lseek(p, &bla, retval)))
                    234:                return error;
                    235:
                    236:        if ((error = copyout(retval, SCARG(uap, res), sizeof (off_t))))
                    237:                return error;
                    238:
                    239:        retval[0] = 0;
                    240:        return 0;
                    241: }
                    242:
                    243: /*
                    244:  * The next two functions take care of converting the flock
                    245:  * structure back and forth between Linux and OpenBSD format.
                    246:  * The only difference in the structures is the order of
                    247:  * the fields, and the 'whence' value.
                    248:  */
                    249: static void
                    250: bsd_to_linux_flock(bfp, lfp)
                    251:        struct flock *bfp;
                    252:        struct linux_flock *lfp;
                    253: {
                    254:
                    255:        lfp->l_start = bfp->l_start;
                    256:        lfp->l_len = bfp->l_len;
                    257:        lfp->l_pid = bfp->l_pid;
                    258:        lfp->l_whence = bfp->l_whence;
                    259:        switch (bfp->l_type) {
                    260:        case F_RDLCK:
                    261:                lfp->l_type = LINUX_F_RDLCK;
                    262:                break;
                    263:        case F_UNLCK:
                    264:                lfp->l_type = LINUX_F_UNLCK;
                    265:                break;
                    266:        case F_WRLCK:
                    267:                lfp->l_type = LINUX_F_WRLCK;
                    268:                break;
                    269:        }
                    270: }
                    271:
                    272: static void
                    273: linux_to_bsd_flock(lfp, bfp)
                    274:        struct linux_flock *lfp;
                    275:        struct flock *bfp;
                    276: {
                    277:
                    278:        bfp->l_start = lfp->l_start;
                    279:        bfp->l_len = lfp->l_len;
                    280:        bfp->l_pid = lfp->l_pid;
                    281:        bfp->l_whence = lfp->l_whence;
                    282:        switch (lfp->l_type) {
                    283:        case LINUX_F_RDLCK:
                    284:                bfp->l_type = F_RDLCK;
                    285:                break;
                    286:        case LINUX_F_UNLCK:
                    287:                bfp->l_type = F_UNLCK;
                    288:                break;
                    289:        case LINUX_F_WRLCK:
                    290:                bfp->l_type = F_WRLCK;
                    291:                break;
                    292:        }
                    293: }
                    294:
                    295: /*
                    296:  * Most actions in the fcntl() call are straightforward; simply
                    297:  * pass control to the OpenBSD system call. A few commands need
                    298:  * conversions after the actual system call has done its work,
                    299:  * because the flag values and lock structure are different.
                    300:  */
                    301: int
                    302: linux_sys_fcntl(p, v, retval)
                    303:        struct proc *p;
                    304:        void *v;
                    305:        register_t *retval;
                    306: {
                    307:        struct linux_sys_fcntl_args /* {
                    308:                syscallarg(int) fd;
                    309:                syscallarg(int) cmd;
                    310:                syscallarg(void *) arg;
                    311:        } */ *uap = v;
                    312:        int fd, cmd, error, val;
                    313:        caddr_t arg, sg;
                    314:        struct linux_flock lfl;
                    315:        struct flock *bfp, bfl;
                    316:        struct sys_fcntl_args fca;
                    317:        struct filedesc *fdp;
                    318:        struct file *fp;
                    319:        struct vnode *vp;
                    320:        struct vattr va;
                    321:        long pgid;
                    322:        struct pgrp *pgrp;
                    323:        struct tty *tp, *(*d_tty)(dev_t);
                    324:
                    325:        fd = SCARG(uap, fd);
                    326:        cmd = SCARG(uap, cmd);
                    327:        arg = (caddr_t) SCARG(uap, arg);
                    328:
                    329:        switch (cmd) {
                    330:        case LINUX_F_DUPFD:
                    331:                cmd = F_DUPFD;
                    332:                break;
                    333:        case LINUX_F_GETFD:
                    334:                cmd = F_GETFD;
                    335:                break;
                    336:        case LINUX_F_SETFD:
                    337:                cmd = F_SETFD;
                    338:                break;
                    339:        case LINUX_F_GETFL:
                    340:                SCARG(&fca, fd) = fd;
                    341:                SCARG(&fca, cmd) = F_GETFL;
                    342:                SCARG(&fca, arg) = arg;
                    343:                if ((error = sys_fcntl(p, &fca, retval)))
                    344:                        return error;
                    345:                retval[0] = bsd_to_linux_ioflags(retval[0]);
                    346:                return 0;
                    347:        case LINUX_F_SETFL:
                    348:                val = linux_to_bsd_ioflags((int)SCARG(uap, arg));
                    349:                SCARG(&fca, fd) = fd;
                    350:                SCARG(&fca, cmd) = F_SETFL;
                    351:                SCARG(&fca, arg) = (caddr_t) val;
                    352:                return sys_fcntl(p, &fca, retval);
                    353:        case LINUX_F_GETLK:
                    354:                sg = stackgap_init(p->p_emul);
                    355:                if ((error = copyin(arg, &lfl, sizeof lfl)))
                    356:                        return error;
                    357:                linux_to_bsd_flock(&lfl, &bfl);
                    358:                bfp = (struct flock *) stackgap_alloc(&sg, sizeof *bfp);
                    359:                SCARG(&fca, fd) = fd;
                    360:                SCARG(&fca, cmd) = F_GETLK;
                    361:                SCARG(&fca, arg) = bfp;
                    362:                if ((error = copyout(&bfl, bfp, sizeof bfl)))
                    363:                        return error;
                    364:                if ((error = sys_fcntl(p, &fca, retval)))
                    365:                        return error;
                    366:                if ((error = copyin(bfp, &bfl, sizeof bfl)))
                    367:                        return error;
                    368:                bsd_to_linux_flock(&bfl, &lfl);
                    369:                error = copyout(&lfl, arg, sizeof lfl);
                    370:                return error;
                    371:                break;
                    372:        case LINUX_F_SETLK:
                    373:        case LINUX_F_SETLKW:
                    374:                cmd = (cmd == LINUX_F_SETLK ? F_SETLK : F_SETLKW);
                    375:                if ((error = copyin(arg, &lfl, sizeof lfl)))
                    376:                        return error;
                    377:                linux_to_bsd_flock(&lfl, &bfl);
                    378:                sg = stackgap_init(p->p_emul);
                    379:                bfp = (struct flock *) stackgap_alloc(&sg, sizeof *bfp);
                    380:                if ((error = copyout(&bfl, bfp, sizeof bfl)))
                    381:                        return error;
                    382:                SCARG(&fca, fd) = fd;
                    383:                SCARG(&fca, cmd) = cmd;
                    384:                SCARG(&fca, arg) = bfp;
                    385:                return sys_fcntl(p, &fca, retval);
                    386:                break;
                    387:        case LINUX_F_SETOWN:
                    388:        case LINUX_F_GETOWN:
                    389:                /*
                    390:                 * We need to route around the normal fcntl() for these calls,
                    391:                 * since it uses TIOC{G,S}PGRP, which is too restrictive for
                    392:                 * Linux F_{G,S}ETOWN semantics. For sockets, this problem
                    393:                 * does not exist.
                    394:                 */
                    395:                fdp = p->p_fd;
                    396:                if ((fp = fd_getfile(fdp, fd)) == NULL)
                    397:                        return (EBADF);
                    398:                if (fp->f_type == DTYPE_SOCKET) {
                    399:                        cmd = cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
                    400:                        break;
                    401:                }
                    402:                vp = (struct vnode *)fp->f_data;
                    403:                if (vp->v_type != VCHR)
                    404:                        return EINVAL;
                    405:                FREF(fp);
                    406:                error = VOP_GETATTR(vp, &va, p->p_ucred, p);
                    407:                FRELE(fp);
                    408:                if (error)
                    409:                        return error;
                    410:                d_tty = cdevsw[major(va.va_rdev)].d_tty;
                    411:                if (!d_tty || (!(tp = (*d_tty)(va.va_rdev))))
                    412:                        return EINVAL;
                    413:                if (cmd == LINUX_F_GETOWN) {
                    414:                        retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
                    415:                        return 0;
                    416:                }
                    417:                if ((long)arg <= 0) {
                    418:                        pgid = -(long)arg;
                    419:                } else {
                    420:                        struct proc *p1 = pfind((long)arg);
                    421:                        if (p1 == 0)
                    422:                                return (ESRCH);
                    423:                        pgid = (long)p1->p_pgrp->pg_id;
                    424:                }
                    425:                pgrp = pgfind(pgid);
                    426:                if (pgrp == NULL || pgrp->pg_session != p->p_session)
                    427:                        return EPERM;
                    428:                tp->t_pgrp = pgrp;
                    429:                return 0;
                    430:        default:
                    431:                return EOPNOTSUPP;
                    432:        }
                    433:
                    434:        SCARG(&fca, fd) = fd;
                    435:        SCARG(&fca, cmd) = cmd;
                    436:        SCARG(&fca, arg) = arg;
                    437:
                    438:        return sys_fcntl(p, &fca, retval);
                    439: }
                    440:
                    441: /*
                    442:  * Convert a OpenBSD stat structure to a Linux stat structure.
                    443:  * Only the order of the fields and the padding in the structure
                    444:  * is different. linux_fakedev is a machine-dependent function
                    445:  * which optionally converts device driver major/minor numbers
                    446:  * (XXX horrible, but what can you do against code that compares
                    447:  * things against constant major device numbers? sigh)
                    448:  */
                    449: static void
                    450: bsd_to_linux_stat(bsp, lsp)
                    451:        struct stat *bsp;
                    452:        struct linux_stat *lsp;
                    453: {
                    454:
                    455:        lsp->lst_dev     = bsp->st_dev;
                    456:        lsp->lst_ino     = bsp->st_ino;
                    457:        lsp->lst_mode    = bsp->st_mode;
                    458:        lsp->lst_nlink   = bsp->st_nlink;
                    459:        lsp->lst_uid     = bsp->st_uid;
                    460:        lsp->lst_gid     = bsp->st_gid;
                    461:        lsp->lst_rdev    = linux_fakedev(bsp->st_rdev);
                    462:        lsp->lst_size    = bsp->st_size;
                    463:        lsp->lst_blksize = bsp->st_blksize;
                    464:        lsp->lst_blocks  = bsp->st_blocks;
                    465:        lsp->lst_atime   = bsp->st_atime;
                    466:        lsp->lst_mtime   = bsp->st_mtime;
                    467:        lsp->lst_ctime   = bsp->st_ctime;
                    468: }
                    469:
                    470: /*
                    471:  * The stat functions below are plain sailing. stat and lstat are handled
                    472:  * by one function to avoid code duplication.
                    473:  */
                    474: int
                    475: linux_sys_fstat(p, v, retval)
                    476:        struct proc *p;
                    477:        void *v;
                    478:        register_t *retval;
                    479: {
                    480:        struct linux_sys_fstat_args /* {
                    481:                syscallarg(int) fd;
                    482:                syscallarg(linux_stat *) sp;
                    483:        } */ *uap = v;
                    484:        struct sys_fstat_args fsa;
                    485:        struct linux_stat tmplst;
                    486:        struct stat *st,tmpst;
                    487:        caddr_t sg;
                    488:        int error;
                    489:
                    490:        sg = stackgap_init(p->p_emul);
                    491:
                    492:        st = stackgap_alloc(&sg, sizeof (struct stat));
                    493:
                    494:        SCARG(&fsa, fd) = SCARG(uap, fd);
                    495:        SCARG(&fsa, sb) = st;
                    496:
                    497:        if ((error = sys_fstat(p, &fsa, retval)))
                    498:                return error;
                    499:
                    500:        if ((error = copyin(st, &tmpst, sizeof tmpst)))
                    501:                return error;
                    502:
                    503:        bsd_to_linux_stat(&tmpst, &tmplst);
                    504:
                    505:        if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst)))
                    506:                return error;
                    507:
                    508:        return 0;
                    509: }
                    510:
                    511: static int
                    512: linux_stat1(p, v, retval, dolstat)
                    513:        struct proc *p;
                    514:        void *v;
                    515:        register_t *retval;
                    516:        int dolstat;
                    517: {
                    518:        struct sys_stat_args sa;
                    519:        struct linux_stat tmplst;
                    520:        struct stat *st, tmpst;
                    521:        caddr_t sg;
                    522:        int error;
                    523:        struct linux_sys_stat_args *uap = v;
                    524:
                    525:        sg = stackgap_init(p->p_emul);
                    526:
                    527:        st = stackgap_alloc(&sg, sizeof (struct stat));
                    528:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    529:
                    530:        SCARG(&sa, ub) = st;
                    531:        SCARG(&sa, path) = SCARG(uap, path);
                    532:
                    533:        if ((error = (dolstat ? sys_lstat(p, &sa, retval) :
                    534:                                sys_stat(p, &sa, retval))))
                    535:                return error;
                    536:
                    537:        if ((error = copyin(st, &tmpst, sizeof tmpst)))
                    538:                return error;
                    539:
                    540:        bsd_to_linux_stat(&tmpst, &tmplst);
                    541:
                    542:        if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst)))
                    543:                return error;
                    544:
                    545:        return 0;
                    546: }
                    547:
                    548: int
                    549: linux_sys_stat(p, v, retval)
                    550:        struct proc *p;
                    551:        void *v;
                    552:        register_t *retval;
                    553: {
                    554:        struct linux_sys_stat_args /* {
                    555:                syscallarg(char *) path;
                    556:                syscallarg(struct linux_stat *) sp;
                    557:        } */ *uap = v;
                    558:
                    559:        return linux_stat1(p, uap, retval, 0);
                    560: }
                    561:
                    562: int
                    563: linux_sys_lstat(p, v, retval)
                    564:        struct proc *p;
                    565:        void *v;
                    566:        register_t *retval;
                    567: {
                    568:        struct linux_sys_lstat_args /* {
                    569:                syscallarg(char *) path;
                    570:                syscallarg(struct linux_stat *) sp;
                    571:        } */ *uap = v;
                    572:
                    573:        return linux_stat1(p, uap, retval, 1);
                    574: }
                    575:
                    576: /*
                    577:  * The following syscalls are mostly here because of the alternate path check.
                    578:  */
                    579: int
                    580: linux_sys_access(p, v, retval)
                    581:        struct proc *p;
                    582:        void *v;
                    583:        register_t *retval;
                    584: {
                    585:        struct linux_sys_access_args /* {
                    586:                syscallarg(char *) path;
                    587:                syscallarg(int) flags;
                    588:        } */ *uap = v;
                    589:        caddr_t sg = stackgap_init(p->p_emul);
                    590:
                    591:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    592:
                    593:        return sys_access(p, uap, retval);
                    594: }
                    595:
                    596: int
                    597: linux_sys_unlink(p, v, retval)
                    598:        struct proc *p;
                    599:        void *v;
                    600:        register_t *retval;
                    601:
                    602: {
                    603:        struct linux_sys_unlink_args /* {
                    604:                syscallarg(char *) path;
                    605:        } */ *uap = v;
                    606:        caddr_t sg = stackgap_init(p->p_emul);
                    607:
                    608:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    609:
                    610:        return sys_unlink(p, uap, retval);
                    611: }
                    612:
                    613: int
                    614: linux_sys_chdir(p, v, retval)
                    615:        struct proc *p;
                    616:        void *v;
                    617:        register_t *retval;
                    618: {
                    619:        struct linux_sys_chdir_args /* {
                    620:                syscallarg(char *) path;
                    621:        } */ *uap = v;
                    622:        caddr_t sg = stackgap_init(p->p_emul);
                    623:
                    624:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    625:
                    626:        return sys_chdir(p, uap, retval);
                    627: }
                    628:
                    629: int
                    630: linux_sys_mknod(p, v, retval)
                    631:        struct proc *p;
                    632:        void *v;
                    633:        register_t *retval;
                    634: {
                    635:        struct linux_sys_mknod_args /* {
                    636:                syscallarg(char *) path;
                    637:                syscallarg(int) mode;
                    638:                syscallarg(int) dev;
                    639:        } */ *uap = v;
                    640:        caddr_t sg = stackgap_init(p->p_emul);
                    641:        struct sys_mkfifo_args bma;
                    642:
                    643:        LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
                    644:
                    645:        /*
                    646:         * BSD handles FIFOs separately
                    647:         */
                    648:        if (S_ISFIFO(SCARG(uap, mode))) {
                    649:                SCARG(&bma, path) = SCARG(uap, path);
                    650:                SCARG(&bma, mode) = SCARG(uap, mode);
                    651:                return sys_mkfifo(p, uap, retval);
                    652:        } else
                    653:                return sys_mknod(p, uap, retval);
                    654: }
                    655:
                    656: int
                    657: linux_sys_chmod(p, v, retval)
                    658:        struct proc *p;
                    659:        void *v;
                    660:        register_t *retval;
                    661: {
                    662:        struct linux_sys_chmod_args /* {
                    663:                syscallarg(char *) path;
                    664:                syscallarg(int) mode;
                    665:        } */ *uap = v;
                    666:        caddr_t sg = stackgap_init(p->p_emul);
                    667:
                    668:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    669:
                    670:        return sys_chmod(p, uap, retval);
                    671: }
                    672:
                    673: int
                    674: linux_sys_chown16(p, v, retval)
                    675:        struct proc *p;
                    676:        void *v;
                    677:        register_t *retval;
                    678: {
                    679:        struct linux_sys_chown16_args /* {
                    680:                syscallarg(char *) path;
                    681:                syscallarg(int) uid;
                    682:                syscallarg(int) gid;
                    683:        } */ *uap = v;
                    684:        struct sys_chown_args bca;
                    685:        caddr_t sg = stackgap_init(p->p_emul);
                    686:
                    687:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    688:
                    689:        SCARG(&bca, path) = SCARG(uap, path);
                    690:        SCARG(&bca, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
                    691:                (uid_t)-1 : SCARG(uap, uid);
                    692:        SCARG(&bca, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
                    693:                (gid_t)-1 : SCARG(uap, gid);
                    694:
                    695:        return sys_chown(p, &bca, retval);
                    696: }
                    697:
                    698: int
                    699: linux_sys_fchown16(p, v, retval)
                    700:        struct proc *p;
                    701:        void *v;
                    702:        register_t *retval;
                    703: {
                    704:        struct linux_sys_fchown16_args /* {
                    705:                syscallarg(int) fd;
                    706:                syscallarg(int) uid;
                    707:                syscallarg(int) gid;
                    708:        } */ *uap = v;
                    709:        struct sys_fchown_args bfa;
                    710:
                    711:        SCARG(&bfa, fd) = SCARG(uap, fd);
                    712:        SCARG(&bfa, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
                    713:                (uid_t)-1 : SCARG(uap, uid);
                    714:        SCARG(&bfa, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
                    715:                (gid_t)-1 : SCARG(uap, gid);
                    716:
                    717:        return sys_fchown(p, &bfa, retval);
                    718: }
                    719:
                    720: int
                    721: linux_sys_lchown16(p, v, retval)
                    722:        struct proc *p;
                    723:        void *v;
                    724:        register_t *retval;
                    725: {
                    726:        struct linux_sys_lchown16_args /* {
                    727:                syscallarg(char *) path;
                    728:                syscallarg(int) uid;
                    729:                syscallarg(int) gid;
                    730:        } */ *uap = v;
                    731:        struct sys_lchown_args bla;
                    732:
                    733:        SCARG(&bla, path) = SCARG(uap, path);
                    734:        SCARG(&bla, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
                    735:                (uid_t)-1 : SCARG(uap, uid);
                    736:        SCARG(&bla, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
                    737:                (gid_t)-1 : SCARG(uap, gid);
                    738:
                    739:        return sys_lchown(p, &bla, retval);
                    740: }
                    741:
                    742: int
                    743: linux_sys_rename(p, v, retval)
                    744:        struct proc *p;
                    745:        void *v;
                    746:        register_t *retval;
                    747: {
                    748:        struct linux_sys_rename_args /* {
                    749:                syscallarg(char *) from;
                    750:                syscallarg(char *) to;
                    751:        } */ *uap = v;
                    752:        caddr_t sg = stackgap_init(p->p_emul);
                    753:
                    754:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
                    755:        LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
                    756:
                    757:        return sys_rename(p, uap, retval);
                    758: }
                    759:
                    760: int
                    761: linux_sys_mkdir(p, v, retval)
                    762:        struct proc *p;
                    763:        void *v;
                    764:        register_t *retval;
                    765: {
                    766:        struct linux_sys_mkdir_args /* {
                    767:                syscallarg(char *) path;
                    768:                syscallarg(int) mode;
                    769:        } */ *uap = v;
                    770:        caddr_t sg = stackgap_init(p->p_emul);
                    771:
                    772:        LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
                    773:
                    774:        return sys_mkdir(p, uap, retval);
                    775: }
                    776:
                    777: int
                    778: linux_sys_rmdir(p, v, retval)
                    779:        struct proc *p;
                    780:        void *v;
                    781:        register_t *retval;
                    782: {
                    783:        struct linux_sys_rmdir_args /* {
                    784:                syscallarg(char *) path;
                    785:        } */ *uap = v;
                    786:        caddr_t sg = stackgap_init(p->p_emul);
                    787:
                    788:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    789:
                    790:        return sys_rmdir(p, uap, retval);
                    791: }
                    792:
                    793: int
                    794: linux_sys_symlink(p, v, retval)
                    795:        struct proc *p;
                    796:        void *v;
                    797:        register_t *retval;
                    798: {
                    799:        struct linux_sys_symlink_args /* {
                    800:                syscallarg(char *) path;
                    801:                syscallarg(char *) to;
                    802:        } */ *uap = v;
                    803:        caddr_t sg = stackgap_init(p->p_emul);
                    804:
                    805:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    806:        LINUX_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
                    807:
                    808:        return sys_symlink(p, uap, retval);
                    809: }
                    810:
                    811: int
                    812: linux_sys_readlink(p, v, retval)
                    813:        struct proc *p;
                    814:        void *v;
                    815:        register_t *retval;
                    816: {
                    817:        struct linux_sys_readlink_args /* {
                    818:                syscallarg(char *) name;
                    819:                syscallarg(char *) buf;
                    820:                syscallarg(int) count;
                    821:        } */ *uap = v;
                    822:        caddr_t sg = stackgap_init(p->p_emul);
                    823:
                    824:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, name));
                    825:
                    826:        return sys_readlink(p, uap, retval);
                    827: }
                    828:
                    829: int
                    830: linux_sys_truncate(p, v, retval)
                    831:        struct proc *p;
                    832:        void *v;
                    833:        register_t *retval;
                    834: {
                    835:        struct linux_sys_truncate_args /* {
                    836:                syscallarg(char *) path;
                    837:                syscallarg(long) length;
                    838:        } */ *uap = v;
                    839:        caddr_t sg = stackgap_init(p->p_emul);
                    840:
                    841:        LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
                    842:
                    843:        return compat_43_sys_truncate(p, uap, retval);
                    844: }
                    845:
                    846: /*
                    847:  * This is just fsync() for now (just as it is in the Linux kernel)
                    848:  */
                    849: int
                    850: linux_sys_fdatasync(p, v, retval)
                    851:        struct proc *p;
                    852:        void *v;
                    853:        register_t *retval;
                    854: {
                    855:        struct linux_sys_fdatasync_args /* {
                    856:                syscallarg(int) fd;
                    857:        } */ *uap = v;
                    858:        return sys_fsync(p, uap, retval);
                    859: }
                    860:
                    861: /*
                    862:  * pread(2).
                    863:  */
                    864: int
                    865: linux_sys_pread(p, v, retval)
                    866:        struct proc *p;
                    867:        void *v;
                    868:        register_t *retval;
                    869: {
                    870:        struct linux_sys_pread_args /* {
                    871:                syscallarg(int) fd;
                    872:                syscallarg(void *) buf;
                    873:                syscallarg(size_t) nbyte;
                    874:                syscallarg(linux_off_t) offset;
                    875:        } */ *uap = v;
                    876:        struct sys_pread_args pra;
                    877:
                    878:        SCARG(&pra, fd) = SCARG(uap, fd);
                    879:        SCARG(&pra, buf) = SCARG(uap, buf);
                    880:        SCARG(&pra, nbyte) = SCARG(uap, nbyte);
                    881:        SCARG(&pra, offset) = SCARG(uap, offset);
                    882:
                    883:        return sys_pread(p, &pra, retval);
                    884: }
                    885:
                    886: /*
                    887:  * pwrite(2).
                    888:  */
                    889: int
                    890: linux_sys_pwrite(p, v, retval)
                    891:        struct proc *p;
                    892:        void *v;
                    893:        register_t *retval;
                    894: {
                    895:        struct linux_sys_pwrite_args /* {
                    896:                syscallarg(int) fd;
                    897:                syscallarg(char *) buf;
                    898:                syscallarg(size_t) nbyte;
                    899:                syscallarg(linux_off_t) offset;
                    900:        } */ *uap = v;
                    901:        struct sys_pwrite_args pra;
                    902:
                    903:        SCARG(&pra, fd) = SCARG(uap, fd);
                    904:        SCARG(&pra, buf) = SCARG(uap, buf);
                    905:        SCARG(&pra, nbyte) = SCARG(uap, nbyte);
                    906:        SCARG(&pra, offset) = SCARG(uap, offset);
                    907:
                    908:        return sys_pwrite(p, &pra, retval);
                    909: }

CVSweb