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

Annotation of sys/compat/ibcs2/ibcs2_fcntl.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: ibcs2_fcntl.c,v 1.9 2002/03/14 01:26:50 millert Exp $ */
        !             2: /*     $NetBSD: ibcs2_fcntl.c,v 1.6 1996/05/03 17:05:20 christos Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1997 Theo de Raadt
        !             6:  * Copyright (c) 1995 Scott Bartram
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. The name of the author may not be used to endorse or promote products
        !            18:  *    derived from this software without specific prior written permission
        !            19:  *
        !            20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            30:  */
        !            31:
        !            32: #include <sys/param.h>
        !            33: #include <sys/systm.h>
        !            34: #include <sys/namei.h>
        !            35: #include <sys/proc.h>
        !            36: #include <sys/file.h>
        !            37: #include <sys/stat.h>
        !            38: #include <sys/filedesc.h>
        !            39: #include <sys/ioctl.h>
        !            40: #include <sys/kernel.h>
        !            41: #include <sys/mount.h>
        !            42: #include <sys/malloc.h>
        !            43: #include <sys/syscallargs.h>
        !            44: #include <sys/vnode.h>
        !            45:
        !            46: #include <compat/ibcs2/ibcs2_types.h>
        !            47: #include <compat/ibcs2/ibcs2_fcntl.h>
        !            48: #include <compat/ibcs2/ibcs2_unistd.h>
        !            49: #include <compat/ibcs2/ibcs2_signal.h>
        !            50: #include <compat/ibcs2/ibcs2_syscallargs.h>
        !            51: #include <compat/ibcs2/ibcs2_util.h>
        !            52:
        !            53: static int cvt_o_flags(int);
        !            54: static void cvt_flock2iflock(struct flock *, struct ibcs2_flock *);
        !            55: static void cvt_iflock2flock(struct ibcs2_flock *, struct flock *);
        !            56: static int ioflags2oflags(int);
        !            57: static int oflags2ioflags(int);
        !            58:
        !            59: static int
        !            60: cvt_o_flags(flags)
        !            61:        int flags;
        !            62: {
        !            63:        int r = 0;
        !            64:
        !            65:         /* convert mode into NetBSD mode */
        !            66:        if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
        !            67:        if (flags & IBCS2_O_RDWR) r |= O_RDWR;
        !            68:        if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK;
        !            69:        if (flags & IBCS2_O_APPEND) r |= O_APPEND;
        !            70:        if (flags & IBCS2_O_SYNC) r |= O_SYNC;
        !            71:        if (flags & IBCS2_O_CREAT) r |= O_CREAT;
        !            72:        if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
        !            73:        if (flags & IBCS2_O_EXCL) r |= O_EXCL;
        !            74:        return r;
        !            75: }
        !            76:
        !            77: static void
        !            78: cvt_flock2iflock(flp, iflp)
        !            79:        struct flock *flp;
        !            80:        struct ibcs2_flock *iflp;
        !            81: {
        !            82:        switch (flp->l_type) {
        !            83:        case F_RDLCK:
        !            84:                iflp->l_type = IBCS2_F_RDLCK;
        !            85:                break;
        !            86:        case F_WRLCK:
        !            87:                iflp->l_type = IBCS2_F_WRLCK;
        !            88:                break;
        !            89:        case F_UNLCK:
        !            90:                iflp->l_type = IBCS2_F_UNLCK;
        !            91:                break;
        !            92:        }
        !            93:        iflp->l_whence = (short)flp->l_whence;
        !            94:        iflp->l_start = (ibcs2_off_t)flp->l_start;
        !            95:        iflp->l_len = (ibcs2_off_t)flp->l_len;
        !            96:        iflp->l_sysid = 0;
        !            97:        iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
        !            98: }
        !            99:
        !           100: static void
        !           101: cvt_iflock2flock(iflp, flp)
        !           102:        struct ibcs2_flock *iflp;
        !           103:        struct flock *flp;
        !           104: {
        !           105:        flp->l_start = (off_t)iflp->l_start;
        !           106:        flp->l_len = (off_t)iflp->l_len;
        !           107:        flp->l_pid = (pid_t)iflp->l_pid;
        !           108:        switch (iflp->l_type) {
        !           109:        case IBCS2_F_RDLCK:
        !           110:                flp->l_type = F_RDLCK;
        !           111:                break;
        !           112:        case IBCS2_F_WRLCK:
        !           113:                flp->l_type = F_WRLCK;
        !           114:                break;
        !           115:        case IBCS2_F_UNLCK:
        !           116:                flp->l_type = F_UNLCK;
        !           117:                break;
        !           118:        }
        !           119:        flp->l_whence = iflp->l_whence;
        !           120: }
        !           121:
        !           122: /* convert iBCS2 mode into NetBSD mode */
        !           123: static int
        !           124: ioflags2oflags(flags)
        !           125:        int flags;
        !           126: {
        !           127:        int r = 0;
        !           128:
        !           129:        if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
        !           130:        if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
        !           131:        if (flags & IBCS2_O_RDWR) r |= O_RDWR;
        !           132:        if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK;
        !           133:        if (flags & IBCS2_O_APPEND) r |= O_APPEND;
        !           134:        if (flags & IBCS2_O_SYNC) r |= O_SYNC;
        !           135:        if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK;
        !           136:        if (flags & IBCS2_O_CREAT) r |= O_CREAT;
        !           137:        if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
        !           138:        if (flags & IBCS2_O_EXCL) r |= O_EXCL;
        !           139:        if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
        !           140:        return r;
        !           141: }
        !           142:
        !           143: /* convert NetBSD mode into iBCS2 mode */
        !           144: static int
        !           145: oflags2ioflags(flags)
        !           146:        int flags;
        !           147: {
        !           148:        int r = 0;
        !           149:
        !           150:        if (flags & O_RDONLY) r |= IBCS2_O_RDONLY;
        !           151:        if (flags & O_WRONLY) r |= IBCS2_O_WRONLY;
        !           152:        if (flags & O_RDWR) r |= IBCS2_O_RDWR;
        !           153:        if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK;
        !           154:        if (flags & O_APPEND) r |= IBCS2_O_APPEND;
        !           155:        if (flags & O_SYNC) r |= IBCS2_O_SYNC;
        !           156:        if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK;
        !           157:        if (flags & O_CREAT) r |= IBCS2_O_CREAT;
        !           158:        if (flags & O_TRUNC) r |= IBCS2_O_TRUNC;
        !           159:        if (flags & O_EXCL) r |= IBCS2_O_EXCL;
        !           160:        if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY;
        !           161:        return r;
        !           162: }
        !           163:
        !           164: int
        !           165: ibcs2_sys_open(p, v, retval)
        !           166:        struct proc *p;
        !           167:        void *v;
        !           168:        register_t *retval;
        !           169: {
        !           170:        struct ibcs2_sys_open_args /* {
        !           171:                syscallarg(char *) path;
        !           172:                syscallarg(int) flags;
        !           173:                syscallarg(int) mode;
        !           174:        } */ *uap = v;
        !           175:        int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
        !           176:        int ret;
        !           177:        caddr_t sg = stackgap_init(p->p_emul);
        !           178:
        !           179:        SCARG(uap, flags) = cvt_o_flags(SCARG(uap, flags));
        !           180:        if (SCARG(uap, flags) & O_CREAT)
        !           181:                IBCS2_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           182:        else
        !           183:                IBCS2_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           184:        ret = sys_open(p, uap, retval);
        !           185:
        !           186:        if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
        !           187:                struct filedesc *fdp = p->p_fd;
        !           188:                struct file *fp;
        !           189:
        !           190:                if ((fp = fd_getfile(fdp, *retval)) == NULL)
        !           191:                        return EBADF;
        !           192:                FREF(fp);
        !           193:                if (fp->f_type == DTYPE_VNODE)
        !           194:                        (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
        !           195:                FRELE(fp);
        !           196:        }
        !           197:        return ret;
        !           198: }
        !           199:
        !           200: int
        !           201: ibcs2_sys_creat(p, v, retval)
        !           202:         struct proc *p;
        !           203:        void *v;
        !           204:        register_t *retval;
        !           205: {
        !           206:        struct ibcs2_sys_creat_args /* {
        !           207:                syscallarg(char *) path;
        !           208:                syscallarg(int) mode;
        !           209:        } */ *uap = v;
        !           210:        struct sys_open_args cup;
        !           211:        caddr_t sg = stackgap_init(p->p_emul);
        !           212:
        !           213:        IBCS2_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           214:        SCARG(&cup, path) = SCARG(uap, path);
        !           215:        SCARG(&cup, mode) = SCARG(uap, mode);
        !           216:        SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
        !           217:        return sys_open(p, &cup, retval);
        !           218: }
        !           219:
        !           220: int
        !           221: ibcs2_sys_access(p, v, retval)
        !           222:         struct proc *p;
        !           223:        void *v;
        !           224:         register_t *retval;
        !           225: {
        !           226:        struct ibcs2_sys_access_args /* {
        !           227:                syscallarg(char *) path;
        !           228:                syscallarg(int) flags;
        !           229:        } */ *uap = v;
        !           230:         struct sys_access_args cup;
        !           231:         caddr_t sg = stackgap_init(p->p_emul);
        !           232:
        !           233:         IBCS2_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           234:         SCARG(&cup, path) = SCARG(uap, path);
        !           235:         SCARG(&cup, flags) = SCARG(uap, flags);
        !           236:         return sys_access(p, &cup, retval);
        !           237: }
        !           238:
        !           239: int
        !           240: ibcs2_sys_eaccess(p, v, retval)
        !           241:         struct proc *p;
        !           242:        void *v;
        !           243:         register_t *retval;
        !           244: {
        !           245:        register struct ibcs2_sys_eaccess_args /* {
        !           246:                syscallarg(char *) path;
        !           247:                syscallarg(int) flags;
        !           248:        } */ *uap = v;
        !           249:        register struct ucred *cred = p->p_ucred;
        !           250:        register struct vnode *vp;
        !           251:         int error, flags;
        !           252:         struct nameidata nd;
        !           253:         caddr_t sg = stackgap_init(p->p_emul);
        !           254:
        !           255:         IBCS2_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           256:
        !           257:         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
        !           258:             SCARG(uap, path), p);
        !           259:         if ((error = namei(&nd)) != 0)
        !           260:                 return error;
        !           261:         vp = nd.ni_vp;
        !           262:
        !           263:         /* Flags == 0 means only check for existence. */
        !           264:         if (SCARG(uap, flags)) {
        !           265:                 flags = 0;
        !           266:                 if (SCARG(uap, flags) & IBCS2_R_OK)
        !           267:                         flags |= VREAD;
        !           268:                 if (SCARG(uap, flags) & IBCS2_W_OK)
        !           269:                         flags |= VWRITE;
        !           270:                 if (SCARG(uap, flags) & IBCS2_X_OK)
        !           271:                         flags |= VEXEC;
        !           272:                 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
        !           273:                         error = VOP_ACCESS(vp, flags, cred, p);
        !           274:         }
        !           275:         vput(vp);
        !           276:         return error;
        !           277: }
        !           278:
        !           279: int
        !           280: ibcs2_sys_fcntl(p, v, retval)
        !           281:        struct proc *p;
        !           282:        void *v;
        !           283:        register_t *retval;
        !           284: {
        !           285:        struct ibcs2_sys_fcntl_args /* {
        !           286:                syscallarg(int) fd;
        !           287:                syscallarg(int) cmd;
        !           288:                syscallarg(char *) arg;
        !           289:        } */ *uap = v;
        !           290:        int error;
        !           291:        struct sys_fcntl_args fa;
        !           292:        struct flock *flp;
        !           293:        struct ibcs2_flock ifl;
        !           294:
        !           295:        switch(SCARG(uap, cmd)) {
        !           296:        case IBCS2_F_DUPFD:
        !           297:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           298:                SCARG(&fa, cmd) = F_DUPFD;
        !           299:                SCARG(&fa, arg) = SCARG(uap, arg);
        !           300:                return sys_fcntl(p, &fa, retval);
        !           301:        case IBCS2_F_GETFD:
        !           302:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           303:                SCARG(&fa, cmd) = F_GETFD;
        !           304:                SCARG(&fa, arg) = SCARG(uap, arg);
        !           305:                return sys_fcntl(p, &fa, retval);
        !           306:        case IBCS2_F_SETFD:
        !           307:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           308:                SCARG(&fa, cmd) = F_SETFD;
        !           309:                SCARG(&fa, arg) = SCARG(uap, arg);
        !           310:                return sys_fcntl(p, &fa, retval);
        !           311:        case IBCS2_F_GETFL:
        !           312:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           313:                SCARG(&fa, cmd) = F_GETFL;
        !           314:                SCARG(&fa, arg) = SCARG(uap, arg);
        !           315:                error = sys_fcntl(p, &fa, retval);
        !           316:                if (error)
        !           317:                        return error;
        !           318:                *retval = oflags2ioflags(*retval);
        !           319:                return error;
        !           320:        case IBCS2_F_SETFL:
        !           321:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           322:                SCARG(&fa, cmd) = F_SETFL;
        !           323:                SCARG(&fa, arg) = (void *)ioflags2oflags((int) SCARG(uap, arg));
        !           324:                return sys_fcntl(p, &fa, retval);
        !           325:
        !           326:        case IBCS2_F_GETLK:
        !           327:            {
        !           328:                caddr_t sg = stackgap_init(p->p_emul);
        !           329:                flp = stackgap_alloc(&sg, sizeof(*flp));
        !           330:                error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
        !           331:                               ibcs2_flock_len);
        !           332:                if (error)
        !           333:                        return error;
        !           334:                cvt_iflock2flock(&ifl, flp);
        !           335:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           336:                SCARG(&fa, cmd) = F_GETLK;
        !           337:                SCARG(&fa, arg) = (void *)flp;
        !           338:                error = sys_fcntl(p, &fa, retval);
        !           339:                if (error)
        !           340:                        return error;
        !           341:                cvt_flock2iflock(flp, &ifl);
        !           342:                return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg),
        !           343:                               ibcs2_flock_len);
        !           344:            }
        !           345:
        !           346:        case IBCS2_F_SETLK:
        !           347:            {
        !           348:                caddr_t sg = stackgap_init(p->p_emul);
        !           349:                flp = stackgap_alloc(&sg, sizeof(*flp));
        !           350:                error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
        !           351:                               ibcs2_flock_len);
        !           352:                if (error)
        !           353:                        return error;
        !           354:                cvt_iflock2flock(&ifl, flp);
        !           355:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           356:                SCARG(&fa, cmd) = F_SETLK;
        !           357:                SCARG(&fa, arg) = (void *)flp;
        !           358:                return sys_fcntl(p, &fa, retval);
        !           359:            }
        !           360:
        !           361:        case IBCS2_F_SETLKW:
        !           362:            {
        !           363:                caddr_t sg = stackgap_init(p->p_emul);
        !           364:                flp = stackgap_alloc(&sg, sizeof(*flp));
        !           365:                error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
        !           366:                               ibcs2_flock_len);
        !           367:                if (error)
        !           368:                        return error;
        !           369:                cvt_iflock2flock(&ifl, flp);
        !           370:                SCARG(&fa, fd) = SCARG(uap, fd);
        !           371:                SCARG(&fa, cmd) = F_SETLKW;
        !           372:                SCARG(&fa, arg) = (void *)flp;
        !           373:                return sys_fcntl(p, &fa, retval);
        !           374:            }
        !           375:        case IBCS2_F_FREESP:
        !           376:            {
        !           377:                struct ibcs2_flock      ifl;
        !           378:                off_t                   off, cur;
        !           379:                caddr_t                 sg = stackgap_init(p->p_emul);
        !           380:                struct sys_fstat_args   ofst;
        !           381:                struct stat             ost;
        !           382:                struct sys_lseek_args   ols;
        !           383:                struct sys_ftruncate_args /* {
        !           384:                        syscallarg(int) fd;
        !           385:                        syscallarg(int) pad;
        !           386:                        syscallarg(off_t) length;
        !           387:                } */ nuap;
        !           388:
        !           389:                error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
        !           390:                if (error)
        !           391:                        return error;
        !           392:
        !           393:                SCARG(&ofst, fd) = SCARG(uap, fd);
        !           394:                SCARG(&ofst, sb) = stackgap_alloc(&sg,
        !           395:                    sizeof(struct stat));
        !           396:                if ((error = sys_fstat(p, &ofst, retval)) != 0)
        !           397:                        return error;
        !           398:                if ((error = copyin(SCARG(&ofst, sb), &ost,
        !           399:                    sizeof ost)) != 0)
        !           400:                        return error;
        !           401:
        !           402:                SCARG(&ols, fd) = SCARG(uap, fd);
        !           403:                SCARG(&ols, whence) = SEEK_CUR;
        !           404:                SCARG(&ols, offset) = 0;
        !           405:                if ((error = sys_lseek(p, &ols, (register_t *)&cur)) != 0)
        !           406:                        return error;
        !           407:
        !           408:                off = (off_t)ifl.l_start;
        !           409:                switch (ifl.l_whence) {
        !           410:                case 0:
        !           411:                        off = (off_t)ifl.l_start;
        !           412:                        break;
        !           413:                case 1:
        !           414:                        off = ost.st_size + (off_t)ifl.l_start;
        !           415:                        break;
        !           416:                case 2:
        !           417:                        off = cur - (off_t)ifl.l_start;
        !           418:                        break;
        !           419:                default:
        !           420:                        return EINVAL;
        !           421:                }
        !           422:
        !           423:                if (ifl.l_len != 0 && off + ifl.l_len != ost.st_size)
        !           424:                        return EINVAL;  /* Sorry, cannot truncate in middle */
        !           425:
        !           426:                SCARG(&nuap, fd) = SCARG(uap, fd);
        !           427:                SCARG(&nuap, length) = off;
        !           428:                return (sys_ftruncate(p, &nuap, retval));
        !           429:            }
        !           430:        }
        !           431:        return ENOSYS;
        !           432: }

CVSweb