[BACK]Return to linux_file.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / linux / common

Annotation of src/sys/compat/linux/common/linux_file.c, Revision 1.73.4.3

1.73.4.3! ad          1: /*     $NetBSD: linux_file.c,v 1.73.4.2 2006/11/18 21:39:07 ad Exp $   */
1.23      erh         2:
                      3: /*-
1.25      fvdl        4:  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
1.23      erh         5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.25      fvdl        8:  * by Frank van der Linden and Eric Haszlakiewicz.
1.23      erh         9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the NetBSD
                     21:  *     Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
1.1       fvdl       37:  */
                     38:
1.23      erh        39: /*
                     40:  * Functions in multiarch:
                     41:  *     linux_sys_llseek        : linux_llseek.c
                     42:  */
1.43      lukem      43:
                     44: #include <sys/cdefs.h>
1.73.4.3! ad         45: __KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.73.4.2 2006/11/18 21:39:07 ad Exp $");
1.23      erh        46:
1.1       fvdl       47: #include <sys/param.h>
                     48: #include <sys/systm.h>
                     49: #include <sys/namei.h>
                     50: #include <sys/proc.h>
                     51: #include <sys/file.h>
                     52: #include <sys/stat.h>
                     53: #include <sys/filedesc.h>
                     54: #include <sys/ioctl.h>
                     55: #include <sys/kernel.h>
                     56: #include <sys/mount.h>
                     57: #include <sys/malloc.h>
1.13      fvdl       58: #include <sys/vnode.h>
                     59: #include <sys/tty.h>
1.39      manu       60: #include <sys/socketvar.h>
1.13      fvdl       61: #include <sys/conf.h>
1.41      jdolecek   62: #include <sys/pipe.h>
1.1       fvdl       63:
                     64: #include <sys/syscallargs.h>
                     65:
1.24      christos   66: #include <compat/linux/common/linux_types.h>
                     67: #include <compat/linux/common/linux_signal.h>
                     68: #include <compat/linux/common/linux_fcntl.h>
                     69: #include <compat/linux/common/linux_util.h>
                     70: #include <compat/linux/common/linux_machdep.h>
                     71:
1.1       fvdl       72: #include <compat/linux/linux_syscallargs.h>
1.14      christos   73:
                     74: static int linux_to_bsd_ioflags __P((int));
                     75: static int bsd_to_linux_ioflags __P((int));
                     76: static void bsd_to_linux_flock __P((struct flock *, struct linux_flock *));
                     77: static void linux_to_bsd_flock __P((struct linux_flock *, struct flock *));
1.67      manu       78: #ifndef __amd64__
1.14      christos   79: static void bsd_to_linux_stat __P((struct stat *, struct linux_stat *));
1.56      thorpej    80: static int linux_stat1 __P((struct lwp *, void *, register_t *, int));
1.67      manu       81: #endif
1.14      christos   82:
1.1       fvdl       83: /*
                     84:  * Some file-related calls are handled here. The usual flag conversion
                     85:  * an structure conversion is done, and alternate emul path searching.
                     86:  */
                     87:
                     88: /*
                     89:  * The next two functions convert between the Linux and NetBSD values
                     90:  * of the flags used in open(2) and fcntl(2).
                     91:  */
                     92: static int
1.14      christos   93: linux_to_bsd_ioflags(lflags)
                     94:        int lflags;
1.1       fvdl       95: {
                     96:        int res = 0;
                     97:
                     98:        res |= cvtto_bsd_mask(lflags, LINUX_O_WRONLY, O_WRONLY);
                     99:        res |= cvtto_bsd_mask(lflags, LINUX_O_RDONLY, O_RDONLY);
                    100:        res |= cvtto_bsd_mask(lflags, LINUX_O_RDWR, O_RDWR);
                    101:        res |= cvtto_bsd_mask(lflags, LINUX_O_CREAT, O_CREAT);
                    102:        res |= cvtto_bsd_mask(lflags, LINUX_O_EXCL, O_EXCL);
                    103:        res |= cvtto_bsd_mask(lflags, LINUX_O_NOCTTY, O_NOCTTY);
                    104:        res |= cvtto_bsd_mask(lflags, LINUX_O_TRUNC, O_TRUNC);
                    105:        res |= cvtto_bsd_mask(lflags, LINUX_O_NDELAY, O_NDELAY);
                    106:        res |= cvtto_bsd_mask(lflags, LINUX_O_SYNC, O_FSYNC);
                    107:        res |= cvtto_bsd_mask(lflags, LINUX_FASYNC, O_ASYNC);
                    108:        res |= cvtto_bsd_mask(lflags, LINUX_O_APPEND, O_APPEND);
                    109:
                    110:        return res;
                    111: }
                    112:
                    113: static int
1.14      christos  114: bsd_to_linux_ioflags(bflags)
                    115:        int bflags;
1.1       fvdl      116: {
                    117:        int res = 0;
                    118:
                    119:        res |= cvtto_linux_mask(bflags, O_WRONLY, LINUX_O_WRONLY);
                    120:        res |= cvtto_linux_mask(bflags, O_RDONLY, LINUX_O_RDONLY);
                    121:        res |= cvtto_linux_mask(bflags, O_RDWR, LINUX_O_RDWR);
                    122:        res |= cvtto_linux_mask(bflags, O_CREAT, LINUX_O_CREAT);
                    123:        res |= cvtto_linux_mask(bflags, O_EXCL, LINUX_O_EXCL);
                    124:        res |= cvtto_linux_mask(bflags, O_NOCTTY, LINUX_O_NOCTTY);
                    125:        res |= cvtto_linux_mask(bflags, O_TRUNC, LINUX_O_TRUNC);
                    126:        res |= cvtto_linux_mask(bflags, O_NDELAY, LINUX_O_NDELAY);
                    127:        res |= cvtto_linux_mask(bflags, O_FSYNC, LINUX_O_SYNC);
                    128:        res |= cvtto_linux_mask(bflags, O_ASYNC, LINUX_FASYNC);
                    129:        res |= cvtto_linux_mask(bflags, O_APPEND, LINUX_O_APPEND);
                    130:
                    131:        return res;
                    132: }
                    133:
                    134: /*
                    135:  * creat(2) is an obsolete function, but it's present as a Linux
                    136:  * system call, so let's deal with it.
                    137:  *
1.23      erh       138:  * Note: On the Alpha this doesn't really exist in Linux, but it's defined
                    139:  * in syscalls.master anyway so this doesn't have to be special cased.
                    140:  *
1.1       fvdl      141:  * Just call open(2) with the TRUNC, CREAT and WRONLY flags.
                    142:  */
                    143: int
1.56      thorpej   144: linux_sys_creat(l, v, retval)
                    145:        struct lwp *l;
