linux_util.c revision 18027
114331Speter/* 214331Speter * Copyright (c) 1994 Christos Zoulas 314331Speter * Copyright (c) 1995 Frank van der Linden 414331Speter * Copyright (c) 1995 Scott Bartram 514331Speter * All rights reserved. 614331Speter * 714331Speter * Redistribution and use in source and binary forms, with or without 814331Speter * modification, are permitted provided that the following conditions 914331Speter * are met: 1014331Speter * 1. Redistributions of source code must retain the above copyright 1114331Speter * notice, this list of conditions and the following disclaimer. 1214331Speter * 2. Redistributions in binary form must reproduce the above copyright 1314331Speter * notice, this list of conditions and the following disclaimer in the 1414331Speter * documentation and/or other materials provided with the distribution. 1514331Speter * 3. The name of the author may not be used to endorse or promote products 1614331Speter * derived from this software without specific prior written permission 1714331Speter * 1814331Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1914331Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2014331Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2114331Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2214331Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2314331Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2414331Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2514331Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2614331Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2714331Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2814331Speter * 2914331Speter * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp 3018027Sbde * $Id: linux_util.c,v 1.2 1996/08/05 20:52:30 nate Exp $ 3114331Speter */ 3214331Speter 3314331Speter#include <sys/param.h> 3414331Speter#include <sys/systm.h> 3514331Speter#include <sys/namei.h> 3614331Speter#include <sys/proc.h> 3714331Speter#include <sys/file.h> 3814331Speter#include <sys/stat.h> 3914331Speter#include <sys/filedesc.h> 4014331Speter#include <sys/ioctl.h> 4114331Speter#include <sys/kernel.h> 4214331Speter#include <sys/malloc.h> 4314331Speter#include <sys/vnode.h> 4414331Speter 4514331Speter#include <i386/linux/linux_util.h> 4614331Speter 4714331Speterconst char linux_emul_path[] = "/compat/linux"; 4814331Speter 4914331Speter/* 5014331Speter * Search an alternate path before passing pathname arguments on 5114331Speter * to system calls. Useful for keeping a seperate 'emulation tree'. 5214331Speter * 5314331Speter * If cflag is set, we check if an attempt can be made to create 5414331Speter * the named file, i.e. we check if the directory it should 5514331Speter * be in exists. 5614331Speter */ 5714331Speterint 5814331Speterlinux_emul_find(p, sgp, prefix, path, pbuf, cflag) 5914331Speter struct proc *p; 6014331Speter caddr_t *sgp; /* Pointer to stackgap memory */ 6114331Speter const char *prefix; 6214331Speter char *path; 6314331Speter char **pbuf; 6414331Speter int cflag; 6514331Speter{ 6614331Speter struct nameidata nd; 6714331Speter struct nameidata ndroot; 6814331Speter struct vattr vat; 6914331Speter struct vattr vatroot; 7014331Speter int error; 7114331Speter char *ptr, *buf, *cp; 7214331Speter size_t sz, len; 7314331Speter 7414331Speter buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 7514331Speter *pbuf = path; 7614331Speter 7714331Speter for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) 7814331Speter continue; 7914331Speter 8014331Speter sz = MAXPATHLEN - (ptr - buf); 8114331Speter 8214331Speter /* 8314331Speter * If sgp is not given then the path is already in kernel space 8414331Speter */ 8514331Speter if (sgp == NULL) 8614331Speter error = copystr(path, ptr, sz, &len); 8714331Speter else 8814331Speter error = copyinstr(path, ptr, sz, &len); 8914331Speter 9014331Speter if (error) { 9114331Speter free(buf, M_TEMP); 9214331Speter return error; 9314331Speter } 9414331Speter 9514331Speter if (*ptr != '/') { 9614331Speter free(buf, M_TEMP); 9714331Speter return EINVAL; 9814331Speter } 9914331Speter 10014331Speter /* 10114331Speter * We know that there is a / somewhere in this pathname. 10214331Speter * Search backwards for it, to find the file's parent dir 10314331Speter * to see if it exists in the alternate tree. If it does, 10414331Speter * and we want to create a file (cflag is set). We don't 10514331Speter * need to worry about the root comparison in this case. 10614331Speter */ 10714331Speter 10814331Speter if (cflag) { 10914331Speter for (cp = &ptr[len] - 1; *cp != '/'; cp--); 11014331Speter *cp = '\0'; 11114331Speter 11214331Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p); 11314331Speter 11414331Speter if ((error = namei(&nd)) != 0) { 11514331Speter free(buf, M_TEMP); 11614331Speter return error; 11714331Speter } 11814331Speter 11914331Speter *cp = '/'; 12014331Speter } 12114331Speter else { 12214331Speter NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p); 12314331Speter 12414331Speter if ((error = namei(&nd)) != 0) { 12514331Speter free(buf, M_TEMP); 12614331Speter return error; 12714331Speter } 12814331Speter 12914331Speter /* 13014331Speter * We now compare the vnode of the linux_root to the one 13114331Speter * vnode asked. If they resolve to be the same, then we 13214331Speter * ignore the match so that the real root gets used. 13314331Speter * This avoids the problem of traversing "../.." to find the 13414331Speter * root directory and never finding it, because "/" resolves 13514331Speter * to the emulation root directory. This is expensive :-( 13614331Speter */ 13718027Sbde NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, 13818027Sbde p); 13914331Speter 14014331Speter if ((error = namei(&ndroot)) != 0) { 14114331Speter /* Cannot happen! */ 14214331Speter free(buf, M_TEMP); 14314331Speter vrele(nd.ni_vp); 14414331Speter return error; 14514331Speter } 14614331Speter 14714331Speter if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) { 14817450Snate goto bad; 14914331Speter } 15014331Speter 15114331Speter if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p)) 15214331Speter != 0) { 15317450Snate goto bad; 15414331Speter } 15514331Speter 15614331Speter if (vat.va_fsid == vatroot.va_fsid && 15714331Speter vat.va_fileid == vatroot.va_fileid) { 15814331Speter error = ENOENT; 15917450Snate goto bad; 16014331Speter } 16114331Speter 16214331Speter } 16314331Speter if (sgp == NULL) 16414331Speter *pbuf = buf; 16514331Speter else { 16614331Speter sz = &ptr[len] - buf; 16714331Speter *pbuf = stackgap_alloc(sgp, sz + 1); 16814331Speter error = copyout(buf, *pbuf, sz); 16914331Speter free(buf, M_TEMP); 17014331Speter } 17114331Speter 17214331Speter vrele(nd.ni_vp); 17314331Speter if (!cflag) 17414331Speter vrele(ndroot.ni_vp); 17514331Speter return error; 17617450Snate 17717450Snatebad: 17817450Snate vrele(ndroot.ni_vp); 17917450Snate vrele(nd.ni_vp); 18017450Snate free(buf, M_TEMP); 18117450Snate return error; 18214331Speter} 183