Index: sys/compat/common/compat_util.c
===================================================================
RCS file: /space/netbsd/NetBSD-cvs/src/sys/compat/common/compat_util.c,v
retrieving revision 1.29
diff -u -r1.29 compat_util.c
--- sys/compat/common/compat_util.c	29 May 2005 22:08:16 -0000	1.29
+++ sys/compat/common/compat_util.c	1 Sep 2005 22:45:09 -0000
@@ -55,6 +55,8 @@
 #include <sys/mount.h>
 
 
+#include <sys/syscallargs.h>
+
 #include <compat/common/compat_util.h>
 
 /*
@@ -318,3 +320,78 @@
 	    msg, mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname);
 	uprintf("%s: dir offset too large for emulated program\n", msg);
 }
+
+/**
+ * Get the current working directory for a process running with
+ * emulation path translation turned on.
+ * Remove the emulation directory from the beginning of
+ * any cwd's that are within it to give the loose impression
+ * of being in a chroot.
+ *
+ * e.g. /emul/linux/home/erh becomes just /home/erh
+ */
+int
+emul_sys___getcwd(struct lwp *l, void *v, register_t *retval)
+{
+	struct sys___getcwd_args /* {
+		syscallarg(char *) bufp;
+		syscallarg(size_t) length;
+	} */ *uap = v;
+
+	struct proc *p = l->l_proc;
+	struct nameidata nd;
+	char *bufp;
+	int emul_path_len, bufp_len;
+	int length = SCARG(uap, length);
+	int error = sys___getcwd(l, v, retval);
+
+	if (error)
+		return error;
+
+	bufp = malloc(length, M_TEMP, M_WAITOK);
+
+	error = copyin(SCARG(uap, bufp), bufp, length);
+	if (error)
+	{
+		free(bufp, M_TEMP);
+		return error;
+	}
+
+	// Look up the emulation path, in case it's a symlink to elsewhere.
+	NDINIT(&nd, LOOKUP, FOLLOW|SAVENAME, UIO_SYSSPACE,
+	       p->p_emul->e_path, p);
+	if ((error = namei(&nd)) != 0)
+	{
+		free(bufp, M_TEMP);
+		return error;
+	}
+	vrele(nd.ni_vp);
+
+	// Can't use strlen: cn_pnbuf might not be null terminated!
+	emul_path_len = nd.ni_cnd.cn_namelen +
+	                 (nd.ni_cnd.cn_nameptr - nd.ni_cnd.cn_pnbuf);
+	bufp_len = strlen(bufp);
+
+	// Remove the emulation path from the cwd, if it's there.
+	if (strncmp(bufp, nd.ni_cnd.cn_pnbuf, emul_path_len) == 0)
+	{
+		if (bufp_len == emul_path_len ||
+		    (bufp[emul_path_len] == '/' &&
+		     bufp_len == emul_path_len + 1))
+		{
+			error = copyout("/", SCARG(uap, bufp), 2);
+			*retval = 2;
+		}
+		else if (bufp[emul_path_len] == '/')
+		{
+			int newlen = bufp_len - emul_path_len;
+			memmove(bufp, bufp + emul_path_len, newlen + 1);
+			error = copyout(bufp, SCARG(uap, bufp), newlen + 1);
+			*retval = newlen + 1;
+		}
+	}
+
+	PNBUF_PUT(nd.ni_cnd.cn_pnbuf);
+	free(bufp, M_TEMP);
+	return error;
+}
Index: sys/compat/common/compat_util.h
===================================================================
RCS file: /space/netbsd/NetBSD-cvs/src/sys/compat/common/compat_util.h,v
retrieving revision 1.15
diff -u -r1.15 compat_util.h
--- sys/compat/common/compat_util.h	29 May 2005 22:08:16 -0000	1.15
+++ sys/compat/common/compat_util.h	1 Sep 2005 16:51:52 -0000
@@ -89,6 +89,8 @@
 
 void compat_offseterr(struct vnode *, const char *);
 
+int emul_sys___getcwd(struct lwp *l, void *v, register_t *retval);
+
 #define	CHECK_ALT_FL_EXISTS	0
 #define	CHECK_ALT_FL_CREAT	1
 #define	CHECK_ALT_FL_SYMLINK	2
