Sat Jan 8 18:11:47 2011 UTC ()
support pollts and rewrite poll in terms of pollts


(pooka)
diff -r1.2 -r1.3 src/lib/librumphijack/hijack.c

cvs diff -r1.2 -r1.3 src/lib/librumphijack/hijack.c (expand / switch to unified diff)

--- src/lib/librumphijack/hijack.c 2011/01/08 14:19:27 1.2
+++ src/lib/librumphijack/hijack.c 2011/01/08 18:11:46 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hijack.c,v 1.2 2011/01/08 14:19:27 pooka Exp $ */ 1/* $NetBSD: hijack.c,v 1.3 2011/01/08 18:11:46 pooka Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2011 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -16,107 +16,105 @@ @@ -16,107 +16,105 @@
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE. 25 * SUCH DAMAGE.
26 */ 26 */
27 27
28#include <sys/cdefs.h> 28#include <sys/cdefs.h>
29__RCSID("$NetBSD: hijack.c,v 1.2 2011/01/08 14:19:27 pooka Exp $"); 29__RCSID("$NetBSD: hijack.c,v 1.3 2011/01/08 18:11:46 pooka Exp $");
30 30
31#include <sys/param.h> 31#include <sys/param.h>
32#include <sys/types.h> 32#include <sys/types.h>
33#include <sys/ioctl.h> 33#include <sys/ioctl.h>
34#include <sys/socket.h> 34#include <sys/socket.h>
35#include <sys/poll.h> 35#include <sys/poll.h>
36 36
37#include <rump/rump.h> 37#include <rump/rump.h>
38#include <rump/rumpclient.h> 38#include <rump/rumpclient.h>
39#include <rump/rump_syscalls.h> 39#include <rump/rump_syscalls.h>
40 40
41#include <assert.h> 41#include <assert.h>
42#include <dlfcn.h> 42#include <dlfcn.h>
43#include <err.h> 43#include <err.h>
44#include <errno.h> 44#include <errno.h>
45#include <fcntl.h> 45#include <fcntl.h>
46#include <poll.h> 46#include <poll.h>
47#include <pthread.h> 47#include <pthread.h>
 48#include <signal.h>
48#include <stdarg.h> 49#include <stdarg.h>
49#include <stdio.h> 50#include <stdio.h>
50#include <stdlib.h> 51#include <stdlib.h>
 52#include <time.h>