1.11      thorpej   146:        void *v;
                    147:        register_t *retval;
                    148: {
1.12      mycroft   149:        struct linux_sys_creat_args /* {
1.27      christos  150:                syscallarg(const char *) path;
1.1       fvdl      151:                syscallarg(int) mode;
1.11      thorpej   152:        } */ *uap = v;
1.56      thorpej   153:        struct proc *p = l->l_proc;
1.12      mycroft   154:        struct sys_open_args oa;
1.1       fvdl      155:        caddr_t sg;
                    156:
1.46      christos  157:        sg = stackgap_init(p, 0);
1.71      christos  158:        CHECK_ALT_CREAT(l, &sg, SCARG(uap, path));
1.1       fvdl      159:
                    160:        SCARG(&oa, path) = SCARG(uap, path);
                    161:        SCARG(&oa, flags) = O_CREAT | O_TRUNC | O_WRONLY;
                    162:        SCARG(&oa, mode) = SCARG(uap, mode);
1.12      mycroft   163:
1.56      thorpej   164:        return sys_open(l, &oa, retval);
1.1       fvdl      165: }
                    166:
                    167: /*
                    168:  * open(2). Take care of the different flag values, and let the
                    169:  * NetBSD syscall do the real work. See if this operation
                    170:  * gives the current process a controlling terminal.
                    171:  * (XXX is this necessary?)
                    172:  */
                    173: int
1.56      thorpej   174: linux_sys_open(l, v, retval)
                    175:        struct lwp *l;
1.11      thorpej   176:        void *v;
                    177:        register_t *retval;
                    178: {
1.12      mycroft   179:        struct linux_sys_open_args /* {
1.27      christos  180:                syscallarg(const char *) path;
1.1       fvdl      181:                syscallarg(int) flags;
                    182:                syscallarg(int) mode;
1.11      thorpej   183:        } */ *uap = v;
1.56      thorpej   184:        struct proc *p = l->l_proc;
1.1       fvdl      185:        int error, fl;
1.12      mycroft   186:        struct sys_open_args boa;
1.1       fvdl      187:        caddr_t sg;
                    188:
1.46      christos  189:        sg = stackgap_init(p, 0);
1.1       fvdl      190:
1.2       fvdl      191:        fl = linux_to_bsd_ioflags(SCARG(uap, flags));
1.1       fvdl      192:
1.2       fvdl      193:        if (fl & O_CREAT)
1.71      christos  194:                CHECK_ALT_CREAT(l, &sg, SCARG(uap, path));
1.2       fvdl      195:        else
1.71      christos  196:                CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.1       fvdl      197:
                    198:        SCARG(&boa, path) = SCARG(uap, path);
                    199:        SCARG(&boa, flags) = fl;
                    200:        SCARG(&boa, mode) = SCARG(uap, mode);
1.2       fvdl      201:
1.56      thorpej   202:        if ((error = sys_open(l, &boa, retval)))
1.1       fvdl      203:                return error;
                    204:
                    205:        /*
                    206:         * this bit from sunos_misc.c (and svr4_fcntl.c).
                    207:         * If we are a session leader, and we don't have a controlling
                    208:         * terminal yet, and the O_NOCTTY flag is not set, try to make
                    209:         * this the controlling terminal.
1.65      perry     210:         */
1.73.4.1  ad        211:         if (!(fl & O_NOCTTY) && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
1.1       fvdl      212:                 struct filedesc *fdp = p->p_fd;
1.38      thorpej   213:                 struct file     *fp;
                    214:
                    215:                fp = fd_getfile(fdp, *retval);
1.1       fvdl      216:
                    217:                 /* ignore any error, just give it a try */
1.57      yamt      218:                 if (fp != NULL) {
                    219:                        FILE_USE(fp);
                    220:                        if (fp->f_type == DTYPE_VNODE) {
                    221:                                (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY,
1.71      christos  222:                                    (caddr_t) 0, l);
1.57      yamt      223:                        }
1.71      christos  224:                        FILE_UNUSE(fp, l);
1.57      yamt      225:                }
1.1       fvdl      226:         }
                    227:        return 0;
                    228: }
                    229:
                    230: /*
                    231:  * The next two functions take care of converting the flock
                    232:  * structure back and forth between Linux and NetBSD format.
                    233:  * The only difference in the structures is the order of
                    234:  * the fields, and the 'whence' value.
                    235:  */
                    236: static void
                    237: bsd_to_linux_flock(bfp, lfp)
                    238:        struct flock *bfp;
                    239:        struct linux_flock *lfp;
                    240: {
1.12      mycroft   241:
1.1       fvdl      242:        lfp->l_start = bfp->l_start;
                    243:        lfp->l_len = bfp->l_len;
                    244:        lfp->l_pid = bfp->l_pid;
1.3       mycroft   245:        lfp->l_whence = bfp->l_whence;
                    246:        switch (bfp->l_type) {
1.1       fvdl      247:        case F_RDLCK:
1.3       mycroft   248:                lfp->l_type = LINUX_F_RDLCK;
1.1       fvdl      249:                break;
                    250:        case F_UNLCK:
1.3       mycroft   251:                lfp->l_type = LINUX_F_UNLCK;
1.1       fvdl      252:                break;
                    253:        case F_WRLCK:
1.3       mycroft   254:                lfp->l_type = LINUX_F_WRLCK;
1.1       fvdl      255:                break;
                    256:        }
                    257: }
                    258:
                    259: static void
                    260: linux_to_bsd_flock(lfp, bfp)
                    261:        struct linux_flock *lfp;
                    262:        struct flock *bfp;
                    263: {
1.12      mycroft   264:
1.1       fvdl      265:        bfp->l_start = lfp->l_start;
                    266:        bfp->l_len = lfp->l_len;
                    267:        bfp->l_pid = lfp->l_pid;
1.3       mycroft   268:        bfp->l_whence = lfp->l_whence;
                    269:        switch (lfp->l_type) {
1.1       fvdl      270:        case LINUX_F_RDLCK:
1.3       mycroft   271:                bfp->l_type = F_RDLCK;
1.1       fvdl      272:                break;
                    273:        case LINUX_F_UNLCK:
1.3       mycroft   274:                bfp->l_type = F_UNLCK;
1.1       fvdl      275:                break;
                    276:        case LINUX_F_WRLCK:
1.3       mycroft   277:                bfp->l_type = F_WRLCK;
1.1       fvdl      278:                break;
                    279:        }
                    280: }
                    281:
                    282: /*
                    283:  * Most actions in the fcntl() call are straightforward; simply
                    284:  * pass control to the NetBSD system call. A few commands need
                    285:  * conversions after the actual system call has done its work,
                    286:  * because the flag values and lock structure are different.
                    287:  */
                    288: int
