[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

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