Module Name:    src
Committed By:   pooka
Date:           Tue Jan 25 12:18:33 UTC 2011

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

Log Message:
Rewrite to declare most dual-kernel calls with macros.  This helps
with adding new calls and makes all existing fd-accepting hijacked
calls dual-kernel.  It would be better to autogenerate the code
from syscalls.master, but this is easier for now.


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 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.16 src/lib/librumphijack/hijack.c:1.17
--- src/lib/librumphijack/hijack.c:1.16	Wed Jan 19 11:27:01 2011
+++ src/lib/librumphijack/hijack.c	Tue Jan 25 12:18:33 2011
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.16 2011/01/19 11:27:01 pooka Exp $	*/
+/*      $NetBSD: hijack.c,v 1.17 2011/01/25 12:18:33 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.16 2011/01/19 11:27:01 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.17 2011/01/25 12:18:33 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -53,94 +53,120 @@
 #include <time.h>
 #include <unistd.h>
 
-enum {	RUMPCALL_SOCKET, RUMPCALL_ACCEPT, RUMPCALL_BIND, RUMPCALL_CONNECT,
-	RUMPCALL_GETPEERNAME, RUMPCALL_GETSOCKNAME, RUMPCALL_LISTEN,
-	RUMPCALL_RECVFROM, RUMPCALL_RECVMSG,
-	RUMPCALL_SENDTO, RUMPCALL_SENDMSG,
-	RUMPCALL_GETSOCKOPT, RUMPCALL_SETSOCKOPT,
-	RUMPCALL_SHUTDOWN,
-	RUMPCALL_READ, RUMPCALL_READV,
-	RUMPCALL_WRITE, RUMPCALL_WRITEV,
-	RUMPCALL_IOCTL, RUMPCALL_FCNTL,
-	RUMPCALL_CLOSE,
-	RUMPCALL_POLLTS,
-	RUMPCALL__NUM
+enum dualcall {
+	DUALCALL_WRITE, DUALCALL_WRITEV,
+	DUALCALL_IOCTL, DUALCALL_FCNTL,
+	DUALCALL_SOCKET, DUALCALL_ACCEPT, DUALCALL_BIND, DUALCALL_CONNECT,
+	DUALCALL_GETPEERNAME, DUALCALL_GETSOCKNAME, DUALCALL_LISTEN,
+	DUALCALL_RECVFROM, DUALCALL_RECVMSG,
+	DUALCALL_SENDTO, DUALCALL_SENDMSG,
+	DUALCALL_GETSOCKOPT, DUALCALL_SETSOCKOPT,
+	DUALCALL_SHUTDOWN,
+	DUALCALL_READ, DUALCALL_READV,
+	DUALCALL_DUP2, DUALCALL_CLOSE,
+	DUALCALL_POLLTS,
+	DUALCALL__NUM
 };
 
 #define RSYS_STRING(a) __STRING(a)
 #define RSYS_NAME(a) RSYS_STRING(__CONCAT(RUMP_SYS_RENAME_,a))
 
-const char *sysnames[] = {
-	RSYS_NAME(SOCKET),
-	RSYS_NAME(ACCEPT),
-	RSYS_NAME(BIND),
-	RSYS_NAME(CONNECT),
-	RSYS_NAME(GETPEERNAME),
-	RSYS_NAME(GETSOCKNAME),
-	RSYS_NAME(LISTEN),
-	RSYS_NAME(RECVFROM),
-	RSYS_NAME(RECVMSG),
-	RSYS_NAME(SENDTO),
-	RSYS_NAME(SENDMSG),
-	RSYS_NAME(GETSOCKOPT),
-	RSYS_NAME(SETSOCKOPT),
-	RSYS_NAME(SHUTDOWN),
-	RSYS_NAME(READ),
-	RSYS_NAME(READV),
-	RSYS_NAME(WRITE),
-	RSYS_NAME(WRITEV),
-	RSYS_NAME(IOCTL),
-	RSYS_NAME(FCNTL),
-	RSYS_NAME(CLOSE),
-	RSYS_NAME(POLLTS),
-};
-
-static int	(*host_socket)(int, int, int);
-static int	(*host_connect)(int, const struct sockaddr *, socklen_t);
-static int	(*host_bind)(int, const struct sockaddr *, socklen_t);
-static int	(*host_listen)(int, int);
-static int	(*host_accept)(int, struct sockaddr *, socklen_t *);
-static int	(*host_getpeername)(int, struct sockaddr *, socklen_t *);
-static int	(*host_getsockname)(int, struct sockaddr *, socklen_t *);
-static int	(*host_setsockopt)(int, int, int, const void *, socklen_t);
-
-static ssize_t	(*host_read)(int, void *, size_t);
-static ssize_t	(*host_readv)(int, const struct iovec *, int);
-static ssize_t	(*host_write)(int, const void *, size_t);
-static ssize_t	(*host_writev)(int, const struct iovec *, int);
-static int	(*host_ioctl)(int, unsigned long, ...);
-static int	(*host_fcntl)(int, int, ...);
-static int	(*host_close)(int);
-static int	(*host_pollts)(struct pollfd *, nfds_t,
-			       const struct timespec *, const sigset_t *);
-static pid_t	(*host_fork)(void);
-static int	(*host_dup2)(int, int);
-static int	(*host_shutdown)(int, int);
-/* XXX */
-static void	*host_sendto;
-static void	*host_recvfrom;
-
-static void *rumpcalls[RUMPCALL__NUM];
-
 /*
  * Would be nice to get this automatically in sync with libc.
  * Also, this does not work for compat-using binaries!
  */