1.56      thorpej   289: linux_sys_fcntl(l, v, retval)
                    290:        struct lwp *l;
1.11      thorpej   291:        void *v;
                    292:        register_t *retval;
                    293: {
1.12      mycroft   294:        struct linux_sys_fcntl_args /* {
1.1       fvdl      295:                syscallarg(int) fd;
                    296:                syscallarg(int) cmd;
                    297:                syscallarg(void *) arg;
1.11      thorpej   298:        } */ *uap = v;
1.56      thorpej   299:        struct proc *p = l->l_proc;
1.23      erh       300:        int fd, cmd, error;
                    301:        u_long val;
1.1       fvdl      302:        caddr_t arg, sg;
                    303:        struct linux_flock lfl;
                    304:        struct flock *bfp, bfl;
1.12      mycroft   305:        struct sys_fcntl_args fca;
1.13      fvdl      306:        struct filedesc *fdp;
                    307:        struct file *fp;
                    308:        struct vnode *vp;
                    309:        struct vattr va;
1.53      gehenna   310:        const struct cdevsw *cdev;
1.13      fvdl      311:        long pgid;
                    312:        struct pgrp *pgrp;
                    313:        struct tty *tp, *(*d_tty) __P((dev_t));
1.1       fvdl      314:
                    315:        fd = SCARG(uap, fd);
                    316:        cmd = SCARG(uap, cmd);
                    317:        arg = (caddr_t) SCARG(uap, arg);
                    318:
                    319:        switch (cmd) {
                    320:        case LINUX_F_DUPFD:
                    321:                cmd = F_DUPFD;
                    322:                break;
                    323:        case LINUX_F_GETFD:
                    324:                cmd = F_GETFD;
                    325:                break;
                    326:        case LINUX_F_SETFD:
                    327:                cmd = F_SETFD;
                    328:                break;
                    329:        case LINUX_F_GETFL:
                    330:                SCARG(&fca, fd) = fd;
                    331:                SCARG(&fca, cmd) = F_GETFL;
                    332:                SCARG(&fca, arg) = arg;
1.56      thorpej   333:                if ((error = sys_fcntl(l, &fca, retval)))
1.1       fvdl      334:                        return error;
                    335:                retval[0] = bsd_to_linux_ioflags(retval[0]);
                    336:                return 0;
1.41      jdolecek  337:        case LINUX_F_SETFL: {
1.69      christos  338:                struct file     *fp1 = NULL;
1.41      jdolecek  339:
1.23      erh       340:                val = linux_to_bsd_ioflags((unsigned long)SCARG(uap, arg));
1.39      manu      341:                /*
1.41      jdolecek  342:                 * Linux seems to have same semantics for sending SIGIO to the
1.64      abs       343:                 * read side of socket, but slightly different semantics
1.41      jdolecek  344:                 * for SIGIO to the write side.  Rather than sending the SIGIO
                    345:                 * every time it's possible to write (directly) more data, it
                    346:                 * only sends SIGIO if last write(2) failed due to insufficient
                    347:                 * memory to hold the data. This is compatible enough
                    348:                 * with NetBSD semantics to not do anything about the
                    349:                 * difference.
1.65      perry     350:                 *
1.41      jdolecek  351:                 * Linux does NOT send SIGIO for pipes. Deal with socketpair
                    352:                 * ones and DTYPE_PIPE ones. For these, we don't set
                    353:                 * the underlying flags (we don't pass O_ASYNC flag down
                    354:                 * to sys_fcntl()), but set the FASYNC flag for file descriptor,
                    355:                 * so that F_GETFL would report the ASYNC i/o is on.
1.39      manu      356:                 */
1.41      jdolecek  357:                if (val & O_ASYNC) {
1.69      christos  358:                        if (((fp1 = fd_getfile(p->p_fd, fd)) == NULL))
1.39      manu      359:                            return (EBADF);
                    360:
1.69      christos  361:                        FILE_USE(fp1);
1.39      manu      362:
1.69      christos  363:                        if (((fp1->f_type == DTYPE_SOCKET) && fp1->f_data
                    364:                              && ((struct socket *)fp1->f_data)->so_state & SS_ISAPIPE)
                    365:                            || (fp1->f_type == DTYPE_PIPE))
1.41      jdolecek  366:                                val &= ~O_ASYNC;
                    367:                        else {
                    368:                                /* not a pipe, do not modify anything */
1.71      christos  369:                                FILE_UNUSE(fp1, l);
1.69      christos  370:                                fp1 = NULL;
1.39      manu      371:                        }
1.41      jdolecek  372:                }
                    373:
                    374:                SCARG(&fca, fd) = fd;
                    375:                SCARG(&fca, cmd) = F_SETFL;
                    376:                SCARG(&fca, arg) = (caddr_t) val;
1.39      manu      377:
1.56      thorpej   378:                error = sys_fcntl(l, &fca, retval);
1.41      jdolecek  379:
                    380:                /* Now set the FASYNC flag for pipes */
1.69      christos  381:                if (fp1) {
1.41      jdolecek  382:                        if (!error)
1.69      christos  383:                                fp1->f_flag |= FASYNC;
1.71      christos  384:                        FILE_UNUSE(fp1, l);
1.39      manu      385:                }
1.41      jdolecek  386:
                    387:                return (error);
                    388:            }
1.1       fvdl      389:        case LINUX_F_GETLK:
1.46      christos  390:                sg = stackgap_init(p, 0);
                    391:                bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp);
1.18      kleink    392:                if ((error = copyin(arg, &lfl, sizeof lfl)))
                    393:                        return error;
                    394:                linux_to_bsd_flock(&lfl, &bfl);
                    395:                if ((error = copyout(&bfl, bfp, sizeof bfl)))
                    396:                        return error;
1.1       fvdl      397:                SCARG(&fca, fd) = fd;
                    398:                SCARG(&fca, cmd) = F_GETLK;
                    399:                SCARG(&fca, arg) = bfp;
1.56      thorpej   400:                if ((error = sys_fcntl(l, &fca, retval)))
1.1       fvdl      401:                        return error;
                    402:                if ((error = copyin(bfp, &bfl, sizeof bfl)))
                    403:                        return error;
                    404:                bsd_to_linux_flock(&bfl, &lfl);
                    405:                return copyout(&lfl, arg, sizeof lfl);
1.47      christos  406:
1.1       fvdl      407:        case LINUX_F_SETLK:
                    408:        case LINUX_F_SETLKW:
                    409:                cmd = (cmd == LINUX_F_SETLK ? F_SETLK : F_SETLKW);
                    410:                if ((error = copyin(arg, &lfl, sizeof lfl)))
                    411:                        return error;
                    412:                linux_to_bsd_flock(&lfl, &bfl);
1.46      christos  413:                sg = stackgap_init(p, 0);
                    414:                bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp);
