Tue Dec 20 21:07:56 2011 UTC ()
thunk_pollchar: use read instead of getchar


(jmcneill)
diff -r1.48 -r1.49 src/sys/arch/usermode/usermode/thunk.c

cvs diff -r1.48 -r1.49 src/sys/arch/usermode/usermode/thunk.c (switch to unified diff)

--- src/sys/arch/usermode/usermode/thunk.c 2011/12/20 15:45:37 1.48
+++ src/sys/arch/usermode/usermode/thunk.c 2011/12/20 21:07:56 1.49
@@ -1,663 +1,666 @@ @@ -1,663 +1,666 @@
1/* $NetBSD: thunk.c,v 1.48 2011/12/20 15:45:37 reinoud Exp $ */ 1/* $NetBSD: thunk.c,v 1.49 2011/12/20 21:07:56 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30#ifdef __NetBSD__ 30#ifdef __NetBSD__
31__RCSID("$NetBSD: thunk.c,v 1.48 2011/12/20 15:45:37 reinoud Exp $"); 31__RCSID("$NetBSD: thunk.c,v 1.49 2011/12/20 21:07:56 jmcneill Exp $");
32#endif 32#endif
33 33
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/mman.h> 35#include <sys/mman.h>
36#include <sys/reboot.h> 36#include <sys/reboot.h>
37#include <sys/poll.h> 37#include <sys/poll.h>
38#include <machine/vmparam.h> 38#include <machine/vmparam.h>
39 39
40#include <aio.h> 40#include <aio.h>
41#include <assert.h> 41#include <assert.h>
42#include <errno.h> 42#include <errno.h>
43#include <fcntl.h> 43#include <fcntl.h>
44#include <sched.h> 44#include <sched.h>
45#include <stdarg.h> 45#include <stdarg.h>
46#include <stdint.h> 46#include <stdint.h>
47#include <stdio.h> 47#include <stdio.h>
48#include <stdlib.h> 48#include <stdlib.h>
49#include <signal.h> 49#include <signal.h>
50#include <string.h> 50#include <string.h>
51#include <termios.h> 51#include <termios.h>
52#include <time.h> 52#include <time.h>
53#include <ucontext.h> 53#include <ucontext.h>
54#include <unistd.h> 54#include <unistd.h>
55 55
56#include "../include/thunk.h" 56#include "../include/thunk.h"
57 57
58#ifndef __arraycount 58#ifndef __arraycount
59#define __arraycount(x) (sizeof((x)) / sizeof((x)[0])) 59#define __arraycount(x) (sizeof((x)) / sizeof((x)[0]))
60#endif 60#endif
61 61
62#ifndef MAP_ANON 62#ifndef MAP_ANON
63#define MAP_ANON MAP_ANONYMOUS 63#define MAP_ANON MAP_ANONYMOUS
64#endif 64#endif
65 65
66extern int boothowto; 66extern int boothowto;
67 67
68void 68void
69dprintf_debug(const char *fmt, ...) 69dprintf_debug(const char *fmt, ...)
70{ 70{
71 if (boothowto & AB_DEBUG) { 71 if (boothowto & AB_DEBUG) {
72 va_list ap; 72 va_list ap;
73 73
74 va_start(ap, fmt); 74 va_start(ap, fmt);
75 vfprintf(stderr, fmt, ap); 75 vfprintf(stderr, fmt, ap);
76 va_end(ap); 76 va_end(ap);
77 } 77 }
78} 78}
79 79
80static void 80static void
81thunk_to_timeval(const struct thunk_timeval *ttv, struct timeval *tv) 81thunk_to_timeval(const struct thunk_timeval *ttv, struct timeval *tv)
82{ 82{
83 tv->tv_sec = ttv->tv_sec; 83 tv->tv_sec = ttv->tv_sec;
84 tv->tv_usec = ttv->tv_usec; 84 tv->tv_usec = ttv->tv_usec;
85} 85}
86 86
87static void 87static void
88thunk_from_timeval(const struct timeval *tv, struct thunk_timeval *ttv) 88thunk_from_timeval(const struct timeval *tv, struct thunk_timeval *ttv)
89{ 89{
90 ttv->tv_sec = tv->tv_sec; 90 ttv->tv_sec = tv->tv_sec;
91 ttv->tv_usec = tv->tv_usec; 91 ttv->tv_usec = tv->tv_usec;
92} 92}
93 93
94static void 94static void
95thunk_to_itimerval(const struct thunk_itimerval *tit, struct itimerval *it) 95thunk_to_itimerval(const struct thunk_itimerval *tit, struct itimerval *it)
96{ 96{
97 thunk_to_timeval(&tit->it_interval, &it->it_interval); 97 thunk_to_timeval(&tit->it_interval, &it->it_interval);
98 thunk_to_timeval(&tit->it_value, &it->it_value); 98 thunk_to_timeval(&tit->it_value, &it->it_value);
99} 99}
100 100
101static void 101static void
102thunk_from_itimerval(const struct itimerval *it, struct thunk_itimerval *tit) 102thunk_from_itimerval(const struct itimerval *it, struct thunk_itimerval *tit)
103{ 103{
104 thunk_from_timeval(&it->it_interval, &tit->it_interval); 104 thunk_from_timeval(&it->it_interval, &tit->it_interval);
105 thunk_from_timeval(&it->it_value, &tit->it_value); 105 thunk_from_timeval(&it->it_value, &tit->it_value);
106} 106}
107 107
108static void 108static void
109thunk_to_termios(const struct thunk_termios *tt, struct termios *t) 109thunk_to_termios(const struct thunk_termios *tt, struct termios *t)
110{ 110{
111 int i; 111 int i;
112 112
113 t->c_iflag = tt->c_iflag; 113 t->c_iflag = tt->c_iflag;
114 t->c_oflag = tt->c_oflag; 114 t->c_oflag = tt->c_oflag;
115 t->c_cflag = tt->c_cflag; 115 t->c_cflag = tt->c_cflag;
116 t->c_lflag = tt->c_lflag; 116 t->c_lflag = tt->c_lflag;
117 for (i = 0; i < __arraycount(t->c_cc); i++) 117 for (i = 0; i < __arraycount(t->c_cc); i++)
118 t->c_cc[i] = tt->c_cc[i]; 118 t->c_cc[i] = tt->c_cc[i];
119 t->c_ispeed = tt->c_ispeed; 119 t->c_ispeed = tt->c_ispeed;
120 t->c_ospeed= tt->c_ospeed; 120 t->c_ospeed= tt->c_ospeed;
121} 121}
122 122
123static void 123static void
124thunk_from_termios(const struct termios *t, struct thunk_termios *tt) 124thunk_from_termios(const struct termios *t, struct thunk_termios *tt)
125{ 125{
126 int i; 126 int i;
127 127
128 tt->c_iflag = t->c_iflag; 128 tt->c_iflag = t->c_iflag;
129 tt->c_oflag = t->c_oflag; 129 tt->c_oflag = t->c_oflag;
130 tt->c_cflag = t->c_cflag; 130 tt->c_cflag = t->c_cflag;
131 tt->c_lflag = t->c_lflag; 131 tt->c_lflag = t->c_lflag;
132 for (i = 0; i < __arraycount(tt->c_cc); i++) 132 for (i = 0; i < __arraycount(tt->c_cc); i++)
133 tt->c_cc[i] = t->c_cc[i]; 133 tt->c_cc[i] = t->c_cc[i];
134 tt->c_ispeed = t->c_ispeed; 134 tt->c_ispeed = t->c_ispeed;
135 tt->c_ospeed= t->c_ospeed; 135 tt->c_ospeed= t->c_ospeed;
136} 136}
137 137
138static int 138static int
139thunk_to_native_prot(int prot) 139thunk_to_native_prot(int prot)
140{ 140{
141 int nprot = PROT_NONE; 141 int nprot = PROT_NONE;
142 142
143 if (prot & THUNK_PROT_READ) 143 if (prot & THUNK_PROT_READ)
144 nprot |= PROT_READ; 144 nprot |= PROT_READ;
145 if (prot & THUNK_PROT_WRITE) 145 if (prot & THUNK_PROT_WRITE)
146 nprot |= PROT_WRITE; 146 nprot |= PROT_WRITE;
147 if (prot & THUNK_PROT_EXEC) 147 if (prot & THUNK_PROT_EXEC)
148 nprot |= PROT_EXEC; 148 nprot |= PROT_EXEC;
149 149
150 return nprot; 150 return nprot;
151} 151}
152 152
153static int 153static int
154thunk_to_native_mapflags(int flags) 154thunk_to_native_mapflags(int flags)
155{ 155{
156 int nflags = 0; 156 int nflags = 0;
157 157
158 if (flags & THUNK_MAP_ANON) 158 if (flags & THUNK_MAP_ANON)
159 nflags |= MAP_ANON; 159 nflags |= MAP_ANON;
160 if (flags & THUNK_MAP_FIXED) 160 if (flags & THUNK_MAP_FIXED)
161 nflags |= MAP_FIXED; 161 nflags |= MAP_FIXED;
162 if (flags & THUNK_MAP_FILE) 162 if (flags & THUNK_MAP_FILE)
163 nflags |= MAP_FILE; 163 nflags |= MAP_FILE;
164 if (flags & THUNK_MAP_SHARED) 164 if (flags & THUNK_MAP_SHARED)
165 nflags |= MAP_SHARED; 165 nflags |= MAP_SHARED;
166 if (flags & THUNK_MAP_PRIVATE) 166 if (flags & THUNK_MAP_PRIVATE)
167 nflags |= MAP_PRIVATE; 167 nflags |= MAP_PRIVATE;
168#ifndef MAP_NOSYSCALLS 168#ifndef MAP_NOSYSCALLS
169#define MAP_NOSYSCALLS (1<<16) /* XXX alias for now XXX */ 169#define MAP_NOSYSCALLS (1<<16) /* XXX alias for now XXX */
170#endif 170#endif
171#ifdef MAP_NOSYSCALLS 171#ifdef MAP_NOSYSCALLS
172 if (flags & THUNK_MAP_NOSYSCALLS) 172 if (flags & THUNK_MAP_NOSYSCALLS)
173 nflags |= MAP_NOSYSCALLS; 173 nflags |= MAP_NOSYSCALLS;
174#endif 174#endif
175 175
176 return nflags; 176 return nflags;
177} 177}
178 178
179int 179int
180thunk_setitimer(int which, const struct thunk_itimerval *value, 180thunk_setitimer(int which, const struct thunk_itimerval *value,
181 struct thunk_itimerval *ovalue) 181 struct thunk_itimerval *ovalue)
182{ 182{
183 struct itimerval it, oit; 183 struct itimerval it, oit;
184 int error; 184 int error;
185 185
186 thunk_to_itimerval(value, &it); 186 thunk_to_itimerval(value, &it);
187 error = setitimer(which, &it, &oit); 187 error = setitimer(which, &it, &oit);
188 if (error) 188 if (error)
189 return error; 189 return error;
190 if (ovalue) 190 if (ovalue)
191 thunk_from_itimerval(&oit, ovalue); 191 thunk_from_itimerval(&oit, ovalue);
192 192
193 return 0; 193 return 0;
194} 194}
195 195
196int 196int
197thunk_gettimeofday(struct thunk_timeval *tp, void *tzp) 197thunk_gettimeofday(struct thunk_timeval *tp, void *tzp)
198{ 198{
199 struct timeval tv; 199 struct timeval tv;
200 int error; 200 int error;
201 201
202 error = gettimeofday(&tv, tzp); 202 error = gettimeofday(&tv, tzp);
203 if (error) 203 if (error)
204 return error; 204 return error;
205 205
206 thunk_from_timeval(&tv, tp); 206 thunk_from_timeval(&tv, tp);
207 207
208 return 0; 208 return 0;
209} 209}
210 210
211unsigned int 211unsigned int
212thunk_getcounter(void) 212thunk_getcounter(void)
213{ 213{
214 struct timespec ts; 214 struct timespec ts;
215 int error; 215 int error;
216 216
217 error = clock_gettime(CLOCK_MONOTONIC, &ts); 217 error = clock_gettime(CLOCK_MONOTONIC, &ts);
218 if (error) { 218 if (error) {
219 perror("clock_gettime CLOCK_MONOTONIC"); 219 perror("clock_gettime CLOCK_MONOTONIC");
220 abort(); 220 abort();
221 } 221 }
222 222
223 return (unsigned int)(ts.tv_nsec % 1000000000ULL); 223 return (unsigned int)(ts.tv_nsec % 1000000000ULL);
224} 224}
225 225
226long 226long
227thunk_clock_getres_monotonic(void) 227thunk_clock_getres_monotonic(void)
228{ 228{
229 struct timespec res; 229 struct timespec res;
230 int error; 230 int error;
231 231
232 error = clock_getres(CLOCK_MONOTONIC, &res); 232 error = clock_getres(CLOCK_MONOTONIC, &res);
233 if (error) 233 if (error)
234 return -1; 234 return -1;
235 235
236 return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec); 236 return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec);
237} 237}
238 238
239timer_t 239timer_t
240thunk_timer_attach(void) 240thunk_timer_attach(void)
241{ 241{
242 timer_t timerid; 242 timer_t timerid;
243 int error; 243 int error;
244 244
245 error = timer_create(CLOCK_MONOTONIC, NULL, &timerid); 245 error = timer_create(CLOCK_MONOTONIC, NULL, &timerid);
246 if (error) { 246 if (error) {
247 perror("timer_create CLOCK_MONOTONIC"); 247 perror("timer_create CLOCK_MONOTONIC");
248 abort(); 248 abort();
249 } 249 }
250 250
251 return timerid; 251 return timerid;
252} 252}
253 253
254int 254int
255thunk_timer_start(timer_t timerid, int freq) 255thunk_timer_start(timer_t timerid, int freq)
256{ 256{
257 struct itimerspec tim; 257 struct itimerspec tim;
258 258
259 tim.it_interval.tv_sec = 0; 259 tim.it_interval.tv_sec = 0;
260 tim.it_interval.tv_nsec = 1000000000 / freq; 260 tim.it_interval.tv_nsec = 1000000000 / freq;
261 tim.it_value = tim.it_interval; 261 tim.it_value = tim.it_interval;
262 262
263 return timer_settime(timerid, TIMER_RELTIME, &tim, NULL); 263 return timer_settime(timerid, TIMER_RELTIME, &tim, NULL);
264} 264}
265 265
266int 266int
267thunk_timer_getoverrun(timer_t timerid) 267thunk_timer_getoverrun(timer_t timerid)
268{ 268{
269 return timer_getoverrun(timerid); 269 return timer_getoverrun(timerid);
270} 270}
271 271
272int 272int
273thunk_usleep(useconds_t microseconds) 273thunk_usleep(useconds_t microseconds)
274{ 274{
275 return usleep(microseconds); 275 return usleep(microseconds);
276} 276}
277 277
278void 278void
279thunk_exit(int status) 279thunk_exit(int status)
280{ 280{
281 return exit(status); 281 return exit(status);
282} 282}
283 283
284void 284void
285thunk_abort(void) 285thunk_abort(void)
286{ 286{
287 abort(); 287 abort();
288} 288}
289 289
290int 290int
291thunk_geterrno(void) 291thunk_geterrno(void)
292{ 292{
293 return errno; 293 return errno;
294} 294}
295 295
296void 296void
297thunk_seterrno(int nerrno) 297thunk_seterrno(int nerrno)
298{ 298{
299 errno = nerrno; 299 errno = nerrno;
300} 300}
301 301
302int 302int
303thunk_getcontext(ucontext_t *ucp) 303thunk_getcontext(ucontext_t *ucp)
304{ 304{
305 return getcontext(ucp); 305 return getcontext(ucp);
306} 306}
307 307
308int 308int
309thunk_setcontext(const ucontext_t *ucp) 309thunk_setcontext(const ucontext_t *ucp)
310{ 310{
311 return setcontext(ucp); 311 return setcontext(ucp);
312} 312}
313 313
314void 314void
315thunk_makecontext(ucontext_t *ucp, void (*func)(void),  315thunk_makecontext(ucontext_t *ucp, void (*func)(void),
316 int nargs, void *arg1, void *arg2, void *arg3) 316 int nargs, void *arg1, void *arg2, void *arg3)
317{ 317{
318 switch (nargs) { 318 switch (nargs) {
319 case 0: 319 case 0:
320 makecontext(ucp, func, 0); 320 makecontext(ucp, func, 0);
321 break; 321 break;
322 case 1: 322 case 1:
323 makecontext(ucp, func, 1, arg1); 323 makecontext(ucp, func, 1, arg1);
324 break; 324 break;
325 case 2: 325 case 2:
326 makecontext(ucp, func, 2, arg1, arg2); 326 makecontext(ucp, func, 2, arg1, arg2);
327 break; 327 break;
328 case 3: 328 case 3:
329 makecontext(ucp, func, 3, arg1, arg2, arg3); 329 makecontext(ucp, func, 3, arg1, arg2, arg3);
330 break; 330 break;
331 default: 331 default:
332 printf("%s: nargs (%d) too big\n", __func__, nargs); 332 printf("%s: nargs (%d) too big\n", __func__, nargs);
333 abort(); 333 abort();
334 } 334 }
335} 335}
336 336
337int 337int
338thunk_swapcontext(ucontext_t *oucp, ucontext_t *ucp) 338thunk_swapcontext(ucontext_t *oucp, ucontext_t *ucp)
339{ 339{
340 return swapcontext(oucp, ucp); 340 return swapcontext(oucp, ucp);
341} 341}
342 342
343int 343int
344thunk_tcgetattr(int fd, struct thunk_termios *tt) 344thunk_tcgetattr(int fd, struct thunk_termios *tt)
345{ 345{
346 struct termios t; 346 struct termios t;
347 int error; 347 int error;
348 348
349 error = tcgetattr(fd, &t); 349 error = tcgetattr(fd, &t);
350 if (error) 350 if (error)
351 return error; 351 return error;
352 thunk_from_termios(&t, tt); 352 thunk_from_termios(&t, tt);
353 return 0; 353 return 0;
354} 354}
355 355
356int 356int
357thunk_tcsetattr(int fd, int action, const struct thunk_termios *tt) 357thunk_tcsetattr(int fd, int action, const struct thunk_termios *tt)
358{ 358{
359 struct termios t; 359 struct termios t;
360 360
361 thunk_to_termios(tt, &t); 361 thunk_to_termios(tt, &t);
362 return tcsetattr(fd, action, &t); 362 return tcsetattr(fd, action, &t);
363} 363}
364 364
365int 365int
366thunk_set_stdin_sigio(int onoff) 366thunk_set_stdin_sigio(int onoff)
367{ 367{
368 int flags; 368 int flags;
369 369
370 flags = fcntl(STDIN_FILENO, F_GETFL, 0); 370 flags = fcntl(STDIN_FILENO, F_GETFL, 0);
371 371
372 if (onoff) 372 if (onoff)
373 flags |= O_ASYNC; 373 flags |= O_ASYNC;
374 else 374 else
375 flags &= ~O_ASYNC; 375 flags &= ~O_ASYNC;
376 376
377 return fcntl(STDIN_FILENO, F_SETFL, flags); 377 return fcntl(STDIN_FILENO, F_SETFL, flags);
378} 378}
379 379
380int 380int
381thunk_pollchar(void) 381thunk_pollchar(void)
382{ 382{
383 struct pollfd fds[1]; 383 struct pollfd fds[1];
 384 uint8_t c;
384 385
385 fds[0].fd = STDIN_FILENO; 386 fds[0].fd = STDIN_FILENO;
386 fds[0].events = POLLIN; 387 fds[0].events = POLLIN;
387 fds[0].revents = 0; 388 fds[0].revents = 0;
388 389
389 if (poll(fds, __arraycount(fds), 0) > 0) { 390 if (poll(fds, __arraycount(fds), 0) > 0) {
390 if (fds[0].revents & POLLIN) { 391 if (fds[0].revents & POLLIN) {
391 return getchar(); 392 if (read(STDIN_FILENO, &c, 1) != 1)
 393 return EOF;
 394 return c;
392 } 395 }
393 } 396 }
394 397
395 return EOF; 398 return EOF;
396} 399}
397 400
398int 401int
399thunk_getchar(void) 402thunk_getchar(void)
400{ 403{
401 return getchar(); 404 return getchar();
402} 405}
403 406
404void 407void
405thunk_putchar(int c) 408thunk_putchar(int c)
406{ 409{
407 char wc = (char) c; 410 char wc = (char) c;
408 write(1, &wc, 1); 411 write(1, &wc, 1);
409} 412}
410 413
411int 414int
412thunk_execv(const char *path, char * const argv[]) 415thunk_execv(const char *path, char * const argv[])
413{ 416{
414 return execv(path, argv); 417 return execv(path, argv);
415} 418}
416 419
417int 420int
418thunk_open(const char *path, int flags, mode_t mode) 421thunk_open(const char *path, int flags, mode_t mode)
419{ 422{
420 return open(path, flags, mode); 423 return open(path, flags, mode);
421} 424}
422 425
423int 426int
424thunk_fstat_getsize(int fd, ssize_t *size, ssize_t *blksize) 427thunk_fstat_getsize(int fd, ssize_t *size, ssize_t *blksize)
425{ 428{
426 struct stat st; 429 struct stat st;
427 int error; 430 int error;
428 431
429 error = fstat(fd, &st); 432 error = fstat(fd, &st);
430 if (error) 433 if (error)
431 return -1; 434 return -1;
432 435
433 if (size) 436 if (size)
434 *size = st.st_size; 437 *size = st.st_size;
435 if (blksize) 438 if (blksize)
436 *blksize = st.st_blksize; 439 *blksize = st.st_blksize;
437 440
438 return 0; 441 return 0;
439} 442}
440 443
441ssize_t 444ssize_t
442thunk_pread(int d, void *buf, size_t nbytes, off_t offset) 445thunk_pread(int d, void *buf, size_t nbytes, off_t offset)
443{ 446{
444 return pread(d, buf, nbytes, offset); 447 return pread(d, buf, nbytes, offset);
445} 448}
446 449
447ssize_t 450ssize_t
448thunk_pwrite(int d, const void *buf, size_t nbytes, off_t offset) 451thunk_pwrite(int d, const void *buf, size_t nbytes, off_t offset)
449{ 452{
450 return pwrite(d, buf, nbytes, offset); 453 return pwrite(d, buf, nbytes, offset);
451} 454}
452 455
453ssize_t 456ssize_t
454thunk_write(int d, const void *buf, size_t nbytes) 457thunk_write(int d, const void *buf, size_t nbytes)
455{ 458{
456 return write(d, buf, nbytes); 459 return write(d, buf, nbytes);
457} 460}
458 461
459int 462int
460thunk_fsync(int fd) 463thunk_fsync(int fd)
461{ 464{
462 return fsync(fd); 465 return fsync(fd);
463} 466}
464 467
465int 468int
466thunk_mkstemp(char *template) 469thunk_mkstemp(char *template)
467{ 470{
468 return mkstemp(template); 471 return mkstemp(template);
469} 472}
470 473
471int 474int
472thunk_unlink(const char *path) 475thunk_unlink(const char *path)
473{ 476{
474 return unlink(path); 477 return unlink(path);
475} 478}
476 479
477int 480int
478thunk_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) 481thunk_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
479{ 482{
480 return sigaction(sig, act, oact); 483 return sigaction(sig, act, oact);
481} 484}
482 485
483int 486int
484thunk_sigaltstack(const stack_t *ss, stack_t *oss) 487thunk_sigaltstack(const stack_t *ss, stack_t *oss)
485{ 488{
486 return sigaltstack(ss, oss); 489 return sigaltstack(ss, oss);
487} 490}
488 491
489void 492void
490thunk_signal(int sig, void (*func)(int)) 493thunk_signal(int sig, void (*func)(int))
491{ 494{
492 signal(sig, func); 495 signal(sig, func);
493} 496}
494 497
495int 498int
496thunk_sigblock(int sig) 499thunk_sigblock(int sig)
497{ 500{
498 sigset_t set; 501 sigset_t set;
499 502
500 sigemptyset(&set); 503 sigemptyset(&set);
501 sigaddset(&set, sig); 504 sigaddset(&set, sig);
502 return sigprocmask(SIG_BLOCK, &set, NULL); 505 return sigprocmask(SIG_BLOCK, &set, NULL);
503} 506}
504 507
505int 508int
506thunk_sigunblock(int sig) 509thunk_sigunblock(int sig)
507{ 510{
508 sigset_t set; 511 sigset_t set;
509 512
510 sigemptyset(&set); 513 sigemptyset(&set);
511 sigaddset(&set, sig); 514 sigaddset(&set, sig);
512 return sigprocmask(SIG_UNBLOCK, &set, NULL); 515 return sigprocmask(SIG_UNBLOCK, &set, NULL);
513} 516}
514 517
515int 518int
516thunk_sigemptyset(sigset_t *sa_mask) 519thunk_sigemptyset(sigset_t *sa_mask)
517{ 520{
518 return sigemptyset(sa_mask); 521 return sigemptyset(sa_mask);
519} 522}
520 523
521 524
522void 525void
523thunk_sigaddset(sigset_t *sa_mask, int sig) 526thunk_sigaddset(sigset_t *sa_mask, int sig)
524{ 527{
525 int retval; 528 int retval;
526 retval = sigaddset(sa_mask, sig); 529 retval = sigaddset(sa_mask, sig);
527 if (retval < 0) { 530 if (retval < 0) {
528 perror("%s: bad signal added"); 531 perror("%s: bad signal added");
529 abort(); 532 abort();
530 } 533 }
531} 534}
532 535
533int 536int
534thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset) 537thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset)
535{ 538{
536 return sigprocmask(how, set, oset); 539 return sigprocmask(how, set, oset);
537} 540}
538 541
539int 542int
540thunk_atexit(void (*function)(void)) 543thunk_atexit(void (*function)(void))
541{ 544{
542 return atexit(function); 545 return atexit(function);
543} 546}
544 547
545int 548int
546thunk_aio_read(struct aiocb *aiocbp) 549thunk_aio_read(struct aiocb *aiocbp)
547{ 550{
548 return aio_read(aiocbp); 551 return aio_read(aiocbp);
549} 552}
550 553
551int 554int
552thunk_aio_write(struct aiocb *aiocbp) 555thunk_aio_write(struct aiocb *aiocbp)
553{ 556{
554 return aio_write(aiocbp); 557 return aio_write(aiocbp);
555} 558}
556 559
557int 560int
558thunk_aio_error(const struct aiocb *aiocbp) 561thunk_aio_error(const struct aiocb *aiocbp)
559{ 562{
560 return aio_error(aiocbp); 563 return aio_error(aiocbp);
561} 564}
562 565
563int 566int
564thunk_aio_return(struct aiocb *aiocbp) 567thunk_aio_return(struct aiocb *aiocbp)
565{ 568{
566 return aio_return(aiocbp); 569 return aio_return(aiocbp);
567} 570}
568 571
569void * 572void *
570thunk_malloc(size_t len) 573thunk_malloc(size_t len)
571{ 574{
572 return malloc(len); 575 return malloc(len);
573} 576}
574 577
575void 578void
576thunk_free(void *addr) 579thunk_free(void *addr)
577{ 580{
578 free(addr); 581 free(addr);
579} 582}
580 583
581void * 584void *
582thunk_sbrk(intptr_t len) 585thunk_sbrk(intptr_t len)
583{ 586{
584 return sbrk(len); 587 return sbrk(len);
585} 588}
586 589
587void * 590void *
588thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) 591thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
589{ 592{
590 int nflags, nprot; 593 int nflags, nprot;
591 void *a; 594 void *a;
592 595
593 nprot = thunk_to_native_prot(prot); 596 nprot = thunk_to_native_prot(prot);
594 nflags = thunk_to_native_mapflags(flags); 597 nflags = thunk_to_native_mapflags(flags);
595 598
596 a = mmap(addr, len, nprot, nflags, fd, offset); 599 a = mmap(addr, len, nprot, nflags, fd, offset);
597 if (a == (void *)-1) 600 if (a == (void *)-1)
598 perror("mmap"); 601 perror("mmap");
599 return a; 602 return a;
600} 603}
601 604
602int 605int
603thunk_munmap(void *addr, size_t len) 606thunk_munmap(void *addr, size_t len)
604{ 607{
605 return munmap(addr, len); 608 return munmap(addr, len);
606} 609}
607 610
608int 611int
609thunk_mprotect(void *addr, size_t len, int prot) 612thunk_mprotect(void *addr, size_t len, int prot)
610{ 613{
611 int nprot; 614 int nprot;
612 615
613 nprot = thunk_to_native_prot(prot); 616 nprot = thunk_to_native_prot(prot);
614 617
615 return mprotect(addr, len, nprot); 618 return mprotect(addr, len, nprot);
616} 619}
617 620
618int 621int
619thunk_posix_memalign(void **ptr, size_t alignment, size_t size) 622thunk_posix_memalign(void **ptr, size_t alignment, size_t size)
620{ 623{
621 return posix_memalign(ptr, alignment, size); 624 return posix_memalign(ptr, alignment, size);
622} 625}
623 626
624char * 627char *
625thunk_getenv(const char *name) 628thunk_getenv(const char *name)
626{ 629{
627 return getenv(name); 630 return getenv(name);
628} 631}
629 632
630vaddr_t 633vaddr_t
631thunk_get_vm_min_address(void) 634thunk_get_vm_min_address(void)
632{ 635{
633 return VM_MIN_ADDRESS; 636 return VM_MIN_ADDRESS;
634} 637}
635 638
636int 639int
637thunk_idle(void) 640thunk_idle(void)
638{ 641{
639 sigset_t sigmask; 642 sigset_t sigmask;
640 643
641 sigemptyset(&sigmask); 644 sigemptyset(&sigmask);
642 645
643 return sigsuspend(&sigmask); 646 return sigsuspend(&sigmask);
644} 647}
645 648
646int 649int
647thunk_getcpuinfo(char *cp, int *len) 650thunk_getcpuinfo(char *cp, int *len)
648{ 651{
649 ssize_t rlen; 652 ssize_t rlen;
650 int fd; 653 int fd;
651 654
652 fd = open("/proc/cpuinfo", O_RDONLY); 655 fd = open("/proc/cpuinfo", O_RDONLY);
653 if (fd == -1) 656 if (fd == -1)
654 return -1; 657 return -1;
655 rlen = read(fd, cp, *len - 1); 658 rlen = read(fd, cp, *len - 1);
656 close(fd); 659 close(fd);
657 660
658 if (rlen == -1) 661 if (rlen == -1)
659 return -1; 662 return -1;
660 663
661 *len = rlen; 664 *len = rlen;
662 return 0; 665 return 0;
663} 666}