Index: sys/compat/linux/arch/i386/linux_syscall.h
===================================================================
RCS file: /space/netbsd/NetBSD-cvs/src/sys/compat/linux/arch/i386/linux_syscall.h,v
retrieving revision 1.57
diff -u -r1.57 linux_syscall.h
--- sys/compat/linux/arch/i386/linux_syscall.h	16 May 2005 21:18:19 -0000	1.57
+++ sys/compat/linux/arch/i386/linux_syscall.h	1 Sep 2005 17:54:19 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_syscall.h,v 1.57 2005/05/16 21:18:19 fvdl Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call numbers.
Index: sys/compat/linux/arch/i386/linux_syscallargs.h
===================================================================
RCS file: /space/netbsd/NetBSD-cvs/src/sys/compat/linux/arch/i386/linux_syscallargs.h,v
retrieving revision 1.57
diff -u -r1.57 linux_syscallargs.h
--- sys/compat/linux/arch/i386/linux_syscallargs.h	16 May 2005 21:18:19 -0000	1.57
+++ sys/compat/linux/arch/i386/linux_syscallargs.h	1 Sep 2005 17:54:19 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_syscallargs.h,v 1.57 2005/05/16 21:18:19 fvdl Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call argument lists.
@@ -528,6 +528,11 @@
 	syscallarg(int) gid;
 };
 
+struct emul_sys___getcwd_args {
+	syscallarg(char *) bufp;
+	syscallarg(size_t) length;
+};
+
 struct linux_sys_sigaltstack_args {
 	syscallarg(const struct linux_sigaltstack *) ss;
 	syscallarg(struct linux_sigaltstack *) oss;
@@ -1037,7 +1042,7 @@
 
 int	linux_sys_chown16(struct lwp *, void *, register_t *);
 
-int	sys___getcwd(struct lwp *, void *, register_t *);
+int	emul_sys___getcwd(struct lwp *, void *, register_t *);
 
 int	linux_sys_sigaltstack(struct lwp *, void *, register_t *);
 
Index: sys/compat/linux/arch/i386/linux_sysent.c
===================================================================
RCS file: /space/netbsd/NetBSD-cvs/src/sys/compat/linux/arch/i386/linux_sysent.c,v
retrieving revision 1.57
diff -u -r1.57 linux_sysent.c
--- sys/compat/linux/arch/i386/linux_sysent.c	16 May 2005 21:18:19 -0000	1.57
+++ sys/compat/linux/arch/i386/linux_sysent.c	1 Sep 2005 17:54:19 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_sysent.c,v 1.57 2005/05/16 21:18:19 fvdl Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call switch table.
@@ -8,7 +8,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_sysent.c,v 1.57 2005/05/16 21:18:19 fvdl Exp $");
+__KERNEL_RCSID(0, "$NetBSD$");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_43.h"
@@ -396,8 +396,8 @@
 	    linux_sys_pwrite },			/* 181 = pwrite */
 	{ 3, s(struct linux_sys_chown16_args), 0,
 	    linux_sys_chown16 },		/* 182 = chown16 */
-	{ 2, s(struct sys___getcwd_args), 0,
-	    sys___getcwd },			/* 183 = __getcwd */
+	{ 2, s(struct emul_sys___getcwd_args), 0,
+	    emul_sys___getcwd },		/* 183 = __getcwd */
 	{ 0, 0, 0,
 	    linux_sys_nosys },			/* 184 = unimplemented capget */
 	{ 0, 0, 0,
Index: sys/compat/linux/arch/i386/syscalls.master
===================================================================
RCS file: /space/netbsd/NetBSD-cvs/src/sys/compat/linux/arch/i386/syscalls.master,v
retrieving revision 1.73
diff -u -r1.73 syscalls.master
--- sys/compat/linux/arch/i386/syscalls.master	16 May 2005 21:17:11 -0000	1.73
+++ sys/compat/linux/arch/i386/syscalls.master	1 Sep 2005 17:54:12 -0000
@@ -313,7 +313,7 @@
 			    size_t nbyte, linux_off_t offset); }
 182	STD		{ int linux_sys_chown16(const char *path, int uid, \
 			    int gid); }
-183	NOARGS		{ int sys___getcwd(char *bufp, size_t length); }
+183	STD		{ int emul_sys___getcwd(char *bufp, size_t length); }
 184	UNIMPL		capget
 185	UNIMPL		capset
 186	STD		{ int linux_sys_sigaltstack( \