1.1       fvdl      415:                if ((error = copyout(&bfl, bfp, sizeof bfl)))
                    416:                        return error;
1.51      christos  417:                arg = (caddr_t)bfp;
1.1       fvdl      418:                break;
1.47      christos  419:
1.1       fvdl      420:        case LINUX_F_SETOWN:
1.65      perry     421:        case LINUX_F_GETOWN:
1.13      fvdl      422:                /*
1.49      jdolecek  423:                 * We need to route fcntl() for tty descriptors around normal
                    424:                 * fcntl(), since NetBSD tty TIOC{G,S}PGRP semantics is too
                    425:                 * restrictive for Linux F_{G,S}ETOWN. For non-tty descriptors,
                    426:                 * this is not a problem.
1.13      fvdl      427:                 */
                    428:                fdp = p->p_fd;
1.38      thorpej   429:                if ((fp = fd_getfile(fdp, fd)) == NULL)
1.13      fvdl      430:                        return EBADF;
1.60      jdolecek  431:                FILE_USE(fp);
                    432:
                    433:                /* Check it's a character device vnode */
                    434:                if (fp->f_type != DTYPE_VNODE
                    435:                    || (vp = (struct vnode *)fp->f_data) == NULL
                    436:                    || vp->v_type != VCHR) {
1.71      christos  437:                        FILE_UNUSE(fp, l);
1.60      jdolecek  438:
1.53      gehenna   439:            not_tty:
1.49      jdolecek  440:                        /* Not a tty, proceed with common fcntl() */
1.13      fvdl      441:                        cmd = cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
1.49      jdolecek  442:                        break;
                    443:                }
1.47      christos  444:
1.73      ad        445:                error = VOP_GETATTR(vp, &va, l->l_cred, l);
1.60      jdolecek  446:
1.71      christos  447:                FILE_UNUSE(fp, l);
1.60      jdolecek  448:
                    449:                if (error)
1.49      jdolecek  450:                        return error;
1.60      jdolecek  451:
1.53      gehenna   452:                cdev = cdevsw_lookup(va.va_rdev);
                    453:                if (cdev == NULL)
                    454:                        return (ENXIO);
                    455:                d_tty = cdev->d_tty;
1.49      jdolecek  456:                if (!d_tty || (!(tp = (*d_tty)(va.va_rdev))))
1.53      gehenna   457:                        goto not_tty;
1.49      jdolecek  458:
                    459:                /* set tty pg_id appropriately */
                    460:                if (cmd == LINUX_F_GETOWN) {
1.58      dsl       461:                        retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
1.49      jdolecek  462:                        return 0;
                    463:                }
                    464:                if ((long)arg <= 0) {
                    465:                        pgid = -(long)arg;
                    466:                } else {
                    467:                        struct proc *p1 = pfind((long)arg);
                    468:                        if (p1 == NULL)
                    469:                                return (ESRCH);
                    470:                        pgid = (long)p1->p_pgrp->pg_id;
1.13      fvdl      471:                }
1.49      jdolecek  472:                pgrp = pgfind(pgid);
                    473:                if (pgrp == NULL || pgrp->pg_session != p->p_session)
                    474:                        return EPERM;
                    475:                tp->t_pgrp = pgrp;
                    476:                return 0;
1.47      christos  477:
1.1       fvdl      478:        default:
                    479:                return EOPNOTSUPP;
                    480:        }
                    481:
                    482:        SCARG(&fca, fd) = fd;
                    483:        SCARG(&fca, cmd) = cmd;
                    484:        SCARG(&fca, arg) = arg;
1.12      mycroft   485:
1.56      thorpej   486:        return sys_fcntl(l, &fca, retval);
1.1       fvdl      487: }
                    488:
1.67      manu      489: #if !defined(__amd64__)
1.1       fvdl      490: /*
                    491:  * Convert a NetBSD stat structure to a Linux stat structure.
                    492:  * Only the order of the fields and the padding in the structure
1.9       fvdl      493:  * is different. linux_fakedev is a machine-dependent function
                    494:  * which optionally converts device driver major/minor numbers
                    495:  * (XXX horrible, but what can you do against code that compares
                    496:  * things against constant major device numbers? sigh)
1.1       fvdl      497:  */
                    498: static void
                    499: bsd_to_linux_stat(bsp, lsp)
                    500:        struct stat *bsp;
                    501:        struct linux_stat *lsp;
                    502: {
1.12      mycroft   503:
1.45      christos  504:        lsp->lst_dev     = linux_fakedev(bsp->st_dev, 0);
1.1       fvdl      505:        lsp->lst_ino     = bsp->st_ino;
1.19      christos  506:        lsp->lst_mode    = (linux_mode_t)bsp->st_mode;
                    507:        if (bsp->st_nlink >= (1 << 15))
                    508:                lsp->lst_nlink = (1 << 15) - 1;
                    509:        else
                    510:                lsp->lst_nlink = (linux_nlink_t)bsp->st_nlink;
1.1       fvdl      511:        lsp->lst_uid     = bsp->st_uid;
                    512:        lsp->lst_gid     = bsp->st_gid;
1.45      christos  513:        lsp->lst_rdev    = linux_fakedev(bsp->st_rdev, 1);
1.1       fvdl      514:        lsp->lst_size    = bsp->st_size;
                    515:        lsp->lst_blksize = bsp->st_blksize;
                    516:        lsp->lst_blocks  = bsp->st_blocks;
                    517:        lsp->lst_atime   = bsp->st_atime;
                    518:        lsp->lst_mtime   = bsp->st_mtime;
                    519:        lsp->lst_ctime   = bsp->st_ctime;
1.66      christos  520: #ifdef LINUX_STAT_HAS_NSEC
                    521:        lsp->lst_atime_nsec   = bsp->st_atimensec;
                    522:        lsp->lst_mtime_nsec   = bsp->st_mtimensec;
                    523:        lsp->lst_ctime_nsec   = bsp->st_ctimensec;
                    524: #endif
1.1       fvdl      525: }
                    526:
                    527: /*
                    528:  * The stat functions below are plain sailing. stat and lstat are handled
                    529:  * by one function to avoid code duplication.
                    530:  */
                    531: int
1.56      thorpej   532: linux_sys_fstat(l, v, retval)
                    533:        struct lwp *l;