51#include <unistd.h> 53#include <unistd.h>
52 54
53enum { RUMPCALL_SOCKET, RUMPCALL_ACCEPT, RUMPCALL_BIND, RUMPCALL_CONNECT, 55enum { RUMPCALL_SOCKET, RUMPCALL_ACCEPT, RUMPCALL_BIND, RUMPCALL_CONNECT,
54 RUMPCALL_GETPEERNAME, RUMPCALL_GETSOCKNAME, RUMPCALL_LISTEN, 56 RUMPCALL_GETPEERNAME, RUMPCALL_GETSOCKNAME, RUMPCALL_LISTEN,
55 RUMPCALL_RECVFROM, RUMPCALL_RECVMSG, 57 RUMPCALL_RECVFROM, RUMPCALL_RECVMSG,
56 RUMPCALL_SENDTO, RUMPCALL_SENDMSG, 58 RUMPCALL_SENDTO, RUMPCALL_SENDMSG,
57 RUMPCALL_GETSOCKOPT, RUMPCALL_SETSOCKOPT, 59 RUMPCALL_GETSOCKOPT, RUMPCALL_SETSOCKOPT,
58 RUMPCALL_SHUTDOWN, 60 RUMPCALL_SHUTDOWN,
59 RUMPCALL_READ, RUMPCALL_READV, 61 RUMPCALL_READ, RUMPCALL_READV,
60 RUMPCALL_WRITE, RUMPCALL_WRITEV, 62 RUMPCALL_WRITE, RUMPCALL_WRITEV,
61 RUMPCALL_IOCTL, RUMPCALL_FCNTL, 63 RUMPCALL_IOCTL, RUMPCALL_FCNTL,
62 RUMPCALL_CLOSE, 64 RUMPCALL_CLOSE,
63 RUMPCALL_SELECT, RUMPCALL_POLL, RUMPCALL_POLLTS, 65 RUMPCALL_SELECT, RUMPCALL_POLLTS,
64 RUMPCALL__NUM 66 RUMPCALL__NUM
65}; 67};
66 68
67const char *sysnames[] = { 69const char *sysnames[] = {
68 "__socket30", 70 "__socket30",
69 "accept", 71 "accept",
70 "bind", 72 "bind",
71 "connect", 73 "connect",
72 "getpeername", 74 "getpeername",
73 "getsockname", 75 "getsockname",
74 "listen", 76 "listen",
75 "recvfrom", 77 "recvfrom",
76 "recvmsg", 78 "recvmsg",
77 "sendto", 79 "sendto",
78 "sendmsg", 80 "sendmsg",
79 "getsockopt", 81 "getsockopt",
80 "setsockopt", 82 "setsockopt",
81 "shutdown", 83 "shutdown",
82 "read", 84 "read",
83 "readv", 85 "readv",
84 "write", 86 "write",
85 "writev", 87 "writev",
86 "ioctl", 88 "ioctl",
87 "fcntl", 89 "fcntl",
88 "close", 90 "close",
89 "__select50", 91 "__select50",
90 "poll", 
91 "__pollts50", 92 "__pollts50",
92}; 93};
93 94
94static ssize_t (*host_read)(int, void *, size_t); 95static ssize_t (*host_read)(int, void *, size_t);
95static ssize_t (*host_readv)(int, const struct iovec *, int); 96static ssize_t (*host_readv)(int, const struct iovec *, int);
96static ssize_t (*host_write)(int, const void *, size_t); 97static ssize_t (*host_write)(int, const void *, size_t);
97static ssize_t (*host_writev)(int, const struct iovec *, int); 98static ssize_t (*host_writev)(int, const struct iovec *, int);
98static int (*host_ioctl)(int, unsigned long, ...); 99static int (*host_ioctl)(int, unsigned long, ...);
99static int (*host_fcntl)(int, int, ...); 100static int (*host_fcntl)(int, int, ...);
100static int (*host_close)(int); 101static int (*host_close)(int);
101static int (*host_select)(int, fd_set *, fd_set *, fd_set *, 102static int (*host_select)(int, fd_set *, fd_set *, fd_set *,
102 struct timeval *); 103 struct timeval *);
103static int (*host_poll)(struct pollfd *, nfds_t, int); 
104static pid_t (*host_fork)(void); 
105static int (*host_dup2)(int, int); 
106#if 0 
107static int (*host_pollts)(struct pollfd *, nfds_t, 104static int (*host_pollts)(struct pollfd *, nfds_t,
108 const struct timespec *, const sigset_t *); 105 const struct timespec *, const sigset_t *);
109#endif 106static pid_t (*host_fork)(void);
 107static int (*host_dup2)(int, int);
