summaryrefslogtreecommitdiffstats
path: root/sys/compat/svr4/svr4_sysvec.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-02-07 21:53:42 +0000
committerjhb <jhb@FreeBSD.org>2005-02-07 21:53:42 +0000
commitb03a8bb21b2ea1fa1d440565c2ee55a7391e1c18 (patch)
treeefd3135666f0a3a86a501aeec1a200d171da8119 /sys/compat/svr4/svr4_sysvec.c
parent60bd53b164c6f3ebe8ff23d8c89209d883ddbb7a (diff)
downloadFreeBSD-src-b03a8bb21b2ea1fa1d440565c2ee55a7391e1c18.zip
FreeBSD-src-b03a8bb21b2ea1fa1d440565c2ee55a7391e1c18.tar.gz
- Implement svr4_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel pointer rather than a user space pointer. This required changing the arguments to the CHECKALT*() macros some and changing the various system calls that used pathnames to use the kern_foo() functions that can accept kernel space filename pointers instead of calling the system call directly. - Use kern_open(), kern_access(), kern_msgctl(), kern_execve(), kern_mkfifo(), kern_mknod(), kern_statfs(), kern_fstatfs(), kern_setitimer(), kern_stat(), kern_lstat(), kern_fstat(), kern_utimes(), kern_pathconf(), and kern_unlink().
Diffstat (limited to 'sys/compat/svr4/svr4_sysvec.c')
-rw-r--r--sys/compat/svr4/svr4_sysvec.c138
1 files changed, 9 insertions, 129 deletions
diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c
index 80e54b0..bcf27b2 100644
--- a/sys/compat/svr4/svr4_sysvec.c
+++ b/sys/compat/svr4/svr4_sysvec.c
@@ -44,13 +44,14 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/imgact.h>
#include <sys/imgact_elf.h>
-#include <sys/socket.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/socket.h>
+#include <sys/syscallsubr.h>
#include <sys/vnode.h>
-#include <sys/module.h>
#include <vm/vm.h>
#include <sys/exec.h>
#include <sys/kernel.h>
@@ -193,6 +194,8 @@ struct sysentvec svr4_sysvec = {
NULL
};
+const char svr4_emul_path[] = "/compat/svr4";
+
Elf32_Brandinfo svr4_brand = {
ELFOSABI_SYSV,
EM_386, /* XXX only implemented for x86 so far. */
@@ -203,8 +206,6 @@ Elf32_Brandinfo svr4_brand = {
NULL,
};
-const char svr4_emul_path[] = "/compat/svr4";
-
static int
svr4_fixup(register_t **stack_base, struct image_params *imgp)
{
@@ -249,135 +250,14 @@ svr4_fixup(register_t **stack_base, struct image_params *imgp)
* If cflag is set, we check if an attempt can be made to create
* the named file, i.e. we check if the directory it should
* be in exists.
- *
- * Code shamelessly stolen by Mark Newton from IBCS2 emulation code.
*/
int
-svr4_emul_find(td, sgp, prefix, path, pbuf, cflag)
- struct thread *td;
- caddr_t *sgp; /* Pointer to stackgap memory */
- const char *prefix;
- char *path;
- char **pbuf;
- int cflag;
+svr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
+ char **pbuf, int create)
{
- struct nameidata nd;
- struct nameidata ndroot;
- struct vattr vat;
- struct vattr vatroot;
- int error;
- char *ptr, *buf, *cp;
- size_t sz, len;
-
- buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
- *pbuf = path;
-
- for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
- continue;
-
- sz = MAXPATHLEN - (ptr - buf);
-
- /*
- * If sgp is not given then the path is already in kernel space
- */
- if (sgp == NULL)
- error = copystr(path, ptr, sz, &len);
- else
- error = copyinstr(path, ptr, sz, &len);
-
- if (error) {
- free(buf, M_TEMP);
- return error;
- }
-
- if (*ptr != '/') {
- free(buf, M_TEMP);
- return EINVAL;
- }
-
- /*
- * We know that there is a / somewhere in this pathname.
- * Search backwards for it, to find the file's parent dir
- * to see if it exists in the alternate tree. If it does,
- * and we want to create a file (cflag is set). We don't
- * need to worry about the root comparison in this case.
- */
-
- if (cflag) {
- for (cp = &ptr[len] - 1; *cp != '/'; cp--);
- *cp = '\0';
-
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
- if ((error = namei(&nd)) != 0) {
- free(buf, M_TEMP);
- return error;
- }
- NDFREE(&nd, NDF_ONLY_PNBUF);
-
- *cp = '/';
- }
- else {
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
-
- if ((error = namei(&nd)) != 0) {
- free(buf, M_TEMP);
- return error;
- }
- NDFREE(&nd, NDF_ONLY_PNBUF);
-
- /*
- * We now compare the vnode of the svr4_root to the one
- * vnode asked. If they resolve to be the same, then we
- * ignore the match so that the real root gets used.
- * This avoids the problem of traversing "../.." to find the
- * root directory and never finding it, because "/" resolves
- * to the emulation root directory. This is expensive :-(
- */
- NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, svr4_emul_path,
- td);
-
- if ((error = namei(&ndroot)) != 0) {
- /* Cannot happen! */
- free(buf, M_TEMP);
- vrele(nd.ni_vp);
- return error;
- }
- NDFREE(&ndroot, NDF_ONLY_PNBUF);
-
- if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) {
- goto done;
- }
-
- if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td->td_ucred, td))
- != 0) {
- goto done;
- }
-
- if (vat.va_fsid == vatroot.va_fsid &&
- vat.va_fileid == vatroot.va_fileid) {
- error = ENOENT;
- goto done;
- }
-
- }
- if (sgp == NULL)
- *pbuf = buf;
- else {
- sz = &ptr[len] - buf;
- if ((*pbuf = stackgap_alloc(sgp, sz + 1)) != NULL)
- error = copyout(buf, *pbuf, sz);
- else
- error = ENAMETOOLONG;
- free(buf, M_TEMP);
- }
-
-
-done:
- vrele(nd.ni_vp);
- if (!cflag)
- vrele(ndroot.ni_vp);
- return error;
+ return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
+ create));
}
static int
OpenPOWER on IntegriCloud