-
 #if !__NetBSD_Prereq__(5,99,7)
-#define SELECT select
-#define POLLTS pollts
-#define POLL poll
+#define LIBCSELECT select
+#define LIBCPOLLTS pollts
+#define LIBCPOLL poll
 #else
-#define SELECT __select50
-#define POLLTS __pollts50
-#define POLL __poll50
+#define LIBCSELECT __select50
+#define LIBCPOLLTS __pollts50
+#define LIBCPOLL __poll50
+#endif
 
 int SELECT(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 int POLLTS(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
 int POLL(struct pollfd *, nfds_t, int);
+
+#define S(a) __STRING(a)
+struct sysnames {
+	enum dualcall scm_callnum;
+	const char *scm_hostname;
+	const char *scm_rumpname;
+} syscnames[] = {
+	{ DUALCALL_SOCKET,	"__socket30",	RSYS_NAME(SOCKET)	},
+	{ DUALCALL_ACCEPT,	"accept",	RSYS_NAME(ACCEPT)	},
+	{ DUALCALL_BIND,	"bind",		RSYS_NAME(BIND)		},
+	{ DUALCALL_CONNECT,	"connect",	RSYS_NAME(CONNECT)	},
+	{ DUALCALL_GETPEERNAME,	"getpeername",	RSYS_NAME(GETPEERNAME)	},
+	{ DUALCALL_GETSOCKNAME,	"getsockname",	RSYS_NAME(GETSOCKNAME)	},
+	{ DUALCALL_LISTEN,	"listen",	RSYS_NAME(LISTEN)	},
+	{ DUALCALL_RECVFROM,	"recvfrom",	RSYS_NAME(RECVFROM)	},
+	{ DUALCALL_RECVMSG,	"recvmsg",	RSYS_NAME(RECVMSG)	},
+	{ DUALCALL_SENDTO,	"sendto",	RSYS_NAME(SENDTO)	},
+	{ DUALCALL_SENDMSG,	"sendmsg",	RSYS_NAME(SENDMSG)	},
+	{ DUALCALL_GETSOCKOPT,	"getsockopt",	RSYS_NAME(GETSOCKOPT)	},
+	{ DUALCALL_SETSOCKOPT,	"setsockopt",	RSYS_NAME(SETSOCKOPT)	},
+	{ DUALCALL_SHUTDOWN,	"shutdown",	RSYS_NAME(SHUTDOWN)	},
+	{ DUALCALL_READ,	"read",		RSYS_NAME(READ)		},
+	{ DUALCALL_READV,	"readv",	RSYS_NAME(READV)	},
+	{ DUALCALL_WRITE,	"write",	RSYS_NAME(WRITE)	},
+	{ DUALCALL_WRITEV,	"writev",	RSYS_NAME(WRITEV)	},
+	{ DUALCALL_IOCTL,	"ioctl",	RSYS_NAME(IOCTL)	},
+	{ DUALCALL_FCNTL,	"fcntl",	RSYS_NAME(FCNTL)	},
+	{ DUALCALL_DUP2,	"dup2",		RSYS_NAME(DUP2)		},
+	{ DUALCALL_CLOSE,	"close",	RSYS_NAME(CLOSE)	},
+	{ DUALCALL_POLLTS,	S(LIBCPOLLTS),	RSYS_NAME(POLLTS)	},
+};
+#undef S
+
+struct bothsys {
+	void *bs_host;
+	void *bs_rump;
+} syscalls[DUALCALL__NUM];
+#define GETSYSCALL(which, name) syscalls[DUALCALL_##name].bs_##which
+
+pid_t (*host_fork)(void);
+
+static unsigned dup2mask;
+#define ISDUP2D(fd) (1<<(fd) & dup2mask)
+
+//#define DEBUGJACK
+#ifdef DEBUGJACK
+#define DPRINTF(x) mydprintf x
+static void
+mydprintf(const char *fmt, ...)
+{
+	va_list ap;
+
+	if (ISDUP2D(STDERR_FILENO))
+		return;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+}
+
+#else
+#define DPRINTF(x)
 #endif
 
+#define FDCALL(type, name, rcname, args, proto, vars)			\
+type name args								\
+{									\
+	type (*fun) proto;						\
+									\
+	if (fd_isrump(fd)) {						\
+		fun = syscalls[rcname].bs_rump;				\
+		fd = fd_host2rump(fd);					\
+	} else {							\
+		fun = syscalls[rcname].bs_host;				\
+	}								\
+									\
+	return fun vars;						\
+}
+
 /*
  * This is called from librumpclient in case of LD_PRELOAD.
  * It ensures correct RTLD_NEXT.
@@ -161,7 +187,7 @@
 	int (*rumpcinit)(void);
 	void **rumpcdlsym;
 	void *hand;
-	int i;
+	int i, j;
 
 	hand = dlopen("librumpclient.so", RTLD_LAZY|RTLD_GLOBAL);
 	if (!hand)
@@ -171,66 +197,39 @@
 
 	rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
 	*rumpcdlsym = hijackdlsym;
-
-	host_socket = dlsym(RTLD_NEXT, "__socket30");
-	host_listen = dlsym(RTLD_NEXT, "listen");
-	host_connect = dlsym(RTLD_NEXT, "connect");
-	host_bind = dlsym(RTLD_NEXT, "bind");
-	host_accept = dlsym(RTLD_NEXT, "accept");
-	host_getpeername = dlsym(RTLD_NEXT, "getpeername");
-	host_getsockname = dlsym(RTLD_NEXT, "getsockname");
-	host_setsockopt = dlsym(RTLD_NEXT, "setsockopt");
-
-	host_read = dlsym(RTLD_NEXT, "read");
-	host_readv = dlsym(RTLD_NEXT, "readv");
-	host_write = dlsym(RTLD_NEXT, "write");
-	host_writev = dlsym(RTLD_NEXT, "writev");
-	host_ioctl = dlsym(RTLD_NEXT, "ioctl");
-	host_fcntl = dlsym(RTLD_NEXT, "fcntl");
-	host_close = dlsym(RTLD_NEXT, "close");
-	host_pollts = dlsym(RTLD_NEXT, "pollts");
 	host_fork = dlsym(RTLD_NEXT, "fork");
-	host_dup2 = dlsym(RTLD_NEXT, "dup2");
-	host_shutdown = dlsym(RTLD_NEXT, "shutdown");
-	host_sendto = dlsym(RTLD_NEXT, "sendto");
-	host_recvfrom = dlsym(RTLD_NEXT, "recvfrom");
-
-	for (i = 0; i < RUMPCALL__NUM; i++) {
-		rumpcalls[i] = dlsym(hand, sysnames[i]);
-		if (!rumpcalls[i]) {
-			fprintf(stderr, "rumphijack: cannot find symbol: %s\n",
-			    sysnames[i]);
-			exit(1);
-		}
+
+	/*
+	 * In theory cannot print anything during lookups because
+	 * we might not have the call vector set up.  so, the errx()
+	 * is a bit of a strech, but it might work.
+	 */
+
+	for (i = 0; i < DUALCALL__NUM; i++) {
+		/* build runtime O(1) access */
+		for (j = 0; j < __arraycount(syscnames); j++) {
+			if (syscnames[j].scm_callnum == i)
+				break;
+		}
+
+		if (j == __arraycount(syscnames))
+			errx(1, "rumphijack error: syscall pos %d missing", i);
+
+		syscalls[i].bs_host = dlsym(hand,syscnames[j].scm_hostname);
+		if (syscalls[i].bs_host == NULL)
+			errx(1, "hostcall %s not found missing",
+			    syscnames[j].scm_hostname);
+
+		syscalls[i].bs_rump = dlsym(hand,syscnames[j].scm_rumpname);
+		if (syscalls[i].bs_rump == NULL)
+			errx(1, "rumpcall %s not found missing",
+			    syscnames[j].scm_rumpname);
 	}
 
 	if (rumpcinit() == -1)
 		err(1, "rumpclient init");
 }
 
-static unsigned dup2mask;
-#define ISDUP2D(fd) (1<<(fd) & dup2mask)
-
-//#define DEBUGJACK
-#ifdef DEBUGJACK
-#define DPRINTF(x) mydprintf x
-static void
-mydprintf(const char *fmt, ...)
-{
-	va_list ap;
-
-	if (ISDUP2D(STDERR_FILENO))
-		return;
-
-	va_start(ap, fmt);
-	vfprintf(stderr, fmt, ap);
-	va_end(ap);
-}
-
-#else
-#define DPRINTF(x)
-#endif
-
 /* XXX: need runtime selection.  low for now due to FD_SETSIZE */
 #define HIJACK_FDOFF 128
 #define HIJACK_SELECT 128 /* XXX */
@@ -271,17 +270,17 @@
 int
 __socket30(int domain, int type, int protocol)
 {
-	int (*rc_socket)(int, int, int);
+	int (*op_socket)(int, int, int);
 	int fd;
 	bool dohost;
 
 	dohost = hostlocalsockets && (domain == AF_LOCAL);
 
 	if (dohost)
-		rc_socket = host_socket;
+		op_socket = GETSYSCALL(host, SOCKET);
 	else
-		rc_socket = rumpcalls[RUMPCALL_SOCKET];
-	fd = rc_socket(domain, type, protocol);
+		op_socket = GETSYSCALL(rump, SOCKET);
+	fd = op_socket(domain, type, protocol);
 
 	if (!dohost)
 		fd = fd_rump2host(fd);
@@ -293,7 +292,7 @@
 int
 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 {
-	int (*rc_accept)(int, struct sockaddr *, socklen_t *);
+	int (*op_accept)(int, struct sockaddr *, socklen_t *);
 	int fd;
 	bool isrump;
 
@@ -301,12 +300,12 @@
 
 	DPRINTF(("accept -> %d", s));
 	if (isrump) {
-		rc_accept = rumpcalls[RUMPCALL_ACCEPT];
+		op_accept = GETSYSCALL(rump, ACCEPT);
 		s = fd_host2rump(s);
 	} else {
-		rc_accept = host_accept;
+		op_accept = GETSYSCALL(host, ACCEPT);
 	}
-	fd = rc_accept(s, addr, addrlen);
+	fd = op_accept(s, addr, addrlen);
 	if (fd != -1 && isrump)
 		fd = fd_rump2host(fd);
 
@@ -315,195 +314,67 @@
 	return fd;
 }
 
+/*
+ * ioctl and fcntl are varargs calls and need special treatment
+ */
 int
-bind(int s, const struct sockaddr *name, socklen_t namelen)
-{
-	int (*rc_bind)(int, const struct sockaddr *, socklen_t);
-
-	DPRINTF(("bind -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_bind = rumpcalls[RUMPCALL_BIND];
-		s = fd_host2rump(s);
-	} else {
-		rc_bind = host_bind;
-	}
-	return rc_bind(s, name, namelen);
-}
-
-int
-connect(int s, const struct sockaddr *name, socklen_t namelen)
-{
-	int (*rc_connect)(int, const struct sockaddr *, socklen_t);
-
-	DPRINTF(("connect -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_connect = rumpcalls[RUMPCALL_CONNECT];
-		s = fd_host2rump(s);
-	} else {
-		rc_connect = host_connect;
-	}
-
-	return rc_connect(s, name, namelen);
-}
-
-int
-getpeername(int s, struct sockaddr *name, socklen_t *namelen)
+ioctl(int fd, unsigned long cmd, ...)
 {
-	int (*rc_getpeername)(int, struct sockaddr *, socklen_t *);
+	int (*op_ioctl)(int, unsigned long cmd, ...);
+	va_list ap;
+	int rv;
 
-	DPRINTF(("getpeername -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_getpeername = rumpcalls[RUMPCALL_GETPEERNAME];
-		s = fd_host2rump(s);
+	DPRINTF(("ioctl -> %d\n", fd));
+	if (fd_isrump(fd)) {
+		fd = fd_host2rump(fd);
+		op_ioctl = GETSYSCALL(rump, IOCTL);
 	} else {
-		rc_getpeername = host_getpeername;
+		op_ioctl = GETSYSCALL(host, IOCTL);
 	}
-	return rc_getpeername(s, name, namelen);
-}
-
-int
-getsockname(int s, struct sockaddr *name, socklen_t *namelen)
-{
-	int (*rc_getsockname)(int, struct sockaddr *, socklen_t *);
 
-	DPRINTF(("getsockname -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_getsockname = rumpcalls[RUMPCALL_GETSOCKNAME];
-		s = fd_host2rump(s);
-	} else {
-		rc_getsockname = host_getsockname;
-	}
-	return rc_getsockname(s, name, namelen);
+	va_start(ap, cmd);
+	rv = op_ioctl(fd, cmd, va_arg(ap, void *));
+	va_end(ap);
+	return rv;
 }
 
 int
-listen(int s, int backlog)
-{
-	int (*rc_listen)(int, int);
-
-	DPRINTF(("listen -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_listen = rumpcalls[RUMPCALL_LISTEN];
-		s = fd_host2rump(s);
-	} else {
-		rc_listen = host_listen;
-	}
-	return rc_listen(s, backlog);
-}
-
-ssize_t
-recv(int s, void *buf, size_t len, int flags)
-{
-
-	return recvfrom(s, buf, len, flags, NULL, NULL);
-}
-
-ssize_t
-recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from,
-	socklen_t *fromlen)
+fcntl(int fd, int cmd, ...)
 {
-	int (*rc_recvfrom)(int, void *, size_t, int,
-	    struct sockaddr *, socklen_t *);
+	int (*op_fcntl)(int, int, ...);
+	va_list ap;
+	int rv;
 
-	DPRINTF(("recvfrom\n"));
-	if (fd_isrump(s)) {
-		rc_recvfrom = rumpcalls[RUMPCALL_RECVFROM];
-		s = fd_host2rump(s);
+	DPRINTF(("fcntl -> %d\n", fd));
+	if (fd_isrump(fd)) {
+		fd = fd_host2rump(fd);
+		op_fcntl = GETSYSCALL(rump, FCNTL);
 	} else {
-		rc_recvfrom = host_recvfrom;
+		op_fcntl = GETSYSCALL(host, FCNTL);
 	}
 
-	return rc_recvfrom(s, buf, len, flags, from, fromlen);
-}
-
-ssize_t
-recvmsg(int s, struct msghdr *msg, int flags)
-{
-	int (*rc_recvmsg)(int, struct msghdr *, int);
-
-	DPRINTF(("recvmsg\n"));
-	assertfd(s);
-	rc_recvmsg = rumpcalls[RUMPCALL_RECVMSG];
-	return rc_recvmsg(fd_host2rump(s), msg, flags);
-}
-
-ssize_t
-send(int s, const void *buf, size_t len, int flags)
-{
-
-	return sendto(s, buf, len, flags, NULL, 0);
-}
-
-ssize_t
-sendto(int s, const void *buf, size_t len, int flags,
-	const struct sockaddr *to, socklen_t tolen)
-{
-	int (*rc_sendto)(int, const void *, size_t, int,
-	    const struct sockaddr *, socklen_t);
-
-	if (s == -1)
-		return len;
-	DPRINTF(("sendto\n"));
-
-	if (fd_isrump(s)) {
-		rc_sendto = rumpcalls[RUMPCALL_SENDTO];
-		s = fd_host2rump(s);
-	} else {
-		rc_sendto = host_sendto;
-	}
-	return rc_sendto(s, buf, len, flags, to, tolen);
+	va_start(ap, cmd);
+	rv = op_fcntl(fd, cmd, va_arg(ap, void *));
+	va_end(ap);
+	return rv;
 }
 
+/*
+ * write cannot issue a standard debug printf due to recursion
+ */
 ssize_t
-sendmsg(int s, const struct msghdr *msg, int flags)
+write(int fd, const void *buf, size_t blen)
 {
-	int (*rc_sendmsg)(int, const struct msghdr *, int);
-
-	DPRINTF(("sendmsg\n"));
-	assertfd(s);
-	rc_sendmsg = rumpcalls[RUMPCALL_SENDTO];
-	return rc_sendmsg(fd_host2rump(s), msg, flags);
-}
-
-int
-getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
-{
-	int (*rc_getsockopt)(int, int, int, void *, socklen_t *);
-
-	DPRINTF(("getsockopt -> %d\n", s));
-	assertfd(s);
-	rc_getsockopt = rumpcalls[RUMPCALL_GETSOCKOPT];
-	return rc_getsockopt(fd_host2rump(s), level, optname, optval, optlen);
-}
-
-int
-setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
-{
-	int (*rc_setsockopt)(int, int, int, const void *, socklen_t);
+	ssize_t (*op_write)(int, const void *, size_t);
 
-	DPRINTF(("setsockopt -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_setsockopt = rumpcalls[RUMPCALL_SETSOCKOPT];
-		s = fd_host2rump(s);
+	if (fd_isrump(fd)) {
+		fd = fd_host2rump(fd);
+		op_write = GETSYSCALL(rump, WRITE);
 	} else {
-		rc_setsockopt = host_setsockopt;
+		op_write = GETSYSCALL(host, WRITE);
 	}
-	return rc_setsockopt(s, level, optname, optval, optlen);
-}
 
-int
-shutdown(int s, int how)
-{
-	int (*rc_shutdown)(int, int);
-
-	DPRINTF(("shutdown -> %d\n", s));
-	if (fd_isrump(s)) {
-		rc_shutdown = rumpcalls[RUMPCALL_SHUTDOWN];
-		s = fd_host2rump(s);
-	} else {
-		rc_shutdown = host_shutdown;
-	}
-	return rc_shutdown(s, how);
+	return op_write(fd, buf, blen);
 }
 
 /*
@@ -512,12 +383,11 @@
  * not >= fdoff is an error.
  *
  * Note: cannot rump2host newd, because it is often hardcoded.
- *
- * XXX: should disable debug prints after stdout/stderr are dup2'd
  */
 int
 dup2(int oldd, int newd)
 {
+	int (*host_dup2)(int, int);
 	int rv;
 
 	DPRINTF(("dup2 -> %d (o) -> %d (n)\n", oldd, newd));
@@ -530,6 +400,7 @@
 		if (rv != -1)
 			dup2mask |= 1<<newd;
 	} else {
+		host_dup2 = syscalls[DUALCALL_DUP2].bs_host;
 		rv = host_dup2(oldd, newd);
 	}
 
@@ -541,7 +412,6 @@
  * the file descriptors of the forked parent in the child, but
  * prevent double use of connection fd.
  */
-
 pid_t
 fork()
 {
@@ -570,134 +440,10 @@
 }
 
 /*
- * Hybrids
+ * select is done by calling poll.
  */
-
-ssize_t
-read(int fd, void *buf, size_t len)
-{
-	ssize_t (*op_read)(int, void *, size_t);
-	ssize_t n;
-
-	DPRINTF(("read %d\n", fd));
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_read = rumpcalls[RUMPCALL_READ];
-	} else {
-		op_read = host_read;
-	}
-
-	n = op_read(fd, buf, len);
-	return n;
-}
-
-ssize_t
-readv(int fd, const struct iovec *iov, int iovcnt)
-{
-	ssize_t (*op_readv)(int, const struct iovec *, int);
-
-	DPRINTF(("readv %d\n", fd));
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_readv = rumpcalls[RUMPCALL_READV];
-	} else {
-		op_readv = host_readv;
-	}
-
-	return op_readv(fd, iov, iovcnt);
-}
-
-ssize_t
-write(int fd, const void *buf, size_t len)
-{
-	ssize_t (*op_write)(int, const void *, size_t);
-
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_write = rumpcalls[RUMPCALL_WRITE];
-	} else {
-		op_write = host_write;
-	}
-
-	return op_write(fd, buf, len);
-}
-
-ssize_t
-writev(int fd, const struct iovec *iov, int iovcnt)
-{
-	ssize_t (*op_writev)(int, const struct iovec *, int);
-
-	DPRINTF(("writev %d\n", fd));
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_writev = rumpcalls[RUMPCALL_WRITEV];
-	} else {
-		op_writev = host_writev;
-	}
-
-	return op_writev(fd, iov, iovcnt);
-}
-
 int
-ioctl(int fd, unsigned long cmd, ...)
-{
-	int (*op_ioctl)(int, unsigned long cmd, ...);
-	va_list ap;
-	int rv;
-
-	DPRINTF(("ioctl\n"));
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_ioctl = rumpcalls[RUMPCALL_IOCTL];
-	} else {
-		op_ioctl = host_ioctl;
-	}
-
-	va_start(ap, cmd);
-	rv = op_ioctl(fd, cmd, va_arg(ap, void *));
-	va_end(ap);
-	return rv;
-}
-
-int
-fcntl(int fd, int cmd, ...)
-{
-	int (*op_fcntl)(int, int, ...);
-	va_list ap;
-	int rv;
-
-	DPRINTF(("fcntl\n"));
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_fcntl = rumpcalls[RUMPCALL_FCNTL];
-	} else {
-		op_fcntl = host_fcntl;
-	}
-
-	va_start(ap, cmd);
-	rv = op_fcntl(fd, cmd, va_arg(ap, void *));
-	va_end(ap);
-	return rv;
-}
-
-int
-close(int fd)
-{
-	int (*op_close)(int);
-
-	DPRINTF(("close %d\n", fd));
-	if (fd_isrump(fd)) {
-		fd = fd_host2rump(fd);
-		op_close = rumpcalls[RUMPCALL_CLOSE];
-	} else {
-		op_close = host_close;
-	}
-
-	return op_close(fd);
-}
-
-int
-SELECT(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+LIBCSELECT(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 	struct timeval *timeout)
 {
 	struct pollfd *pfds;
@@ -710,7 +456,7 @@
 	/*
 	 * Well, first we must scan the fds to figure out how many
 	 * fds there really are.  This is because up to and including
-	 * nb5 poll() silently refuses nfds > process_open_fds.
+	 * nb5 poll() silently refuses nfds > process_maxopen_fds.
 	 * Seems to be fixed in current, thank the maker.
 	 * god damn cluster...bomb.
 	 */
@@ -847,10 +593,13 @@
 static void *
 hostpoll(void *arg)
 {
+	int (*op_pollts)(struct pollfd *, nfds_t, const struct timespec *,
+			 const sigset_t *);
 	struct pollarg *parg = arg;
 	intptr_t rv;
 
-	rv = host_pollts(parg->pfds, parg->nfds, parg->ts, parg->sigmask);
+	op_pollts = syscalls[DUALCALL_POLLTS].bs_host;
+	rv = op_pollts(parg->pfds, parg->nfds, parg->ts, parg->sigmask);
 	if (rv == -1)
 		parg->errnum = errno;
 	rump_sys_write(parg->pipefd, &rv, sizeof(rv));
@@ -859,11 +608,12 @@
 }
 
 int
-POLLTS(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
+LIBCPOLLTS(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
 	const sigset_t *sigmask)
 {
 	int (*op_pollts)(struct pollfd *, nfds_t, const struct timespec *,
 			 const sigset_t *);
+	int (*host_close)(int);
 	int hostcall = 0, rumpcall = 0;
 	pthread_t pt;
 	nfds_t i;
@@ -941,7 +691,7 @@
 		parg.pipefd = rpipe[1];
 		pthread_create(&pt, NULL, hostpoll, &parg);
 
-		op_pollts = rumpcalls[RUMPCALL_POLLTS];
+		op_pollts = syscalls[DUALCALL_POLLTS].bs_rump;
 		lrv = op_pollts(pfd_rump, nfds+1, ts, NULL);
 		sverrno = errno;
 		write(hpipe[1], &rv, sizeof(rv));
@@ -968,6 +718,7 @@
 		}
 
  out:
+		host_close = syscalls[DUALCALL_CLOSE].bs_host;
 		if (rpipe[0] != -1)
 			rump_sys_close(rpipe[0]);
 		if (rpipe[1] != -1)
@@ -981,9 +732,9 @@
 		errno = sverrno;
 	} else {
 		if (hostcall) {
-			op_pollts = host_pollts;
+			op_pollts = syscalls[DUALCALL_POLLTS].bs_host;
 		} else {
-			op_pollts = rumpcalls[RUMPCALL_POLLTS];
+			op_pollts = syscalls[DUALCALL_POLLTS].bs_rump;
 			adjustpoll(fds, nfds, fd_host2rump);
 		}
 
@@ -996,7 +747,7 @@
 }
 
 int
-POLL(struct pollfd *fds, nfds_t nfds, int timeout)
+LIBCPOLL(struct pollfd *fds, nfds_t nfds, int timeout)
 {
 	struct timespec ts;
 	struct timespec *tsp = NULL;
@@ -1015,14 +766,107 @@
 kqueue(void)
 {
 
+	fprintf(stderr, "kqueue unsupported");
 	abort();
+	/*NOTREACHED*/
 }
 
+/*ARGSUSED*/
 int
 kevent(int kq, const struct kevent *changelist, size_t nchanges,
 	struct kevent *eventlist, size_t nevents,
 	const struct timespec *timeout)
 {
 
+	fprintf(stderr, "kqueue unsupported");
 	abort();
+	/*NOTREACHED*/
 }
+
+/*
+ * Rest are std type calls.
+ */
+
+FDCALL(int, bind, DUALCALL_BIND,					\
+	(int fd, const struct sockaddr *name, socklen_t namelen),	\
+	(int, const struct sockaddr *, socklen_t),			\
+	(fd, name, namelen))
+
+FDCALL(int, connect, DUALCALL_CONNECT,					\
+	(int fd, const struct sockaddr *name, socklen_t namelen),	\
+	(int, const struct sockaddr *, socklen_t),			\
+	(fd, name, namelen))
+
+FDCALL(int, getpeername, DUALCALL_GETPEERNAME,				\
+	(int fd, struct sockaddr *name, socklen_t *namelen),		\
+	(int, struct sockaddr *, socklen_t *),				\
+	(fd, name, namelen))
+
+FDCALL(int, getsockname, DUALCALL_GETSOCKNAME, 				\
+	(int fd, struct sockaddr *name, socklen_t *namelen),		\
+	(int, struct sockaddr *, socklen_t *),				\
+	(fd, name, namelen))
+
+FDCALL(int, listen, DUALCALL_LISTEN,	 				\
+	(int fd, int backlog),						\
+	(int, int),							\
+	(fd, backlog))
+
+FDCALL(ssize_t, recvfrom, DUALCALL_RECVFROM, 				\
+	(int fd, void *buf, size_t len, int flags,			\
+	    struct sockaddr *from, socklen_t *fromlen),			\
+	(int, void *, size_t, int, struct sockaddr *, socklen_t *),	\
+	(fd, buf, len, flags, from, fromlen))
+
+FDCALL(ssize_t, sendto, DUALCALL_SENDTO, 				\
+	(int fd, const void *buf, size_t len, int flags,		\
+	    const struct sockaddr *to, socklen_t tolen),		\
+	(int, const void *, size_t, int,				\
+	    const struct sockaddr *, socklen_t),			\
+	(fd, buf, len, flags, to, tolen))
+
+FDCALL(ssize_t, recvmsg, DUALCALL_RECVMSG, 				\
+	(int fd, struct msghdr *msg, int flags),			\
+	(int, struct msghdr *, int),					\
+	(fd, msg, flags))
+
+FDCALL(ssize_t, sendmsg, DUALCALL_SENDMSG, 				\
+	(int fd, const struct msghdr *msg, int flags),			\
+	(int, const struct msghdr *, int),				\
+	(fd, msg, flags))
+
+FDCALL(int, getsockopt, DUALCALL_GETSOCKOPT, 				\
+	(int fd, int level, int optn, void *optval, socklen_t *optlen),	\
+	(int, int, int, void *, socklen_t *),				\
+	(fd, level, optn, optval, optlen))
+
+FDCALL(int, setsockopt, DUALCALL_SETSOCKOPT, 				\
+	(int fd, int level, int optn,					\
+	    const void *optval, socklen_t optlen),			\
+	(int, int, int, const void *, socklen_t),			\
+	(fd, level, optn, optval, optlen))
+
+FDCALL(int, shutdown, DUALCALL_SHUTDOWN, 				\
+	(int fd, int how),						\
+	(int, int),							\
+	(fd, how))
+
+FDCALL(ssize_t, read, DUALCALL_READ,	 				\
+	(int fd, void *buf, size_t buflen),				\
+	(int, void *, size_t),						\
+	(fd, buf, buflen))
+
+FDCALL(ssize_t, readv, DUALCALL_READV, 				\
+	(int fd, const struct iovec *iov, int iovcnt),			\
+	(int, const struct iovec *, int),				\
+	(fd, iov, iovcnt))
+
+FDCALL(ssize_t, writev, DUALCALL_WRITEV, 				\
+	(int fd, const struct iovec *iov, int iovcnt),			\
+	(int, const struct iovec *, int),				\
+	(fd, iov, iovcnt))
+
+FDCALL(int, close, DUALCALL_CLOSE,	 				\
+	(int fd),							\
+	(int),								\
+	(fd))

Reply via email to