1.11      thorpej   534:        void *v;
                    535:        register_t *retval;
                    536: {
1.12      mycroft   537:        struct linux_sys_fstat_args /* {
1.1       fvdl      538:                syscallarg(int) fd;
                    539:                syscallarg(linux_stat *) sp;
1.11      thorpej   540:        } */ *uap = v;
1.56      thorpej   541:        struct proc *p = l->l_proc;
1.70      christos  542:        struct sys___fstat30_args fsa;
1.1       fvdl      543:        struct linux_stat tmplst;
                    544:        struct stat *st,tmpst;
                    545:        caddr_t sg;
                    546:        int error;
                    547:
1.46      christos  548:        sg = stackgap_init(p, 0);
1.1       fvdl      549:
1.46      christos  550:        st = stackgap_alloc(p, &sg, sizeof (struct stat));
1.1       fvdl      551:
                    552:        SCARG(&fsa, fd) = SCARG(uap, fd);
                    553:        SCARG(&fsa, sb) = st;
                    554:
1.70      christos  555:        if ((error = sys___fstat30(l, &fsa, retval)))
1.1       fvdl      556:                return error;
                    557:
                    558:        if ((error = copyin(st, &tmpst, sizeof tmpst)))
                    559:                return error;
                    560:
                    561:        bsd_to_linux_stat(&tmpst, &tmplst);
                    562:
                    563:        if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst)))
                    564:                return error;
                    565:
                    566:        return 0;
                    567: }
                    568:
                    569: static int
1.56      thorpej   570: linux_stat1(l, v, retval, dolstat)
                    571:        struct lwp *l;
1.14      christos  572:        void *v;
1.1       fvdl      573:        register_t *retval;
                    574:        int dolstat;
                    575: {
1.70      christos  576:        struct sys___stat30_args sa;
1.1       fvdl      577:        struct linux_stat tmplst;
                    578:        struct stat *st, tmpst;
1.56      thorpej   579:        struct proc *p = l->l_proc;
1.1       fvdl      580:        caddr_t sg;
                    581:        int error;
1.14      christos  582:        struct linux_sys_stat_args *uap = v;
1.1       fvdl      583:
1.46      christos  584:        sg = stackgap_init(p, 0);
                    585:        st = stackgap_alloc(p, &sg, sizeof (struct stat));
1.37      jdolecek  586:        if (dolstat)
1.71      christos  587:                CHECK_ALT_SYMLINK(l, &sg, SCARG(uap, path));
1.37      jdolecek  588:        else
1.71      christos  589:                CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.1       fvdl      590:
                    591:        SCARG(&sa, ub) = st;
                    592:        SCARG(&sa, path) = SCARG(uap, path);
                    593:
1.70      christos  594:        if ((error = (dolstat ? sys___lstat30(l, &sa, retval) :
                    595:                                sys___stat30(l, &sa, retval))))
1.1       fvdl      596:                return error;
                    597:
                    598:        if ((error = copyin(st, &tmpst, sizeof tmpst)))
                    599:                return error;
                    600:
                    601:        bsd_to_linux_stat(&tmpst, &tmplst);
                    602:
                    603:        if ((error = copyout(&tmplst, SCARG(uap, sp), sizeof tmplst)))
                    604:                return error;
                    605:
                    606:        return 0;
                    607: }
                    608:
                    609: int
1.56      thorpej   610: linux_sys_stat(l, v, retval)
                    611:        struct lwp *l;
1.11      thorpej   612:        void *v;
                    613:        register_t *retval;
                    614: {
1.12      mycroft   615:        struct linux_sys_stat_args /* {
1.27      christos  616:                syscallarg(const char *) path;
1.1       fvdl      617:                syscallarg(struct linux_stat *) sp;
1.11      thorpej   618:        } */ *uap = v;
                    619:
1.56      thorpej   620:        return linux_stat1(l, uap, retval, 0);
1.1       fvdl      621: }
                    622:
1.23      erh       623: /* Note: this is "newlstat" in the Linux sources */
                    624: /*     (we don't bother with the old lstat currently) */
1.1       fvdl      625: int
1.56      thorpej   626: linux_sys_lstat(l, v, retval)
                    627:        struct lwp *l;
1.11      thorpej   628:        void *v;
                    629:        register_t *retval;
                    630: {
1.12      mycroft   631:        struct linux_sys_lstat_args /* {
1.27      christos  632:                syscallarg(const char *) path;
1.1       fvdl      633:                syscallarg(struct linux_stat *) sp;
1.11      thorpej   634:        } */ *uap = v;
                    635:
1.56      thorpej   636:        return linux_stat1(l, uap, retval, 1);
1.1       fvdl      637: }
1.67      manu      638: #endif /* !__amd64__ */
1.1       fvdl      639:
                    640: /*
1.10      fvdl      641:  * The following syscalls are mostly here because of the alternate path check.
1.1       fvdl      642:  */
                    643: int
1.56      thorpej   644: linux_sys_access(l, v, retval)
                    645:        struct lwp *l;
1.11      thorpej   646:        void *v;
                    647:        register_t *retval;
                    648: {
1.12      mycroft   649:        struct linux_sys_access_args /* {
1.27      christos  650:                syscallarg(const char *) path;
1.1       fvdl      651:                syscallarg(int) flags;
1.11      thorpej   652:        } */ *uap = v;
1.56      thorpej   653:        struct proc *p = l->l_proc;
1.46      christos  654:        caddr_t sg = stackgap_init(p, 0);
1.1       fvdl      655:
1.71      christos  656:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.1       fvdl      657:
1.56      thorpej   658:        return sys_access(l, uap, retval);
1.2       fvdl      659: }
                    660:
                    661: int
1.56      thorpej   662: linux_sys_unlink(l, v, retval)
                    663:        struct lwp *l;
1.11      thorpej   664:        void *v;
1.2       fvdl      665:        register_t *retval;
                    666:
                    667: {
1.12      mycroft   668:        struct linux_sys_unlink_args /* {
1.27      christos  669:                syscallarg(const char *) path;
1.11      thorpej   670:        } */ *uap = v;
1.56      thorpej   671:        struct proc *p = l->l_proc;
1.46      christos  672:        caddr_t sg = stackgap_init(p, 0);
1.63      jdolecek  673:        int error;
                    674:        struct nameidata nd;
1.2       fvdl      675:
1.71      christos  676:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.2       fvdl      677:
1.63      jdolecek  678:        error = sys_unlink(l, uap, retval);
                    679:        if (error != EPERM)
                    680:                return (error);
                    681:
                    682:        /*
                    683:         * Linux returns EISDIR if unlink(2) is called on a directory.
                    684:         * We return EPERM in such cases. To emulate correct behaviour,
                    685:         * check if the path points to directory and return EISDIR if this
                    686:         * is the case.
                    687:         */
                    688:        NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1.71      christos  689:            SCARG(uap, path), l);