110 108
111static void *rumpcalls[RUMPCALL__NUM]; 109static void *rumpcalls[RUMPCALL__NUM];
112 110
113/* 111/*
114 * This is called from librumpclient in case of LD_PRELOAD. 112 * This is called from librumpclient in case of LD_PRELOAD.
115 * It ensures correct RTLD_NEXT. 113 * It ensures correct RTLD_NEXT.
116 */ 114 */
117static void * 115static void *
118hijackdlsym(void *handle, const char *symbol) 116hijackdlsym(void *handle, const char *symbol)
119{ 117{
120 118
121 return dlsym(handle, symbol); 119 return dlsym(handle, symbol);
122} 120}
@@ -136,37 +134,37 @@ rcinit(void) @@ -136,37 +134,37 @@ rcinit(void)
136 _DIAGASSERT(rumpcinit); 134 _DIAGASSERT(rumpcinit);
137 135
138 rumpcdlsym = dlsym(hand, "rumpclient_dlsym"); 136 rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
139 *rumpcdlsym = hijackdlsym; 137 *rumpcdlsym = hijackdlsym;
140 138
141 host_read = dlsym(RTLD_NEXT, "read"); 139 host_read = dlsym(RTLD_NEXT, "read");
142 host_readv = dlsym(RTLD_NEXT, "readv"); 140 host_readv = dlsym(RTLD_NEXT, "readv");
143 host_write = dlsym(RTLD_NEXT, "write"); 141 host_write = dlsym(RTLD_NEXT, "write");
144 host_writev = dlsym(RTLD_NEXT, "writev"); 142 host_writev = dlsym(RTLD_NEXT, "writev");
145 host_ioctl = dlsym(RTLD_NEXT, "ioctl"); 143 host_ioctl = dlsym(RTLD_NEXT, "ioctl");
146 host_fcntl = dlsym(RTLD_NEXT, "fcntl"); 144 host_fcntl = dlsym(RTLD_NEXT, "fcntl");
147 host_close = dlsym(RTLD_NEXT, "close"); 145 host_close = dlsym(RTLD_NEXT, "close");
148 host_select = dlsym(RTLD_NEXT, "select"); 146 host_select = dlsym(RTLD_NEXT, "select");
149 host_poll = dlsym(RTLD_NEXT, "poll"); 147 host_pollts = dlsym(RTLD_NEXT, "pollts");
150 host_fork = dlsym(RTLD_NEXT, "fork"); 148 host_fork = dlsym(RTLD_NEXT, "fork");
151 host_dup2 = dlsym(RTLD_NEXT, "dup2"); 149 host_dup2 = dlsym(RTLD_NEXT, "dup2");
152 150
153 for (i = 0; i < RUMPCALL__NUM; i++) { 151 for (i = 0; i < RUMPCALL__NUM; i++) {
154 char sysname[128]; 152 char sysname[128];
155 153
156 snprintf(sysname, sizeof(sysname), "rump_sys_%s", sysnames[i]); 154 snprintf(sysname, sizeof(sysname), "rump_sys_%s", sysnames[i]);
157 rumpcalls[i] = dlsym(hand, sysname); 155 rumpcalls[i] = dlsym(hand, sysname);
158 if (!rumpcalls[i]) { 156 if (!rumpcalls[i]) {
159 fprintf(stderr, "%s\n", sysname); 157 fprintf(stderr, "cannot find symbol: %s\n", sysname);
160 exit(1); 158 exit(1);
161 } 159 }
162 } 160 }
163 161
164 if (rumpcinit() == -1) 162 if (rumpcinit() == -1)
165 err(1, "rumpclient init"); 163 err(1, "rumpclient init");
166} 164}
167 165
168//#define DEBUGJACK 166//#define DEBUGJACK
169#ifdef DEBUGJACK 167#ifdef DEBUGJACK
170#define DPRINTF(x) printf x 168#define DPRINTF(x) printf x
171#else 169#else
172#define DPRINTF(x) 170#define DPRINTF(x)
@@ -677,61 +675,79 @@ checkpoll(struct pollfd *fds, nfds_t nfd @@ -677,61 +675,79 @@ checkpoll(struct pollfd *fds, nfds_t nfd
677 } 675 }
678} 676}
679 677
680static void 678static void
681adjustpoll(struct pollfd *fds, nfds_t nfds, int (*fdadj)(int)) 679adjustpoll(struct pollfd *fds, nfds_t nfds, int (*fdadj)(int))
682{ 680{
683 nfds_t i; 681 nfds_t i;
684 682
685 for (i = 0; i < nfds; i++) { 683 for (i = 0; i < nfds; i++) {
686 fds[i].fd = fdadj(fds[i].fd); 684 fds[i].fd = fdadj(fds[i].fd);
687 } 685 }
688} 686}
689 687
 688struct mytimespec {
 689 uint64_t tv_sec;
 690 long tv_nsec;
 691};
 692
