pthread_cancelstub.c revision 1.29 1 /* $NetBSD: pthread_cancelstub.c,v 1.29 2011/01/25 19:13:26 christos Exp $ */
2
3 /*-
4 * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Nathan J. Williams and Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: pthread_cancelstub.c,v 1.29 2011/01/25 19:13:26 christos Exp $");
34
35 #ifndef lint
36
37
38 /*
39 * This is necessary because the names are always weak (they are not
40 * POSIX functions).
41 */
42 #define fsync_range _fsync_range
43 #define pollts _pollts
44
45 /*
46 * XXX this is necessary to get the prototypes for the __sigsuspend14
47 * XXX and __msync13 internal names, instead of the application-visible
48 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty
49 * XXX intimate with libc already.
50 */
51 #define __LIBC12_SOURCE__
52
53 #include <sys/msg.h>
54 #include <sys/types.h>
55 #include <sys/uio.h>
56 #include <sys/wait.h>
57 #include <aio.h>
58 #include <fcntl.h>
59 #include <mqueue.h>
60 #include <poll.h>
61 #include <stdarg.h>
62
63 #define read _read
64 #include <unistd.h>
65 #undef read
66 ssize_t read(int, void *, size_t);
67
68
69 #include <signal.h>
70 #include <sys/mman.h>
71 #include <sys/select.h>
72 #include <sys/socket.h>
73 #include <sys/event.h>
74
75 #include <compat/sys/mman.h>
76 #include <compat/sys/poll.h>
77 #include <compat/sys/select.h>
78 #include <compat/sys/event.h>
79 #include <compat/sys/wait.h>
80 #include <compat/include/mqueue.h>
81 #include <compat/include/signal.h>
82
83 #include "pthread.h"
84 #include "pthread_int.h"
85
86 int pthread__cancel_stub_binder;
87
88 int _sys_accept(int, struct sockaddr *, socklen_t *);
89 int _sys___aio_suspend50(const struct aiocb * const [], int,
90 const struct timespec *);
91 int __aio_suspend50(const struct aiocb * const [], int,
92 const struct timespec *);
93 int _sys_close(int);
94 int _sys_connect(int, const struct sockaddr *, socklen_t);
95 int _sys_fcntl(int, int, ...);
96 int _sys_fdatasync(int);
97 int _sys_fsync(int);
98 int _sys_fsync_range(int, int, off_t, off_t);
99 int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
100 size_t, const struct timespec *);
101 int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
102 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
103 int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
104 const struct timespec *);
105 ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
106 const struct timespec *);
107 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
108 int _sys_msgsnd(int, const void *, size_t, int);
109 int _sys___msync13(void *, size_t, int);
110 int _sys___nanosleep50(const struct timespec *, struct timespec *);
111 int __nanosleep50(const struct timespec *, struct timespec *);
112 int _sys_open(const char *, int, ...);
113 int _sys_poll(struct pollfd *, nfds_t, int);
114 int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
115 const sigset_t *);
116 ssize_t _sys_pread(int, void *, size_t, off_t);
117 int _sys___pselect50(int, fd_set *, fd_set *, fd_set *,
118 const struct timespec *, const sigset_t *);
119 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
120 ssize_t _sys_read(int, void *, size_t);
121 ssize_t _sys_readv(int, const struct iovec *, int);
122 int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
123 int _sys___wait450(pid_t, int *, int, struct rusage *);
124 ssize_t _sys_write(int, const void *, size_t);
125 ssize_t _sys_writev(int, const struct iovec *, int);
126 int _sys___sigsuspend14(const sigset_t *);
127 int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
128 struct timespec * __restrict);
129 int __sigsuspend14(const sigset_t *);
130
131 #define TESTCANCEL(id) do { \
132 if (__predict_false((id)->pt_cancel)) \
133 pthread__cancelled(); \
134 } while (/*CONSTCOND*/0)
135
136
137 int
138 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
139 {
140 int retval;
141 pthread_t self;
142
143 self = pthread__self();
144 TESTCANCEL(self);
145 retval = _sys_accept(s, addr, addrlen);
146 TESTCANCEL(self);
147
148 return retval;
149 }
150
151 int
152 __aio_suspend50(const struct aiocb * const list[], int nent,
153 const struct timespec *timeout)
154 {
155 int retval;
156 pthread_t self;
157
158 self = pthread__self();
159 TESTCANCEL(self);
160 retval = _sys___aio_suspend50(list, nent, timeout);
161 TESTCANCEL(self);
162
163 return retval;
164 }
165
166 int
167 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
168 size_t nrev, const struct timespec *ts)
169 {
170 int retval;
171 pthread_t self;
172
173 self = pthread__self();
174 TESTCANCEL(self);
175 retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
176 TESTCANCEL(self);
177
178 return retval;
179 }
180
181 int
182 close(int d)
183 {
184 int retval;
185 pthread_t self;
186
187 self = pthread__self();
188 TESTCANCEL(self);
189 retval = _sys_close(d);
190 TESTCANCEL(self);
191
192 return retval;
193 }
194
195 int
196 connect(int s, const struct sockaddr *addr, socklen_t namelen)
197 {
198 int retval;
199 pthread_t self;
200
201 self = pthread__self();
202 TESTCANCEL(self);
203 retval = _sys_connect(s, addr, namelen);
204 TESTCANCEL(self);
205
206 return retval;
207 }
208
209 int
210 fcntl(int fd, int cmd, ...)
211 {
212 int retval;
213 pthread_t self;
214 va_list ap;
215
216 self = pthread__self();
217 TESTCANCEL(self);
218 va_start(ap, cmd);
219 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
220 va_end(ap);
221 TESTCANCEL(self);
222
223 return retval;
224 }
225
226 int
227 fdatasync(int d)
228 {
229 int retval;
230 pthread_t self;
231
232 self = pthread__self();
233 TESTCANCEL(self);
234 retval = _sys_fdatasync(d);
235 TESTCANCEL(self);
236
237 return retval;
238 }
239
240 int
241 fsync(int d)
242 {
243 int retval;
244 pthread_t self;
245
246 self = pthread__self();
247 TESTCANCEL(self);
248 retval = _sys_fsync(d);
249 TESTCANCEL(self);
250
251 return retval;
252 }
253
254 int
255 fsync_range(int d, int f, off_t s, off_t e)
256 {
257 int retval;
258 pthread_t self;
259
260 self = pthread__self();
261 TESTCANCEL(self);
262 retval = _sys_fsync_range(d, f, s, e);
263 TESTCANCEL(self);
264
265 return retval;
266 }
267
268 int
269 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
270 {
271 int retval;
272 pthread_t self;
273
274 self = pthread__self();
275 TESTCANCEL(self);
276 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
277 TESTCANCEL(self);
278
279 return retval;
280 }
281
282 ssize_t
283 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
284 {
285 ssize_t retval;
286 pthread_t self;
287
288 self = pthread__self();
289 TESTCANCEL(self);
290 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
291 TESTCANCEL(self);
292
293 return retval;
294 }
295
296 int
297 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
298 unsigned msg_prio, const struct timespec *abst)
299 {
300 int retval;
301 pthread_t self;
302
303 self = pthread__self();
304 TESTCANCEL(self);
305 retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
306 TESTCANCEL(self);
307
308 return retval;
309 }
310
311 ssize_t
312 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
313 const struct timespec *abst)
314 {
315 ssize_t retval;
316 pthread_t self;
317
318 self = pthread__self();
319 TESTCANCEL(self);
320 retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
321 TESTCANCEL(self);
322
323 return retval;
324 }
325
326 ssize_t
327 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
328 {
329 ssize_t retval;
330 pthread_t self;
331
332 self = pthread__self();
333 TESTCANCEL(self);
334 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
335 TESTCANCEL(self);
336
337 return retval;
338 }
339
340 int
341 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
342 {
343 int retval;
344 pthread_t self;
345
346 self = pthread__self();
347 TESTCANCEL(self);
348 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
349 TESTCANCEL(self);
350
351 return retval;
352 }
353
354 int
355 __msync13(void *addr, size_t len, int flags)
356 {
357 int retval;
358 pthread_t self;
359
360 self = pthread__self();
361 TESTCANCEL(self);
362 retval = _sys___msync13(addr, len, flags);
363 TESTCANCEL(self);
364
365 return retval;
366 }
367
368 int
369 open(const char *path, int flags, ...)
370 {
371 int retval;
372 pthread_t self;
373 va_list ap;
374
375 self = pthread__self();
376 TESTCANCEL(self);
377 va_start(ap, flags);
378 retval = _sys_open(path, flags, va_arg(ap, mode_t));
379 va_end(ap);
380 TESTCANCEL(self);
381
382 return retval;
383 }
384
385 int
386 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
387 {
388 int retval;
389 pthread_t self;
390
391 self = pthread__self();
392 TESTCANCEL(self);
393 /*
394 * For now, just nanosleep. In the future, maybe pass a ucontext_t
395 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
396 */
397 retval = _sys___nanosleep50(rqtp, rmtp);
398 TESTCANCEL(self);
399
400 return retval;
401 }
402
403 int
404 poll(struct pollfd *fds, nfds_t nfds, int timeout)
405 {
406 int retval;
407 pthread_t self;
408
409 self = pthread__self();
410 TESTCANCEL(self);
411 retval = _sys_poll(fds, nfds, timeout);
412 TESTCANCEL(self);
413
414 return retval;
415 }
416
417 int
418 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
419 const sigset_t *sigmask)
420 {
421 int retval;
422 pthread_t self;
423
424 self = pthread__self();
425 TESTCANCEL(self);
426 retval = _sys___pollts50(fds, nfds, ts, sigmask);
427 TESTCANCEL(self);
428
429 return retval;
430 }
431
432 ssize_t
433 pread(int d, void *buf, size_t nbytes, off_t offset)
434 {
435 ssize_t retval;
436 pthread_t self;
437
438 self = pthread__self();
439 TESTCANCEL(self);
440 retval = _sys_pread(d, buf, nbytes, offset);
441 TESTCANCEL(self);
442
443 return retval;
444 }
445
446 int
447 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
448 const struct timespec *timeout, const sigset_t *sigmask)
449 {
450 int retval;
451 pthread_t self;
452
453 self = pthread__self();
454 TESTCANCEL(self);
455 retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
456 sigmask);
457 TESTCANCEL(self);
458
459 return retval;
460 }
461
462 ssize_t
463 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
464 {
465 ssize_t retval;
466 pthread_t self;
467
468 self = pthread__self();
469 TESTCANCEL(self);
470 retval = _sys_pwrite(d, buf, nbytes, offset);
471 TESTCANCEL(self);
472
473 return retval;
474 }
475
476 ssize_t
477 read(int d, void *buf, size_t nbytes)
478 {
479 ssize_t retval;
480 pthread_t self;
481
482 #ifdef __ssp_check
483 __ssp_check(buf, nbytes, __ssp_bos0);
484 #endif
485
486 self = pthread__self();
487 TESTCANCEL(self);
488 retval = _sys_read(d, buf, nbytes);
489 TESTCANCEL(self);
490
491 return retval;
492 }
493
494 ssize_t
495 readv(int d, const struct iovec *iov, int iovcnt)
496 {
497 ssize_t retval;
498 pthread_t self;
499
500 self = pthread__self();
501 TESTCANCEL(self);
502 retval = _sys_readv(d, iov, iovcnt);
503 TESTCANCEL(self);
504
505 return retval;
506 }
507
508 int
509 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
510 struct timeval *timeout)
511 {
512 int retval;
513 pthread_t self;
514
515 self = pthread__self();
516 TESTCANCEL(self);
517 retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
518 TESTCANCEL(self);
519
520 return retval;
521 }
522
523 pid_t
524 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
525 {
526 pid_t retval;
527 pthread_t self;
528
529 self = pthread__self();
530 TESTCANCEL(self);
531 retval = _sys___wait450(wpid, status, options, rusage);
532 TESTCANCEL(self);
533
534 return retval;
535 }
536
537 ssize_t
538 write(int d, const void *buf, size_t nbytes)
539 {
540 ssize_t retval;
541 pthread_t self;
542
543 self = pthread__self();
544 TESTCANCEL(self);
545 retval = _sys_write(d, buf, nbytes);
546 TESTCANCEL(self);
547
548 return retval;
549 }
550
551 ssize_t
552 writev(int d, const struct iovec *iov, int iovcnt)
553 {
554 ssize_t retval;
555 pthread_t self;
556
557 self = pthread__self();
558 TESTCANCEL(self);
559 retval = _sys_writev(d, iov, iovcnt);
560 TESTCANCEL(self);
561
562 return retval;
563 }
564
565 int
566 __sigsuspend14(const sigset_t *sigmask)
567 {
568 pthread_t self;
569 int retval;
570
571 self = pthread__self();
572 TESTCANCEL(self);
573 retval = _sys___sigsuspend14(sigmask);
574 TESTCANCEL(self);
575
576 return retval;
577 }
578
579 int
580 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
581 const struct timespec * __restrict timeout)
582 {
583 pthread_t self;
584 int retval;
585 struct timespec tout, *tp;
586 if (timeout) {
587 tout = *timeout;
588 tp = &tout;
589 } else
590 tp = NULL;
591
592 self = pthread__self();
593 TESTCANCEL(self);
594 retval = ____sigtimedwait50(set, info, tp);
595 TESTCANCEL(self);
596
597 return retval;
598 }
599
600 __strong_alias(_close, close)
601 __strong_alias(_fcntl, fcntl)
602 __strong_alias(_fdatasync, fdatasync)
603 __strong_alias(_fsync, fsync)
604 __weak_alias(fsync_range, _fsync_range)
605 __strong_alias(_mq_send, mq_send)
606 __strong_alias(_mq_receive, mq_receive)
607 __strong_alias(_msgrcv, msgrcv)
608 __strong_alias(_msgsnd, msgsnd)
609 __strong_alias(___msync13, __msync13)
610 __strong_alias(___nanosleep50, __nanosleep50)
611 __strong_alias(_open, open)
612 __strong_alias(_poll, poll)
613 __strong_alias(_pread, pread)
614 __strong_alias(_pwrite, pwrite)
615 __strong_alias(_read, read)
616 __strong_alias(_readv, readv)
617 __strong_alias(_write, write)
618 __strong_alias(_writev, writev)
619
620 #endif /* !lint */
621