1.63      jdolecek  690:        if (namei(&nd) == 0) {
                    691:                struct stat sb;
                    692:
1.71      christos  693:                if (vn_stat(nd.ni_vp, &sb, l) == 0
1.63      jdolecek  694:                    && S_ISDIR(sb.st_mode))
                    695:                        error = EISDIR;
                    696:
                    697:                vput(nd.ni_vp);
                    698:        }
                    699:
                    700:        return (error);
1.2       fvdl      701: }
                    702:
1.10      fvdl      703: int
1.56      thorpej   704: linux_sys_chdir(l, v, retval)
                    705:        struct lwp *l;
1.11      thorpej   706:        void *v;
                    707:        register_t *retval;
                    708: {
1.12      mycroft   709:        struct linux_sys_chdir_args /* {
1.27      christos  710:                syscallarg(const char *) path;
1.11      thorpej   711:        } */ *uap = v;
1.56      thorpej   712:        struct proc *p = l->l_proc;
1.46      christos  713:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      714:
1.71      christos  715:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.2       fvdl      716:
1.56      thorpej   717:        return sys_chdir(l, uap, retval);
1.2       fvdl      718: }
                    719:
                    720: int
1.56      thorpej   721: linux_sys_mknod(l, v, retval)
                    722:        struct lwp *l;
1.11      thorpej   723:        void *v;
                    724:        register_t *retval;
                    725: {
1.12      mycroft   726:        struct linux_sys_mknod_args /* {
1.27      christos  727:                syscallarg(const char *) path;
1.2       fvdl      728:                syscallarg(int) mode;
                    729:                syscallarg(int) dev;
1.11      thorpej   730:        } */ *uap = v;
1.56      thorpej   731:        struct proc *p = l->l_proc;
1.46      christos  732:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      733:
1.71      christos  734:        CHECK_ALT_CREAT(l, &sg, SCARG(uap, path));
1.2       fvdl      735:
1.10      fvdl      736:        /*
1.40      wiz       737:         * BSD handles FIFOs separately
1.10      fvdl      738:         */
1.73.4.2  ad        739:        if (S_ISFIFO(SCARG(uap, mode))) {
1.54      jdolecek  740:                struct sys_mkfifo_args bma;
                    741:
1.21      thorpej   742:                SCARG(&bma, path) = SCARG(uap, path);
                    743:                SCARG(&bma, mode) = SCARG(uap, mode);
1.56      thorpej   744:                return sys_mkfifo(l, &bma, retval);
1.54      jdolecek  745:        } else {
                    746:                struct sys_mknod_args bma;
                    747:
                    748:                SCARG(&bma, path) = SCARG(uap, path);
                    749:                SCARG(&bma, mode) = SCARG(uap, mode);
                    750:                /*
                    751:                 * Linux device numbers uses 8 bits for minor and 8 bits
                    752:                 * for major. Due to how we map our major and minor,
                    753:                 * this just fints into our dev_t. Just mask off the
                    754:                 * upper 16bit to remove any random junk.
                    755:                 */
                    756:                SCARG(&bma, dev) = SCARG(uap, dev) & 0xffff;
1.56      thorpej   757:                return sys_mknod(l, &bma, retval);
1.54      jdolecek  758:        }
1.2       fvdl      759: }
                    760:
                    761: int
1.56      thorpej   762: linux_sys_chmod(l, v, retval)
                    763:        struct lwp *l;
1.11      thorpej   764:        void *v;
                    765:        register_t *retval;
                    766: {
1.12      mycroft   767:        struct linux_sys_chmod_args /* {
1.27      christos  768:                syscallarg(const char *) path;
1.2       fvdl      769:                syscallarg(int) mode;
1.11      thorpej   770:        } */ *uap = v;
1.56      thorpej   771:        struct proc *p = l->l_proc;
1.46      christos  772:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      773:
1.71      christos  774:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.2       fvdl      775:
1.56      thorpej   776:        return sys_chmod(l, uap, retval);
1.2       fvdl      777: }
                    778:
1.67      manu      779: #if defined(__i386__) || defined(__m68k__) || \
                    780:     defined(__arm__)
1.2       fvdl      781: int
1.56      thorpej   782: linux_sys_chown16(l, v, retval)
                    783:        struct lwp *l;
