Module Name:    src
Committed By:   pooka
Date:           Sat Feb 19 13:10:35 UTC 2011

Modified Files:
        src/lib/librumphijack: hijack.c

Log Message:
hijack __getcwd()


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/lib/librumphijack/hijack.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumphijack/hijack.c
diff -u src/lib/librumphijack/hijack.c:1.56 src/lib/librumphijack/hijack.c:1.57
--- src/lib/librumphijack/hijack.c:1.56	Sat Feb 19 13:09:40 2011
+++ src/lib/librumphijack/hijack.c	Sat Feb 19 13:10:35 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.56 2011/02/19 13:09:40 pooka Exp $	*/
+/*      $NetBSD: hijack.c,v 1.57 2011/02/19 13:10:35 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.56 2011/02/19 13:09:40 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.57 2011/02/19 13:10:35 pooka Exp $");
 
 #define __ssp_weak_name(fun) _hijack_ ## fun
 
@@ -87,6 +87,7 @@
 	DUALCALL_TRUNCATE, DUALCALL_FTRUNCATE,
 	DUALCALL_FSYNC, DUALCALL_FSYNC_RANGE,
 	DUALCALL_MOUNT, DUALCALL_UNMOUNT,
+	DUALCALL___GETCWD,
 	DUALCALL__NUM
 };
 
@@ -138,6 +139,7 @@
 int REALFUTIMES(int, const struct timeval [2]);
 int REALMOUNT(const char *, const char *, int, void *, size_t);
 off_t REALLSEEK(int, off_t, int);
+int __getcwd(char *, size_t);
 
 #define S(a) __STRING(a)
 struct sysnames {
@@ -200,6 +202,7 @@
 	{ DUALCALL_FSYNC_RANGE,	"fsync_range",	RSYS_NAME(FSYNC_RANGE)	},
 	{ DUALCALL_MOUNT,	S(REALMOUNT),	RSYS_NAME(MOUNT)	},
 	{ DUALCALL_UNMOUNT,	"unmount",	RSYS_NAME(UNMOUNT)	},
+	{ DUALCALL___GETCWD,	"__getcwd",	RSYS_NAME(__GETCWD)	},
 };
 #undef S
 
@@ -376,8 +379,15 @@
 pathparser(char *buf)
 {
 
+	/* sanity-check */
 	if (*buf != '/')
 		errx(1, "hijack path specifier must begin with ``/''");
+	rumpprefixlen = strlen(buf);
+	if (rumpprefixlen < 2)
+		errx(1, "invalid hijack prefix: %s", buf);
+	if (buf[rumpprefixlen-1] == '/' && strspn(buf, "/") != rumpprefixlen)
+		errx(1, "hijack prefix may end in slash only if pure "
+		    "slash, gave %s", buf);
 
 	if ((rumpprefix = strdup(buf)) == NULL)
 		err(1, "strdup");
@@ -698,6 +708,52 @@
 }
 
 int
+__getcwd(char *bufp, size_t len)
+{
+	int (*op___getcwd)(char *, size_t);
+	int rv;
+
+	if (pwdinrump) {
+		size_t prefixgap;
+		bool iamslash;
+
+		if (rumpprefix[rumpprefixlen-1] == '/')
+			iamslash = true;
+		else
+			iamslash = false;
+
+		if (iamslash)
+			prefixgap = rumpprefixlen - 1; /* ``//+path'' */
+		else
+			prefixgap = rumpprefixlen; /* ``/pfx+/path'' */
+		if (len <= prefixgap) {
+			return ERANGE;
+		}
+
+		op___getcwd = GETSYSCALL(rump, __GETCWD);
+		rv = op___getcwd(bufp + prefixgap, len - prefixgap);
+		if (rv == -1)
+			return rv;
+
+		/* augment the "/" part only for a non-root path */
+		memcpy(bufp, rumpprefix, rumpprefixlen);
+
+		/* append / only to non-root cwd */
+		if (rv != 2)
+			bufp[prefixgap] = '/';
+
+		/* don't append extra slash in the purely-slash case */
+		if (rv == 2 && !iamslash)
+			bufp[rumpprefixlen] = '\0';
+
+		return rv;
+	} else {
+		op___getcwd = GETSYSCALL(host, __GETCWD);
+		return op___getcwd(bufp, len);
+	}
+}
+
+int
 rename(const char *from, const char *to)
 {
 	int (*op_rename)(const char *, const char *);

Reply via email to