Module Name:    src
Committed By:   pooka
Date:           Tue Feb  8 14:45:35 UTC 2011

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

Log Message:
Make sure we can do host kevent since the -current (and recent nb5)
libc resolver uses it.  Error out in case of rump fd kevent (TODO).
Fixes one more problem pointed out by Alexander Nasonov.

Also, implement dup().
(TODO: implement it along the fcntl path too)


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 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.33 src/lib/librumphijack/hijack.c:1.34
--- src/lib/librumphijack/hijack.c:1.33	Tue Feb  8 12:20:11 2011
+++ src/lib/librumphijack/hijack.c	Tue Feb  8 14:45:35 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.33 2011/02/08 12:20:11 pooka Exp $	*/
+/*      $NetBSD: hijack.c,v 1.34 2011/02/08 14:45: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.33 2011/02/08 12:20:11 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.34 2011/02/08 14:45:35 pooka Exp $");
 
 #define __ssp_weak_name(fun) _hijack_ ## fun
 
@@ -66,8 +66,10 @@
 	DUALCALL_GETSOCKOPT, DUALCALL_SETSOCKOPT,
 	DUALCALL_SHUTDOWN,
 	DUALCALL_READ, DUALCALL_READV,
-	DUALCALL_DUP2, DUALCALL_CLOSE,
+	DUALCALL_DUP, DUALCALL_DUP2,
+	DUALCALL_CLOSE,
 	DUALCALL_POLLTS,
+	DUALCALL_KEVENT,
 	DUALCALL__NUM
 };
 
@@ -81,15 +83,19 @@
 #if !__NetBSD_Prereq__(5,99,7)
 #define REALSELECT select
 #define REALPOLLTS pollts
+#define REALKEVENT kevent
 #else
 #define REALSELECT _sys___select50
 #define REALPOLLTS _sys___pollts50
+#define REALKEVENT _sys___kevent50
 #endif
 #define REALREAD _sys_read
 
 int REALSELECT(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 int REALPOLLTS(struct pollfd *, nfds_t,
 	       const struct timespec *, const sigset_t *);
+int REALKEVENT(int, const struct kevent *, size_t, struct kevent *, size_t,
+	       const struct timespec *);
 ssize_t REALREAD(int, void *, size_t);
 
 #define S(a) __STRING(a)
@@ -118,9 +124,11 @@
 	{ DUALCALL_WRITEV,	"writev",	RSYS_NAME(WRITEV)	},
 	{ DUALCALL_IOCTL,	"ioctl",	RSYS_NAME(IOCTL)	},
 	{ DUALCALL_FCNTL,	"fcntl",	RSYS_NAME(FCNTL)	},
+	{ DUALCALL_DUP,		"dup",		RSYS_NAME(DUP)		},
 	{ DUALCALL_DUP2,	"dup2",		RSYS_NAME(DUP2)		},
 	{ DUALCALL_CLOSE,	"close",	RSYS_NAME(CLOSE)	},
 	{ DUALCALL_POLLTS,	S(REALPOLLTS),	RSYS_NAME(POLLTS)	},
+	{ DUALCALL_KEVENT,	S(REALKEVENT),	RSYS_NAME(KEVENT)	},
 };
 #undef S
 
@@ -269,7 +277,6 @@
 
 /* XXX: need runtime selection.  low for now due to FD_SETSIZE */
 #define HIJACK_FDOFF 128
-#define HIJACK_SELECT 128 /* XXX */
 #define HIJACK_ASSERT 128 /* XXX */
 static int
 fd_rump2host(int fd)
@@ -375,6 +382,8 @@
 	return rv;
 }
 
+
+/* TODO: support F_DUPFD, F_CLOSEM, F_MAXFD */
 int
 fcntl(int fd, int cmd, ...)
 {
@@ -444,6 +453,28 @@
 	return rv;
 }
 
+int
+dup(int oldd)
+{
+	int (*op_dup)(int);
+	int newd;
+
+	DPRINTF(("dup -> %d\n", oldd));
+	if (fd_isrump(oldd)) {
+		op_dup = GETSYSCALL(rump, DUP);
+	} else {
+		op_dup = GETSYSCALL(host, DUP);
+	}
+
+	newd = op_dup(oldd);
+
+	if (fd_isrump(oldd))
+		newd = fd_rump2host(newd);
+	DPRINTF(("dup <- %d\n", newd));
+
+	return newd;
+}
+
 /*
  * We just wrap fork the appropriate rump client calls to preserve
  * the file descriptors of the forked parent in the child, but
@@ -818,26 +849,32 @@
 }
 
 int
-kqueue(void)
-{
-
-	if (!ISDUP2D(STDERR_FILENO) && isatty(STDERR_FILENO)) {
-		fprintf(stderr, "rumphijack: kqueue currently unsupported\n");
-	}
-	errno = ENOSYS;
-	return -1;
-}
-
-/*ARGSUSED*/
-int
-kevent(int kq, const struct kevent *changelist, size_t nchanges,
+REALKEVENT(int kq, const struct kevent *changelist, size_t nchanges,
 	struct kevent *eventlist, size_t nevents,
 	const struct timespec *timeout)
 {
+	int (*op_kevent)(int, const struct kevent *, size_t,
+		struct kevent *, size_t, const struct timespec *);
+	const struct kevent *ev;
+	size_t i;
+
+	/*
+	 * Check that we don't attempt to kevent rump kernel fd's.
+	 * That needs similar treatment to select/poll, but is slightly
+	 * trickier since we need to manage to different kq descriptors.
+	 * (TODO, in case you're wondering).
+	 */
+	for (i = 0; i < nchanges; i++) {
+		ev = &changelist[i];
+		if (ev->filter == EVFILT_READ || ev->filter == EVFILT_WRITE ||
+		    ev->filter == EVFILT_VNODE) {
+			if (fd_isrump(ev->ident))
+				return ENOTSUP;
+		}
+	}
 
-	fprintf(stderr, "kevent impossible\n");
-	abort();
-	/*NOTREACHED*/
+	op_kevent = GETSYSCALL(host, ACCEPT);
+	return op_kevent(kq, changelist, nchanges, eventlist, nevents, timeout);
 }
 
 /*

Reply via email to