1.11      thorpej   784:        void *v;
                    785:        register_t *retval;
                    786: {
1.31      fvdl      787:        struct linux_sys_chown16_args /* {
1.27      christos  788:                syscallarg(const char *) path;
1.2       fvdl      789:                syscallarg(int) uid;
                    790:                syscallarg(int) gid;
1.11      thorpej   791:        } */ *uap = v;
1.56      thorpej   792:        struct proc *p = l->l_proc;
1.22      kleink    793:        struct sys___posix_chown_args bca;
1.46      christos  794:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      795:
1.71      christos  796:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.2       fvdl      797:
1.10      fvdl      798:        SCARG(&bca, path) = SCARG(uap, path);
                    799:        SCARG(&bca, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
                    800:                (uid_t)-1 : SCARG(uap, uid);
                    801:        SCARG(&bca, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
                    802:                (gid_t)-1 : SCARG(uap, gid);
1.65      perry     803:
1.56      thorpej   804:        return sys___posix_chown(l, &bca, retval);
1.10      fvdl      805: }
                    806:
                    807: int
1.56      thorpej   808: linux_sys_fchown16(l, v, retval)
                    809:        struct lwp *l;
1.11      thorpej   810:        void *v;
                    811:        register_t *retval;
                    812: {
1.31      fvdl      813:        struct linux_sys_fchown16_args /* {
1.10      fvdl      814:                syscallarg(int) fd;
                    815:                syscallarg(int) uid;
                    816:                syscallarg(int) gid;
1.11      thorpej   817:        } */ *uap = v;
1.22      kleink    818:        struct sys___posix_fchown_args bfa;
1.10      fvdl      819:
                    820:        SCARG(&bfa, fd) = SCARG(uap, fd);
                    821:        SCARG(&bfa, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
                    822:                (uid_t)-1 : SCARG(uap, uid);
                    823:        SCARG(&bfa, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
                    824:                (gid_t)-1 : SCARG(uap, gid);
1.65      perry     825:
1.56      thorpej   826:        return sys___posix_fchown(l, &bfa, retval);
1.2       fvdl      827: }
                    828:
                    829: int
1.56      thorpej   830: linux_sys_lchown16(l, v, retval)
                    831:        struct lwp *l;
1.23      erh       832:        void *v;
                    833:        register_t *retval;
                    834: {
1.31      fvdl      835:        struct linux_sys_lchown16_args /* {
1.23      erh       836:                syscallarg(char *) path;
                    837:                syscallarg(int) uid;
                    838:                syscallarg(int) gid;
                    839:        } */ *uap = v;
1.56      thorpej   840:        struct proc *p = l->l_proc;
1.23      erh       841:        struct sys___posix_lchown_args bla;
1.46      christos  842:        caddr_t sg = stackgap_init(p, 0);
1.33      fvdl      843:
1.71      christos  844:        CHECK_ALT_SYMLINK(l, &sg, SCARG(uap, path));
1.23      erh       845:
                    846:        SCARG(&bla, path) = SCARG(uap, path);
                    847:        SCARG(&bla, uid) = ((linux_uid_t)SCARG(uap, uid) == (linux_uid_t)-1) ?
                    848:                (uid_t)-1 : SCARG(uap, uid);
                    849:        SCARG(&bla, gid) = ((linux_gid_t)SCARG(uap, gid) == (linux_gid_t)-1) ?
                    850:                (gid_t)-1 : SCARG(uap, gid);
                    851:
1.56      thorpej   852:        return sys___posix_lchown(l, &bla, retval);
1.33      fvdl      853: }
1.67      manu      854: #endif /* __i386__ || __m68k__ || __arm__ || __amd64__ */
                    855: #if defined (__i386__) || defined (__m68k__) || defined(__amd64__) || \
                    856:     defined (__powerpc__) || defined (__mips__) || defined (__arm__)
1.33      fvdl      857: int
1.56      thorpej   858: linux_sys_chown(l, v, retval)
                    859:        struct lwp *l;
1.33      fvdl      860:        void *v;
                    861:        register_t *retval;
                    862: {
                    863:        struct linux_sys_chown_args /* {
                    864:                syscallarg(char *) path;
                    865:                syscallarg(int) uid;
                    866:                syscallarg(int) gid;
                    867:        } */ *uap = v;
1.56      thorpej   868:        struct proc *p = l->l_proc;
1.46      christos  869:        caddr_t sg = stackgap_init(p, 0);
1.33      fvdl      870:
1.71      christos  871:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.33      fvdl      872:
1.56      thorpej   873:        return sys___posix_chown(l, uap, retval);
1.33      fvdl      874: }
                    875:
                    876: int
1.56      thorpej   877: linux_sys_lchown(l, v, retval)
                    878:        struct lwp *l;
1.33      fvdl      879:        void *v;
                    880:        register_t *retval;
                    881: {
                    882:        struct linux_sys_lchown_args /* {
                    883:                syscallarg(char *) path;
                    884:                syscallarg(int) uid;
                    885:                syscallarg(int) gid;
                    886:        } */ *uap = v;
1.56      thorpej   887:        struct proc *p = l->l_proc;
1.46      christos  888:        caddr_t sg = stackgap_init(p, 0);
1.33      fvdl      889:
1.71      christos  890:        CHECK_ALT_SYMLINK(l, &sg, SCARG(uap, path));
1.33      fvdl      891:
1.56      thorpej   892:        return sys___posix_lchown(l, uap, retval);
1.23      erh       893: }
1.67      manu      894: #endif /* __i386__||__m68k__||__powerpc__||__mips__||__arm__ ||__amd64__ */
1.32      thorpej   895:
1.23      erh       896: int
1.56      thorpej   897: linux_sys_rename(l, v, retval)
                    898:        struct lwp *l;
1.11      thorpej   899:        void *v;
                    900:        register_t *retval;
                    901: {
1.12      mycroft   902:        struct linux_sys_rename_args /* {
1.27      christos  903:                syscallarg(const char *) from;
                    904:                syscallarg(const char *) to;
1.11      thorpej   905:        } */ *uap = v;
1.56      thorpej   906:        struct proc *p = l->l_proc;
1.46      christos  907:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      908:
1.71      christos  909:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, from));
                    910:        CHECK_ALT_CREAT(l, &sg, SCARG(uap, to));
1.2       fvdl      911:
1.56      thorpej   912:        return sys___posix_rename(l, uap, retval);
1.2       fvdl      913: }
                    914:
                    915: int
1.56      thorpej   916: linux_sys_mkdir(l, v, retval)
                    917:        struct lwp *l;
1.11      thorpej   918:        void *v;
                    919:        register_t *retval;
                    920: {
1.12      mycroft   921:        struct linux_sys_mkdir_args /* {
1.27      christos  922:                syscallarg(const char *) path;
1.7       fvdl      923:                syscallarg(int) mode;
1.11      thorpej   924:        } */ *uap = v;
1.56      thorpej   925:        struct proc *p = l->l_proc;
1.46      christos  926:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      927:
1.71      christos  928:        CHECK_ALT_CREAT(l, &sg, SCARG(uap, path));
1.12      mycroft   929:
1.56      thorpej   930:        return sys_mkdir(l, uap, retval);
1.2       fvdl      931: }
                    932:
                    933: int
1.56      thorpej   934: linux_sys_rmdir(l, v, retval)
                    935:        struct lwp *l;
1.11      thorpej   936:        void *v;
                    937:        register_t *retval;
                    938: {
1.12      mycroft   939:        struct linux_sys_rmdir_args /* {
1.27      christos  940:                syscallarg(const char *) path;
1.11      thorpej   941:        } */ *uap = v;
1.56      thorpej   942:        struct proc *p = l->l_proc;
1.46      christos  943:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      944:
1.71      christos  945:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.12      mycroft   946:
1.56      thorpej   947:        return sys_rmdir(l, uap, retval);
1.2       fvdl      948: }
                    949:
                    950: int
1.56      thorpej   951: linux_sys_symlink(l, v, retval)
                    952:        struct lwp *l;
1.11      thorpej   953:        void *v;
                    954:        register_t *retval;
                    955: {
1.12      mycroft   956:        struct linux_sys_symlink_args /* {
1.27      christos  957:                syscallarg(const char *) path;
                    958:                syscallarg(const char *) to;
1.11      thorpej   959:        } */ *uap = v;
1.56      thorpej   960:        struct proc *p = l->l_proc;
1.46      christos  961:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl      962:
1.71      christos  963:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
                    964:        CHECK_ALT_CREAT(l, &sg, SCARG(uap, to));
1.2       fvdl      965:
1.56      thorpej   966:        return sys_symlink(l, uap, retval);
1.34      fvdl      967: }
                    968:
                    969: int
1.56      thorpej   970: linux_sys_link(l, v, retval)
                    971:        struct lwp *l;
1.34      fvdl      972:        void *v;
                    973:        register_t *retval;
                    974: {
                    975:        struct linux_sys_link_args /* {
                    976:                syscallarg(const char *) path;
                    977:                syscallarg(const char *) link;
                    978:        } */ *uap = v;
1.56      thorpej   979:        struct proc *p = l->l_proc;
1.46      christos  980:        caddr_t sg = stackgap_init(p, 0);
1.34      fvdl      981:
1.71      christos  982:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
                    983:        CHECK_ALT_CREAT(l, &sg, SCARG(uap, link));
1.34      fvdl      984:
1.56      thorpej   985:        return sys_link(l, uap, retval);
1.2       fvdl      986: }
                    987:
                    988: int
1.56      thorpej   989: linux_sys_readlink(l, v, retval)
                    990:        struct lwp *l;
1.11      thorpej   991:        void *v;
                    992:        register_t *retval;
                    993: {
1.12      mycroft   994:        struct linux_sys_readlink_args /* {
1.27      christos  995:                syscallarg(const char *) name;
1.2       fvdl      996:                syscallarg(char *) buf;
                    997:                syscallarg(int) count;
1.11      thorpej   998:        } */ *uap = v;
1.56      thorpej   999:        struct proc *p = l->l_proc;
1.46      christos 1000:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl     1001:
1.71      christos 1002:        CHECK_ALT_SYMLINK(l, &sg, SCARG(uap, name));
1.12      mycroft  1003:
1.56      thorpej  1004:        return sys_readlink(l, uap, retval);
1.2       fvdl     1005: }
                   1006:
1.67      manu     1007: #if !defined(__amd64__)
1.2       fvdl     1008: int
1.56      thorpej  1009: linux_sys_truncate(l, v, retval)
                   1010:        struct lwp *l;
1.11      thorpej  1011:        void *v;
                   1012:        register_t *retval;
                   1013: {
1.12      mycroft  1014:        struct linux_sys_truncate_args /* {
1.27      christos 1015:                syscallarg(const char *) path;
1.2       fvdl     1016:                syscallarg(long) length;
1.11      thorpej  1017:        } */ *uap = v;
1.56      thorpej  1018:        struct proc *p = l->l_proc;
1.46      christos 1019:        caddr_t sg = stackgap_init(p, 0);
1.2       fvdl     1020:
1.71      christos 1021:        CHECK_ALT_EXIST(l, &sg, SCARG(uap, path));
1.12      mycroft  1022:
1.56      thorpej  1023:        return compat_43_sys_truncate(l, uap, retval);
1.15      fvdl     1024: }
1.67      manu     1025: #endif /* !__amd64__ */
1.15      fvdl     1026:
                   1027: /*
                   1028:  * This is just fsync() for now (just as it is in the Linux kernel)
1.23      erh      1029:  * Note: this is not implemented under Linux on Alpha and Arm
                   1030:  *     but should still be defined in our syscalls.master.
                   1031:  *     (syscall #148 on the arm)
1.15      fvdl     1032:  */
                   1033: int
1.56      thorpej  1034: linux_sys_fdatasync(l, v, retval)
                   1035:        struct lwp *l;
1.15      fvdl     1036:        void *v;
                   1037:        register_t *retval;
                   1038: {
1.16      christos 1039: #ifdef notdef
1.15      fvdl     1040:        struct linux_sys_fdatasync_args /* {
                   1041:                syscallarg(int) fd;
                   1042:        } */ *uap = v;
1.16      christos 1043: #endif
1.56      thorpej  1044:        return sys_fsync(l, v, retval);
1.28      tron     1045: }
                   1046:
                   1047: /*
                   1048:  * pread(2).
                   1049:  */
                   1050: int
1.56      thorpej  1051: linux_sys_pread(l, v, retval)
                   1052:        struct lwp *l;
1.28      tron     1053:        void *v;
                   1054:        register_t *retval;
                   1055: {
                   1056:        struct linux_sys_pread_args /* {
                   1057:                syscallarg(int) fd;
                   1058:                syscallarg(void *) buf;
                   1059:                syscallarg(size_t) nbyte;
                   1060:                syscallarg(linux_off_t) offset;
                   1061:        } */ *uap = v;
                   1062:        struct sys_pread_args pra;
                   1063:
                   1064:        SCARG(&pra, fd) = SCARG(uap, fd);
                   1065:        SCARG(&pra, buf) = SCARG(uap, buf);
                   1066:        SCARG(&pra, nbyte) = SCARG(uap, nbyte);
                   1067:        SCARG(&pra, offset) = SCARG(uap, offset);
                   1068:
1.62      jdolecek 1069:        return sys_pread(l, &pra, retval);
1.28      tron     1070: }
                   1071:
                   1072: /*
                   1073:  * pwrite(2).
                   1074:  */
                   1075: int
1.56      thorpej  1076: linux_sys_pwrite(l, v, retval)
                   1077:        struct lwp *l;
1.28      tron     1078:        void *v;
                   1079:        register_t *retval;
                   1080: {
                   1081:        struct linux_sys_pwrite_args /* {
                   1082:                syscallarg(int) fd;
                   1083:                syscallarg(void *) buf;
                   1084:                syscallarg(size_t) nbyte;
                   1085:                syscallarg(linux_off_t) offset;
                   1086:        } */ *uap = v;
                   1087:        struct sys_pwrite_args pra;
                   1088:
                   1089:        SCARG(&pra, fd) = SCARG(uap, fd);
                   1090:        SCARG(&pra, buf) = SCARG(uap, buf);
                   1091:        SCARG(&pra, nbyte) = SCARG(uap, nbyte);
                   1092:        SCARG(&pra, offset) = SCARG(uap, offset);
                   1093:
1.62      jdolecek 1094:        return sys_pwrite(l, &pra, retval);
1.1       fvdl     1095: }
1.68      fvdl     1096:
1.73.4.2  ad       1097: #define LINUX_NOT_SUPPORTED(fun) \
                   1098: int \
                   1099: fun(struct lwp *l, void *v, register_t *retval) \
                   1100: { \
                   1101:        return EOPNOTSUPP; \
                   1102: }
                   1103:
                   1104: LINUX_NOT_SUPPORTED(linux_sys_setxattr)
                   1105: LINUX_NOT_SUPPORTED(linux_sys_lsetxattr)
                   1106: LINUX_NOT_SUPPORTED(linux_sys_fsetxattr)
                   1107:
                   1108: LINUX_NOT_SUPPORTED(linux_sys_getxattr)
                   1109: LINUX_NOT_SUPPORTED(linux_sys_lgetxattr)
                   1110: LINUX_NOT_SUPPORTED(linux_sys_fgetxattr)
                   1111:
                   1112: LINUX_NOT_SUPPORTED(linux_sys_listxattr)
                   1113: LINUX_NOT_SUPPORTED(linux_sys_llistxattr)
                   1114: LINUX_NOT_SUPPORTED(linux_sys_flistxattr)
                   1115:
                   1116: LINUX_NOT_SUPPORTED(linux_sys_removexattr)
                   1117: LINUX_NOT_SUPPORTED(linux_sys_lremovexattr)
                   1118: LINUX_NOT_SUPPORTED(linux_sys_fremovexattr)

CVSweb <webmaster@jp.NetBSD.org>