Index: linux_mib.c =================================================================== RCS file: /usr/local/cvs/src/sys/i386/linux/linux_mib.c,v retrieving revision 1.2 diff -u -r1.2 linux_mib.c --- linux_mib.c 1999/08/28 02:16:31 1.2 +++ linux_mib.c 1999/12/07 06:33:35 @@ -43,6 +43,7 @@ char pr_osname[LINUX_MAX_UTSNAME]; char pr_osrelease[LINUX_MAX_UTSNAME]; int pr_oss_version; + int pr_pathmunge; }; SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, @@ -111,6 +112,28 @@ 0, 0, linux_sysctl_oss_version, "I", "Linux OSS version"); +static int linux_pathmunge = 1; + +static int +linux_sysctl_pathmunge SYSCTL_HANDLER_ARGS +{ + int pathmunge; + int error; + + pathmunge = linux_get_pathmunge(req->p); + error = sysctl_handle_int(oidp, &pathmunge, 0, req); + if (error || req->newptr == NULL) + return (error); + error = linux_set_pathmunge(req->p, pathmunge); + return (error); +} + +SYSCTL_PROC(_compat_linux, OID_AUTO, pathmunge, + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON, + 0, 0, linux_sysctl_pathmunge, "I", + "Linux Path Munge"); + + static struct linux_prison * get_prison(struct proc *p) { @@ -226,6 +249,38 @@ lpr->pr_oss_version = oss_version; else linux_oss_version = oss_version; + + return (0); +} +int +linux_get_pathmunge(p) + struct proc *p; +{ + register struct prison *pr; + register struct linux_prison *lpr; + + pr = p->p_prison; + if (pr != NULL && pr->pr_linux != NULL) { + lpr = pr->pr_linux; + if (lpr->pr_pathmunge) + return (lpr->pr_pathmunge); + } + + return (linux_pathmunge); +} + +int +linux_set_pathmunge(p, pathmunge) + struct proc *p; + int pathmunge; +{ + register struct linux_prison *lpr; + + lpr = get_prison(p); + if (lpr != NULL) + lpr->pr_pathmunge = pathmunge; + else + linux_pathmunge = pathmunge; return (0); } Index: linux_mib.h =================================================================== RCS file: /usr/local/cvs/src/sys/i386/linux/linux_mib.h,v retrieving revision 1.2 diff -u -r1.2 linux_mib.h --- linux_mib.h 1999/08/28 02:16:32 1.2 +++ linux_mib.h 1999/12/07 05:22:18 @@ -1,3 +1,4 @@ + /*- * Copyright (c) 1999 Marcel Moolenaar * All rights reserved. @@ -39,5 +40,8 @@ int linux_get_oss_version __P((struct proc *p)); int linux_set_oss_version __P((struct proc *p, int oss_version)); + +int linux_get_pathmunge __P((struct proc *p)); +int linux_set_pathmunge __P((struct proc *p, int pathmunge)); #endif /* _LINUX_MIB_H_ */ Index: linux_util.c =================================================================== RCS file: /usr/local/cvs/src/sys/i386/linux/linux_util.c,v retrieving revision 1.8 diff -u -r1.8 linux_util.c --- linux_util.c 1999/08/28 00:45:25 1.8 +++ linux_util.c 1999/12/08 05:22:49 @@ -38,6 +38,7 @@ #include #include +#include const char linux_emul_path[] = "/compat/linux"; @@ -69,8 +70,22 @@ buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); *pbuf = path; - for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) - continue; + /* + * Look at the compat.linux.pathmunge sysctl to determine + * whether to add the linux_emul_path on the front of the + * requested file. Software that does tree walks, such + * as backup clients, get locked into the /compat/linux + * subtree if this is set. Setting the sysctl to 0 + * makes Linux apps access files like any other, but must + * be statically linked or they'll never find their libs. + */ + + if(linux_get_pathmunge(p)) { + for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) + continue; + } else { + ptr = buf; + } sz = MAXPATHLEN - (ptr - buf);