690/* 693/*
691 * poll is easy as long as the call comes in the fds only in one 694 * poll is easy as long as the call comes in the fds only in one
692 * kernel. otherwise its quite tricky... 695 * kernel. otherwise its quite tricky...
693 */ 696 */
694struct pollarg { 697struct pollarg {
695 struct pollfd *pfds; 698 struct pollfd *pfds;
696 nfds_t nfds; 699 nfds_t nfds;
697 int timeout; 700 const struct timespec *ts;
 701 const sigset_t *sigmask;
698 int pipefd; 702 int pipefd;
699 int errnum; 703 int errnum;
700}; 704};
701 705
702static void * 706static void *
703hostpoll(void *arg) 707hostpoll(void *arg)
704{ 708{
705 struct pollarg *parg = arg; 709 struct pollarg *parg = arg;
706 intptr_t rv; 710 intptr_t rv;
707 711
708 rv = poll(parg->pfds, parg->nfds, parg->timeout); 712 rv = host_pollts(parg->pfds, parg->nfds, parg->ts, parg->sigmask);
709 if (rv == -1) 713 if (rv == -1)
710 parg->errnum = errno; 714 parg->errnum = errno;
711 rump_sys_write(parg->pipefd, &rv, sizeof(rv)); 715 rump_sys_write(parg->pipefd, &rv, sizeof(rv));
712 716
713 return (void *)(intptr_t)rv; 717 return (void *)(intptr_t)rv;
714} 718}
715 719
716int 720int
717poll(struct pollfd *fds, nfds_t nfds, int timeout) 721pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
 722 const sigset_t *sigmask)
