2 * Copyright (c) 1994 Christos Zoulas
3 * Copyright (c) 1995 Frank van der Linden
4 * Copyright (c) 1995 Scott Bartram
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp
30 * $FreeBSD: src/sys/compat/linux/linux_util.c,v 1.12.2.2 2001/11/05 19:08:23 marcel Exp $
31 * $DragonFly: src/sys/emulation/linux/linux_util.c,v 1.14 2006/10/27 04:56:28 dillon Exp $
34 #include <sys/param.h>
35 #include <sys/systm.h>
37 #include <sys/nlookup.h>
38 #include <sys/malloc.h>
39 #include <sys/vnode.h>
41 #include "linux_util.h"
43 const char linux_emul_path
[] = "/compat/linux";
46 * Search for an alternate path before passing pathname arguments on
49 * Only signal an error if something really bad happens. In most cases
50 * we can just return the untranslated path, eg. name lookup failures.
53 linux_copyin_path(char *uname
, char **kname
, int flags
)
55 struct nlookupdata nd
, ndroot
;
56 struct vattr vat
, vatroot
;
57 struct vnode
*vp
, *vproot
;
59 int error
, length
, dummy
, byte
;
61 buf
= (char *) kmalloc(MAXPATHLEN
, M_TEMP
, M_WAITOK
);
65 * Read a byte and see if uname is a valid address. if not, EFAULT.
73 * Don't bother trying to translate if the path is relative.
79 * The path is absolute. Prepend the buffer with the emulation
82 length
= strlen(linux_emul_path
);
83 bcopy(linux_emul_path
, buf
, length
);
84 error
= copyinstr(uname
, buf
+ length
, MAXPATHLEN
- length
, &dummy
);
89 case LINUX_PATH_CREATE
:
91 * Check to see if the parent directory exists in the
92 * emulation tree. Walk the string backwards to find
95 cp
= buf
+ strlen(buf
);
104 error
= nlookup_init(&nd
, buf
, UIO_SYSSPACE
, NLC_FOLLOW
);
106 error
= nlookup(&nd
);
112 case LINUX_PATH_EXISTS
:
113 error
= nlookup_init(&nd
, buf
, UIO_SYSSPACE
, NLC_FOLLOW
);
115 error
= nlookup(&nd
);
118 error
= cache_vref(&nd
.nl_nch
, nd
.nl_cred
, &vp
);
124 * We now compare the vnode of the linux_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 :-(
131 * The next three function calls should not return errors.
132 * If they do something is seriously wrong, eg. the
133 * emulation subtree does not exist. Cross our fingers
134 * and return the untranslated path if something happens.
136 error
= nlookup_init(&ndroot
, linux_emul_path
, UIO_SYSSPACE
,
139 error
= nlookup(&ndroot
);
142 error
= cache_vref(&ndroot
.nl_nch
, ndroot
.nl_cred
,
145 nlookup_done(&ndroot
);
151 error
= VOP_GETATTR(vp
, &vat
);
153 error
= VOP_GETATTR(vproot
, &vatroot
);
155 if (vat
.va_fsid
== vatroot
.va_fsid
&&
156 vat
.va_fileid
== vatroot
.va_fileid
)
171 error
= copyinstr(uname
, buf
, MAXPATHLEN
, &dummy
);
174 linux_free_path(kname
);
179 * Smaller version of the above for translating in kernel buffers. Only
180 * used in exec_linux_imgact_try(). Only check is path exists.
183 linux_translate_path(char *path
, int size
)
185 struct nlookupdata nd
;
187 int error
, length
, dummy
;
189 buf
= (char *) kmalloc(MAXPATHLEN
, M_TEMP
, M_WAITOK
);
190 length
= strlen(linux_emul_path
);
191 bcopy(linux_emul_path
, buf
, length
);
192 error
= copystr(path
, buf
+ length
, MAXPATHLEN
- length
, &dummy
);
197 * If this errors, then the path probably doesn't exist.
199 error
= nlookup_init(&nd
, buf
, UIO_SYSSPACE
, NLC_FOLLOW
);
201 error
= nlookup(&nd
);
209 * The alternate path does exist. Return it in the buffer if
212 if (strlen(buf
) + 1 <= size
)
213 error
= copystr(buf
, path
, size
, &dummy
);