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))