718{ 723{
719 int (*op_poll)(struct pollfd *, nfds_t, int); 724 int (*op_pollts)(struct pollfd *, nfds_t, const struct timespec *,
 725 const sigset_t *);
720 int hostcall = 0, rumpcall = 0; 726 int hostcall = 0, rumpcall = 0;
721 pthread_t pt; 727 pthread_t pt;
722 nfds_t i; 728 nfds_t i;
723 int rv; 729 int rv;
724 730
 731#if 0
 732 /* XXX: quick 5.0 kludge. do syscall compat in rumpclient properly */
 733 struct mytimespec mts;
 734 if (ts) {
 735 mts.tv_sec = ts->tv_sec;
 736 mts.tv_nsec = ts->tv_nsec;
 737 ts = (struct timespec *)&mts;
 738 }
 739#endif
 740
725 DPRINTF(("poll\n")); 741 DPRINTF(("poll\n"));
726 checkpoll(fds, nfds, &hostcall, &rumpcall); 742 checkpoll(fds, nfds, &hostcall, &rumpcall);
727 743
728 if (hostcall && rumpcall) { 744 if (hostcall && rumpcall) {
729 struct pollfd *pfd_host = NULL, *pfd_rump = NULL; 745 struct pollfd *pfd_host = NULL, *pfd_rump = NULL;
730 int rpipe[2] = {-1,-1}, hpipe[2] = {-1,-1}; 746 int rpipe[2] = {-1,-1}, hpipe[2] = {-1,-1};
731 struct pollarg parg; 747 struct pollarg parg;
732 uintptr_t lrv; 748 uintptr_t lrv;
733 int sverrno = 0, trv; 749 int sverrno = 0, trv;
734 750
735 /* 751 /*
736 * ok, this is where it gets tricky. We must support 752 * ok, this is where it gets tricky. We must support
737 * this since it's a very common operation in certain 753 * this since it's a very common operation in certain
@@ -743,27 +759,30 @@ poll(struct pollfd *fds, nfds_t nfds, in @@ -743,27 +759,30 @@ poll(struct pollfd *fds, nfds_t nfds, in
743 rv = -1; 759 rv = -1;
744 760
745 /* allocate full vector for O(n) joining after call */ 761 /* allocate full vector for O(n) joining after call */
746 pfd_host = malloc(sizeof(*pfd_host)*(nfds+1)); 762 pfd_host = malloc(sizeof(*pfd_host)*(nfds+1));
747 if (!pfd_host) 763 if (!pfd_host)
748 goto out; 764 goto out;
749 pfd_rump = malloc(sizeof(*pfd_rump)*(nfds+1)); 765 pfd_rump = malloc(sizeof(*pfd_rump)*(nfds+1));
750 if (!pfd_rump) { 766 if (!pfd_rump) {
751 goto out; 767 goto out;
752 } 768 }
753 769
754 /* split vectors */ 770 /* split vectors */
755 for (i = 0; i < nfds; i++) { 771 for (i = 0; i < nfds; i++) {
756 if (fd_isrump(fds[i].fd)) { 772 if (fds[i].fd == -1) {
 773 pfd_host[i].fd = -1;
 774 pfd_rump[i].fd = -1;
 775 } else if (fd_isrump(fds[i].fd)) {
757 pfd_host[i].fd = -1; 776 pfd_host[i].fd = -1;
758 pfd_rump[i].fd = fd_host2rump(fds[i].fd); 777 pfd_rump[i].fd = fd_host2rump(fds[i].fd);
759 pfd_rump[i].events = fds[i].events; 778 pfd_rump[i].events = fds[i].events;
760 } else { 779 } else {
761 pfd_rump[i].fd = -1; 780 pfd_rump[i].fd = -1;
762 pfd_host[i].fd = fds[i].fd; 781 pfd_host[i].fd = fds[i].fd;
763 pfd_host[i].events = fds[i].events; 782 pfd_host[i].events = fds[i].events;
764 } 783 }
765 } 784 }
766 785
767 /* 786 /*
768 * then, open two pipes, one for notifications 787 * then, open two pipes, one for notifications
769 * to each kernel. 788 * to each kernel.
@@ -775,78 +794,87 @@ poll(struct pollfd *fds, nfds_t nfds, in @@ -775,78 +794,87 @@ poll(struct pollfd *fds, nfds_t nfds, in
775 794
776 pfd_host[nfds].fd = hpipe[0]; 795 pfd_host[nfds].fd = hpipe[0];
777 pfd_host[nfds].events = POLLIN; 796 pfd_host[nfds].events = POLLIN;
778 pfd_rump[nfds].fd = rpipe[0]; 797 pfd_rump[nfds].fd = rpipe[0];
779 pfd_rump[nfds].events = POLLIN; 798 pfd_rump[nfds].events = POLLIN;
780 799
781 /* 800 /*
782 * then, create a thread to do host part and meanwhile 801 * then, create a thread to do host part and meanwhile
783 * do rump kernel part right here 802 * do rump kernel part right here
784 */ 803 */
785 804
786 parg.pfds = pfd_host; 805 parg.pfds = pfd_host;
787 parg.nfds = nfds+1; 806 parg.nfds = nfds+1;
788 parg.timeout = timeout; 807 parg.ts = ts;
 808 parg.sigmask = sigmask;
789 parg.pipefd = rpipe[1]; 809 parg.pipefd = rpipe[1];
790 pthread_create(&pt, NULL, hostpoll, &parg); 810 pthread_create(&pt, NULL, hostpoll, &parg);
791 811
792 lrv = rump_sys_poll(pfd_rump, nfds+1, timeout); 812 op_pollts = rumpcalls[RUMPCALL_POLLTS];
 813 lrv = op_pollts(pfd_rump, nfds+1, ts, NULL);
793 sverrno = errno; 814 sverrno = errno;
794 write(hpipe[1], &rv, sizeof(rv)); 815 write(hpipe[1], &rv, sizeof(rv));
795 pthread_join(pt, (void *)&trv); 816 pthread_join(pt, (void *)&trv);
796 817
797 /* check who "won" and merge results */ 818 /* check who "won" and merge results */
798 if (lrv != 0 && pfd_host[nfds].revents & POLLIN) { 819 if (lrv != 0 && pfd_host[nfds].revents & POLLIN) {
799 rv = trv; 820 rv = trv;
800 821
801 for (i = 0; i < nfds; i++) { 822 for (i = 0; i < nfds; i++) {
802 if (pfd_rump[i].fd != -1) 823 if (pfd_rump[i].fd != -1)
803 fds[i].revents = pfd_rump[i].revents; 824 fds[i].revents = pfd_rump[i].revents;
804 } 825 }
805 sverrno = parg.errnum; 826 sverrno = parg.errnum;
806 } else if (trv != 0 && pfd_rump[nfds].revents & POLLIN) { 827 } else if (trv != 0 && pfd_rump[nfds].revents & POLLIN) {
807 rv = trv; 828 rv = trv;
808 829
809 for (i = 0; i < nfds; i++) { 830 for (i = 0; i < nfds; i++) {
810 if (pfd_host[i].fd != -1) 831 if (pfd_host[i].fd != -1)
811 fds[i].revents = pfd_host[i].revents; 832 fds[i].revents = pfd_host[i].revents;
812 } 833 }
813 } else { 834 } else {
814 rv = 0; 835 rv = 0;
815 assert(timeout != -1); 
816 } 836 }
817 837
818 out: 838 out:
819 if (rpipe[0] != -1) 839 if (rpipe[0] != -1)
820 rump_sys_close(rpipe[0]); 840 rump_sys_close(rpipe[0]);
821 if (rpipe[1] != -1) 841 if (rpipe[1] != -1)
822 rump_sys_close(rpipe[1]); 842 rump_sys_close(rpipe[1]);
823 if (hpipe[0] != -1) 843 if (hpipe[0] != -1)
824 close(hpipe[0]); 844 close(hpipe[0]);
825 if (hpipe[1] != -1) 845 if (hpipe[1] != -1)
826 close(hpipe[1]); 846 close(hpipe[1]);
827 free(pfd_host); 847 free(pfd_host);
828 free(pfd_rump); 848 free(pfd_rump);
829 errno = sverrno; 849 errno = sverrno;
830 } else { 850 } else {
831 if (hostcall) { 851 if (hostcall) {
832 op_poll = host_poll; 852 op_pollts = host_pollts;
833 } else { 853 } else {
834 op_poll = rumpcalls[RUMPCALL_POLL]; 854 op_pollts = rumpcalls[RUMPCALL_POLLTS];
835 adjustpoll(fds, nfds, fd_host2rump); 855 adjustpoll(fds, nfds, fd_host2rump);
836 } 856 }
837 857
838 rv = op_poll(fds, nfds, timeout); 858 rv = op_pollts(fds, nfds, ts, sigmask);
839 if (rumpcall) 859 if (rumpcall)
840 adjustpoll(fds, nfds, fd_rump2host); 860 adjustpoll(fds, nfds, fd_rump2host);
841 } 861 }
842 862
843 return rv; 863 return rv;
844} 864}
845 865
846int 866int
847pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, 867poll(struct pollfd *fds, nfds_t nfds, int timeout)
848 const sigset_t *sigmask) 
849{ 868{
 869 struct timespec ts;
 870 struct timespec *tsp = NULL;
 871
 872 if (timeout != INFTIM) {
 873 ts.tv_sec = timeout / 1000;
 874 ts.tv_nsec = (timeout % 1000) * 1000;
 875
 876 tsp = &ts;
 877 }
850 878
851 abort(); 879 return pollts(fds, nfds, tsp, NULL);
852} 880}