| @@ -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 | |
53 | enum { RUMPCALL_SOCKET, RUMPCALL_ACCEPT, RUMPCALL_BIND, RUMPCALL_CONNECT, | | 55 | enum { 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 | |
67 | const char *sysnames[] = { | | 69 | const 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 | |
94 | static ssize_t (*host_read)(int, void *, size_t); | | 95 | static ssize_t (*host_read)(int, void *, size_t); |
95 | static ssize_t (*host_readv)(int, const struct iovec *, int); | | 96 | static ssize_t (*host_readv)(int, const struct iovec *, int); |
96 | static ssize_t (*host_write)(int, const void *, size_t); | | 97 | static ssize_t (*host_write)(int, const void *, size_t); |
97 | static ssize_t (*host_writev)(int, const struct iovec *, int); | | 98 | static ssize_t (*host_writev)(int, const struct iovec *, int); |
98 | static int (*host_ioctl)(int, unsigned long, ...); | | 99 | static int (*host_ioctl)(int, unsigned long, ...); |
99 | static int (*host_fcntl)(int, int, ...); | | 100 | static int (*host_fcntl)(int, int, ...); |
100 | static int (*host_close)(int); | | 101 | static int (*host_close)(int); |
101 | static int (*host_select)(int, fd_set *, fd_set *, fd_set *, | | 102 | static int (*host_select)(int, fd_set *, fd_set *, fd_set *, |
102 | struct timeval *); | | 103 | struct timeval *); |
103 | static int (*host_poll)(struct pollfd *, nfds_t, int); | | | |
104 | static pid_t (*host_fork)(void); | | | |
105 | static int (*host_dup2)(int, int); | | | |
106 | #if 0 | | | |
107 | static int (*host_pollts)(struct pollfd *, nfds_t, | | 104 | static int (*host_pollts)(struct pollfd *, nfds_t, |
108 | const struct timespec *, const sigset_t *); | | 105 | const struct timespec *, const sigset_t *); |
109 | #endif | | 106 | static pid_t (*host_fork)(void); |
| | | 107 | static int (*host_dup2)(int, int); |
110 | | | 108 | |
111 | static void *rumpcalls[RUMPCALL__NUM]; | | 109 | static 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 | */ |
117 | static void * | | 115 | static void * |
118 | hijackdlsym(void *handle, const char *symbol) | | 116 | hijackdlsym(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 | |
680 | static void | | 678 | static void |
681 | adjustpoll(struct pollfd *fds, nfds_t nfds, int (*fdadj)(int)) | | 679 | adjustpoll(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 | |
| | | 688 | struct 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 | */ |
694 | struct pollarg { | | 697 | struct 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 | |
702 | static void * | | 706 | static void * |
703 | hostpoll(void *arg) | | 707 | hostpoll(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 | |
716 | int | | 720 | int |
717 | poll(struct pollfd *fds, nfds_t nfds, int timeout) | | 721 | pollts(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 | |
846 | int | | 866 | int |
847 | pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts, | | 867 | poll(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 | } |