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

Annotation of sys/compat/common/compat_util.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: compat_util.c,v 1.10 2004/08/01 06:22:28 mickey Exp $ */
        !             2: /*     $NetBSD: compat_util.c,v 1.4 1996/03/14 19:31:45 christos Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1994 Christos Zoulas
        !             6:  * Copyright (c) 1995 Frank van der Linden
        !             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:
        !            33: #include <sys/param.h>
        !            34: #include <sys/systm.h>
        !            35: #include <sys/namei.h>
        !            36: #include <sys/proc.h>
        !            37: #include <sys/file.h>
        !            38: #include <sys/stat.h>
        !            39: #include <sys/filedesc.h>
        !            40: #include <sys/ioctl.h>
        !            41: #include <sys/kernel.h>
        !            42: #include <sys/malloc.h>
        !            43: #include <sys/vnode.h>
        !            44:
        !            45: #include <compat/common/compat_util.h>
        !            46:
        !            47: /*
        !            48:  * Search an alternate path before passing pathname arguments on
        !            49:  * to system calls. Useful for keeping a separate 'emulation tree'.
        !            50:  *
        !            51:  * If cflag is set, we check if an attempt can be made to create
        !            52:  * the named file, i.e. we check if the directory it should
        !            53:  * be in exists.
        !            54:  */
        !            55: int
        !            56: emul_find(p, sgp, prefix, path, pbuf, cflag)
        !            57:        struct proc      *p;
        !            58:        caddr_t          *sgp;          /* Pointer to stackgap memory */
        !            59:        const char       *prefix;
        !            60:        char             *path;
        !            61:        char            **pbuf;
        !            62:        int               cflag;
        !            63: {
        !            64:        struct nameidata         nd;
        !            65:        struct nameidata         ndroot;
        !            66:        struct vattr             vat;
        !            67:        struct vattr             vatroot;
        !            68:        int                      error;
        !            69:        char                    *ptr, *buf, *cp;
        !            70:        const char              *pr;
        !            71:        size_t                   sz, len;
        !            72:
        !            73:        buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
        !            74:        *pbuf = path;
        !            75:
        !            76:        for (ptr = buf, pr = prefix; (*ptr = *pr) != '\0'; ptr++, pr++)
        !            77:                continue;
        !            78:
        !            79:        sz = MAXPATHLEN - (ptr - buf);
        !            80:
        !            81:        /*
        !            82:         * If sgp is not given then the path is already in kernel space
        !            83:         */
        !            84:        if (sgp == NULL)
        !            85:                error = copystr(path, ptr, sz, &len);
        !            86:        else
        !            87:                error = copyinstr(path, ptr, sz, &len);
        !            88:
        !            89:        if (error)
        !            90:                goto bad;
        !            91:
        !            92:        if (*ptr != '/') {
        !            93:                error = EINVAL;
        !            94:                goto bad;
        !            95:        }
        !            96:
        !            97:        /*
        !            98:         * We know that there is a / somewhere in this pathname.
        !            99:         * Search backwards for it, to find the file's parent dir
        !           100:         * to see if it exists in the alternate tree. If it does,
        !           101:         * and we want to create a file (cflag is set). We don't
        !           102:         * need to worry about the root comparison in this case.
        !           103:         */
        !           104:
        !           105:        if (cflag) {
        !           106:                for (cp = &ptr[len] - 1; *cp != '/'; cp--)
        !           107:                        ;
        !           108:                *cp = '\0';
        !           109:
        !           110:                NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
        !           111:
        !           112:                if ((error = namei(&nd)) != 0)
        !           113:                        goto bad;
        !           114:
        !           115:                *cp = '/';
        !           116:        }
        !           117:        else {
        !           118:                NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
        !           119:
        !           120:                if ((error = namei(&nd)) != 0)
        !           121:                        goto bad;
        !           122:
        !           123:                /*
        !           124:                 * We now compare the vnode of the emulation root to the one
        !           125:                 * vnode asked. If they resolve to be the same, then we
        !           126:                 * ignore the match so that the real root gets used.
        !           127:                 * This avoids the problem of traversing "../.." to find the
        !           128:                 * root directory and never finding it, because "/" resolves
        !           129:                 * to the emulation root directory. This is expensive :-(
        !           130:                 */
        !           131:                /* XXX: prototype should have const here for NDINIT */
        !           132:                NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, prefix, p);
        !           133:
        !           134:                if ((error = namei(&ndroot)) != 0)
        !           135:                        goto bad2;
        !           136:
        !           137:                if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0)
        !           138:                        goto bad3;
        !           139:
        !           140:                if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
        !           141:                    != 0)
        !           142:                        goto bad3;
        !           143:
        !           144:                if (vat.va_fsid == vatroot.va_fsid &&
        !           145:                    vat.va_fileid == vatroot.va_fileid) {
        !           146:                        error = ENOENT;
        !           147:                        goto bad3;
        !           148:                }
        !           149:        }
        !           150:        if (sgp == NULL)
        !           151:                *pbuf = buf;
        !           152:        else {
        !           153:                sz = &ptr[len] - buf;
        !           154:                *pbuf = stackgap_alloc(sgp, sz + 1);
        !           155:                if (*pbuf == NULL) {
        !           156:                        error = ENAMETOOLONG;
        !           157:                        goto bad;
        !           158:                }
        !           159:                if ((error = copyout(buf, *pbuf, sz)) != 0) {
        !           160:                        *pbuf = path;
        !           161:                        goto bad;
        !           162:                }
        !           163:                free(buf, M_TEMP);
        !           164:        }
        !           165:
        !           166:        vrele(nd.ni_vp);
        !           167:        if (!cflag)
        !           168:                vrele(ndroot.ni_vp);
        !           169:        return error;
        !           170:
        !           171: bad3:
        !           172:        vrele(ndroot.ni_vp);
        !           173: bad2:
        !           174:        vrele(nd.ni_vp);
        !           175: bad:
        !           176:        free(buf, M_TEMP);
        !           177:        return error;
        !           178: }
        !           179:
        !           180: /*
        !           181:  * Translate one set of flags to another, based on the entries in
        !           182:  * the given table.  If 'leftover' is specified, it is filled in
        !           183:  * with any flags which could not be translated.
        !           184:  */
        !           185: unsigned long
        !           186: emul_flags_translate(tab, in, leftover)
        !           187:        const struct emul_flags_xtab *tab;
        !           188:        unsigned long in;
        !           189:        unsigned long *leftover;
        !           190: {
        !           191:         unsigned long out;
        !           192:
        !           193:         for (out = 0; tab->omask != 0; tab++) {
        !           194:                 if ((in & tab->omask) == tab->oval) {
        !           195:                         in &= ~tab->omask;
        !           196:                         out |= tab->nval;
        !           197:                 }
        !           198:         }
        !           199:         if (leftover != NULL)
        !           200:                 *leftover = in;
        !           201:         return (out);
        !           202: }
        !           203:
        !           204: caddr_t
        !           205: stackgap_init(e)
        !           206:         struct emul *e;
        !           207: {
        !           208:         return STACKGAPBASE;
        !           209: }
        !           210:
        !           211: void *
        !           212: stackgap_alloc(sgp, sz)
        !           213:         caddr_t *sgp;
        !           214:         size_t sz;
        !           215: {
        !           216:        void *n = (void *) *sgp;
        !           217:        caddr_t nsgp;
        !           218:
        !           219:        sz = ALIGN(sz);
        !           220:        nsgp = *sgp + sz;
        !           221: #ifdef MACHINE_STACK_GROWS_UP
        !           222:        if (nsgp > ((caddr_t)PS_STRINGS) + STACKGAPLEN)
        !           223:                return NULL;
        !           224: #else
        !           225:        if (nsgp > ((caddr_t)PS_STRINGS))
        !           226:                return NULL;
        !           227: #endif
        !           228:        *sgp = nsgp;
        !           229:        return n;
        !           230: }

CVSweb