pthread_cancelstub.c revision 1.31 1 /* $NetBSD: pthread_cancelstub.c,v 1.31 2011/01/26 18:48:57 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.31 2011/01/26 18:48:57 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 #define __ssp_weak_name(fun) _cancelstub_ ## fun
54
55 #include <sys/msg.h>
56 #include <sys/types.h>
57 #include <sys/uio.h>
58 #include <sys/wait.h>
59 #include <aio.h>
60 #include <fcntl.h>
61 #include <mqueue.h>
62 #include <poll.h>
63 #include <stdarg.h>
64 #include <unistd.h>
65
66 #include <signal.h>
67 #include <sys/mman.h>
68 #include <sys/select.h>
69 #include <sys/socket.h>
70 #include <sys/event.h>
71
72 #include <compat/sys/mman.h>
73 #include <compat/sys/poll.h>
74 #include <compat/sys/select.h>
75 #include <compat/sys/event.h>
76 #include <compat/sys/wait.h>
77 #include <compat/include/mqueue.h>
78 #include <compat/include/signal.h>
79
80 #include "pthread.h"
81 #include "pthread_int.h"
82
83 int pthread__cancel_stub_binder;
84
85 int _sys_accept(int, struct sockaddr *, socklen_t *);
86 int _sys___aio_suspend50(const struct aiocb * const [], int,
87 const struct timespec *);
88 int __aio_suspend50(const struct aiocb * const [], int,
89 const struct timespec *);
90 int _sys_close(int);
91 int _sys_connect(int, const struct sockaddr *, socklen_t);
92 int _sys_fcntl(int, int, ...);
93 int _sys_fdatasync(int);
94 int _sys_fsync(int);
95 int _sys_fsync_range(int, int, off_t, off_t);
96 int _sys___kevent50(int, const struct kevent *, size_t, struct kevent *,
97 size_t, const struct timespec *);
98 int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
99 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
100 int _sys___mq_timedsend50(mqd_t, const char *, size_t, unsigned,
101 const struct timespec *);
102 ssize_t _sys___mq_timedreceive50(mqd_t, char *, size_t, unsigned *,
103 const struct timespec *);
104 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
105 int _sys_msgsnd(int, const void *, size_t, int);
106 int _sys___msync13(void *, size_t, int);
107 int _sys___nanosleep50(const struct timespec *, struct timespec *);
108 int __nanosleep50(const struct timespec *, struct timespec *);
109 int _sys_open(const char *, int, ...);
110 int _sys_poll(struct pollfd *, nfds_t, int);
111 int _sys___pollts50(struct pollfd *, nfds_t, const struct timespec *,
112 const sigset_t *);
113 ssize_t _sys_pread(int, void *, size_t, off_t);
114 int _sys___pselect50(int, fd_set *, fd_set *, fd_set *,
115 const struct timespec *, const sigset_t *);
116 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
117 ssize_t _sys_read(int, void *, size_t);
118 ssize_t _sys_readv(int, const struct iovec *, int);
119 int _sys___select50(int, fd_set *, fd_set *, fd_set *, struct timeval *);
120 int _sys___wait450(pid_t, int *, int, struct rusage *);
121 ssize_t _sys_write(int, const void *, size_t);
122 ssize_t _sys_writev(int, const struct iovec *, int);
123 int _sys___sigsuspend14(const sigset_t *);
124 int ____sigtimedwait50(const sigset_t * __restrict, siginfo_t * __restrict,
125 struct timespec * __restrict);
126 int __sigsuspend14(const sigset_t *);
127
128 #define TESTCANCEL(id) do { \
129 if (__predict_false((id)->pt_cancel)) \
130 pthread__cancelled(); \
131 } while (/*CONSTCOND*/0)
132
133
134 int
135 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
136 {
137 int retval;
138 pthread_t self;
139
140 self = pthread__self();
141 TESTCANCEL(self);
142 retval = _sys_accept(s, addr, addrlen);
143 TESTCANCEL(self);
144
145 return retval;
146 }
147
148 int
149 __aio_suspend50(const struct aiocb * const list[], int nent,
150 const struct timespec *timeout)
151 {
152 int retval;
153 pthread_t self;
154
155 self = pthread__self();
156 TESTCANCEL(self);
157 retval = _sys___aio_suspend50(list, nent, timeout);
158 TESTCANCEL(self);
159
160 return retval;
161 }
162
163 int
164 __kevent50(int fd, const struct kevent *ev, size_t nev, struct kevent *rev,
165 size_t nrev, const struct timespec *ts)
166 {
167 int retval;
168 pthread_t self;
169
170 self = pthread__self();
171 TESTCANCEL(self);
172 retval = _sys___kevent50(fd, ev, nev, rev, nrev, ts);
173 TESTCANCEL(self);
174
175 return retval;
176 }
177
178 int
179 close(int d)
180 {
181 int retval;
182 pthread_t self;
183
184 self = pthread__self();
185 TESTCANCEL(self);
186 retval = _sys_close(d);
187 TESTCANCEL(self);
188
189 return retval;
190 }
191
192 int
193 connect(int s, const struct sockaddr *addr, socklen_t namelen)
194 {
195 int retval;
196 pthread_t self;
197
198 self = pthread__self();
199 TESTCANCEL(self);
200 retval = _sys_connect(s, addr, namelen);
201 TESTCANCEL(self);
202
203 return retval;
204 }
205
206 int
207 fcntl(int fd, int cmd, ...)
208 {
209 int retval;
210 pthread_t self;
211 va_list ap;
212
213 self = pthread__self();
214 TESTCANCEL(self);
215 va_start(ap, cmd);
216 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
217 va_end(ap);
218 TESTCANCEL(self);
219
220 return retval;
221 }
222
223 int
224 fdatasync(int d)
225 {
226 int retval;
227 pthread_t self;
228
229 self = pthread__self();
230 TESTCANCEL(self);
231 retval = _sys_fdatasync(d);
232 TESTCANCEL(self);
233
234 return retval;
235 }
236
237 int
238 fsync(int d)
239 {
240 int retval;
241 pthread_t self;
242
243 self = pthread__self();
244 TESTCANCEL(self);
245 retval = _sys_fsync(d);
246 TESTCANCEL(self);
247
248 return retval;
249 }
250
251 int
252 fsync_range(int d, int f, off_t s, off_t e)
253 {
254 int retval;
255 pthread_t self;
256
257 self = pthread__self();
258 TESTCANCEL(self);
259 retval = _sys_fsync_range(d, f, s, e);
260 TESTCANCEL(self);
261
262 return retval;
263 }
264
265 int
266 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
267 {
268 int retval;
269 pthread_t self;
270
271 self = pthread__self();
272 TESTCANCEL(self);
273 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
274 TESTCANCEL(self);
275
276 return retval;
277 }
278
279 ssize_t
280 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
281 {
282 ssize_t retval;
283 pthread_t self;
284
285 self = pthread__self();
286 TESTCANCEL(self);
287 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
288 TESTCANCEL(self);
289
290 return retval;
291 }
292
293 int
294 __mq_timedsend50(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
295 unsigned msg_prio, const struct timespec *abst)
296 {
297 int retval;
298 pthread_t self;
299
300 self = pthread__self();
301 TESTCANCEL(self);
302 retval = _sys___mq_timedsend50(mqdes, msg_ptr, msg_len, msg_prio, abst);
303 TESTCANCEL(self);
304
305 return retval;
306 }
307
308 ssize_t
309 __mq_timedreceive50(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
310 const struct timespec *abst)
311 {
312 ssize_t retval;
313 pthread_t self;
314
315 self = pthread__self();
316 TESTCANCEL(self);
317 retval = _sys___mq_timedreceive50(mqdes, msg_ptr, msg_len, msg_prio, abst);
318 TESTCANCEL(self);
319
320 return retval;
321 }
322
323 ssize_t
324 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
325 {
326 ssize_t retval;
327 pthread_t self;
328
329 self = pthread__self();
330 TESTCANCEL(self);
331 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
332 TESTCANCEL(self);
333
334 return retval;
335 }
336
337 int
338 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
339 {
340 int retval;
341 pthread_t self;
342
343 self = pthread__self();
344 TESTCANCEL(self);
345 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
346 TESTCANCEL(self);
347
348 return retval;
349 }
350
351 int
352 __msync13(void *addr, size_t len, int flags)
353 {
354 int retval;
355 pthread_t self;
356
357 self = pthread__self();
358 TESTCANCEL(self);
359 retval = _sys___msync13(addr, len, flags);
360 TESTCANCEL(self);
361
362 return retval;
363 }
364
365 int
366 open(const char *path, int flags, ...)
367 {
368 int retval;
369 pthread_t self;
370 va_list ap;
371
372 self = pthread__self();
373 TESTCANCEL(self);
374 va_start(ap, flags);
375 retval = _sys_open(path, flags, va_arg(ap, mode_t));
376 va_end(ap);
377 TESTCANCEL(self);
378
379 return retval;
380 }
381
382 int
383 __nanosleep50(const struct timespec *rqtp, struct timespec *rmtp)
384 {
385 int retval;
386 pthread_t self;
387
388 self = pthread__self();
389 TESTCANCEL(self);
390 /*
391 * For now, just nanosleep. In the future, maybe pass a ucontext_t
392 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
393 */
394 retval = _sys___nanosleep50(rqtp, rmtp);
395 TESTCANCEL(self);
396
397 return retval;
398 }
399
400 int
401 poll(struct pollfd *fds, nfds_t nfds, int timeout)
402 {
403 int retval;
404 pthread_t self;
405
406 self = pthread__self();
407 TESTCANCEL(self);
408 retval = _sys_poll(fds, nfds, timeout);
409 TESTCANCEL(self);
410
411 return retval;
412 }
413
414 int
415 __pollts50(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
416 const sigset_t *sigmask)
417 {
418 int retval;
419 pthread_t self;
420
421 self = pthread__self();
422 TESTCANCEL(self);
423 retval = _sys___pollts50(fds, nfds, ts, sigmask);
424 TESTCANCEL(self);
425
426 return retval;
427 }
428
429 ssize_t
430 pread(int d, void *buf, size_t nbytes, off_t offset)
431 {
432 ssize_t retval;
433 pthread_t self;
434
435 self = pthread__self();
436 TESTCANCEL(self);
437 retval = _sys_pread(d, buf, nbytes, offset);
438 TESTCANCEL(self);
439
440 return retval;
441 }
442
443 int
444 __pselect50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
445 const struct timespec *timeout, const sigset_t *sigmask)
446 {
447 int retval;
448 pthread_t self;
449
450 self = pthread__self();
451 TESTCANCEL(self);
452 retval = _sys___pselect50(nfds, readfds, writefds, exceptfds, timeout,
453 sigmask);
454 TESTCANCEL(self);
455
456 return retval;
457 }
458
459 ssize_t
460 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
461 {
462 ssize_t retval;
463 pthread_t self;
464
465 self = pthread__self();
466 TESTCANCEL(self);
467 retval = _sys_pwrite(d, buf, nbytes, offset);
468 TESTCANCEL(self);
469
470 return retval;
471 }
472
473 #if _FORTIFY_SOURCE > 0
474 #define STUB(fun) __ssp_weak_name(fun)
475 ssize_t _sys_readlink(const char * __restrict, char * __restrict, size_t);
476 ssize_t
477 STUB(readlink)(const char * __restrict path, char * __restrict buf,
478 size_t bufsiz)
479 {
480 return _sys_readlink(path, buf, bufsiz);
481 }
482
483 char *_sys_getcwd(char *, size_t);
484 char *
485 STUB(getcwd)(char *buf, size_t size)
486 {
487 return _sys_getcwd(buf, size);
488 }
489 #else
490 #define STUB(fun) fun
491 #endif
492
493 ssize_t
494 STUB(read)(int d, void *buf, size_t nbytes)
495 {
496 ssize_t retval;
497 pthread_t self;
498
499 self = pthread__self();
500 TESTCANCEL(self);
501 retval = _sys_read(d, buf, nbytes);
502 TESTCANCEL(self);
503
504 return retval;
505 }
506
507 ssize_t
508 readv(int d, const struct iovec *iov, int iovcnt)
509 {
510 ssize_t retval;
511 pthread_t self;
512
513 self = pthread__self();
514 TESTCANCEL(self);
515 retval = _sys_readv(d, iov, iovcnt);
516 TESTCANCEL(self);
517
518 return retval;
519 }
520
521 int
522 __select50(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
523 struct timeval *timeout)
524 {
525 int retval;
526 pthread_t self;
527
528 self = pthread__self();
529 TESTCANCEL(self);
530 retval = _sys___select50(nfds, readfds, writefds, exceptfds, timeout);
531 TESTCANCEL(self);
532
533 return retval;
534 }
535
536 pid_t
537 __wait450(pid_t wpid, int *status, int options, struct rusage *rusage)
538 {
539 pid_t retval;
540 pthread_t self;
541
542 self = pthread__self();
543 TESTCANCEL(self);
544 retval = _sys___wait450(wpid, status, options, rusage);
545 TESTCANCEL(self);
546
547 return retval;
548 }
549
550 ssize_t
551 write(int d, const void *buf, size_t nbytes)
552 {
553 ssize_t retval;
554 pthread_t self;
555
556 self = pthread__self();
557 TESTCANCEL(self);
558 retval = _sys_write(d, buf, nbytes);
559 TESTCANCEL(self);
560
561 return retval;
562 }
563
564 ssize_t
565 writev(int d, const struct iovec *iov, int iovcnt)
566 {
567 ssize_t retval;
568 pthread_t self;
569
570 self = pthread__self();
571 TESTCANCEL(self);
572 retval = _sys_writev(d, iov, iovcnt);
573 TESTCANCEL(self);
574
575 return retval;
576 }
577
578 int
579 __sigsuspend14(const sigset_t *sigmask)
580 {
581 pthread_t self;
582 int retval;
583
584 self = pthread__self();
585 TESTCANCEL(self);
586 retval = _sys___sigsuspend14(sigmask);
587 TESTCANCEL(self);
588
589 return retval;
590 }
591
592 int
593 __sigtimedwait50(const sigset_t * __restrict set, siginfo_t * __restrict info,
594 const struct timespec * __restrict timeout)
595 {
596 pthread_t self;
597 int retval;
598 struct timespec tout, *tp;
599 if (timeout) {
600 tout = *timeout;
601 tp = &tout;
602 } else
603 tp = NULL;
604
605 self = pthread__self();
606 TESTCANCEL(self);
607 retval = ____sigtimedwait50(set, info, tp);
608 TESTCANCEL(self);
609
610 return retval;
611 }
612
613 __strong_alias(_close, close)
614 __strong_alias(_fcntl, fcntl)
615 __strong_alias(_fdatasync, fdatasync)
616 __strong_alias(_fsync, fsync)
617 __weak_alias(fsync_range, _fsync_range)
618 __strong_alias(_mq_send, mq_send)
619 __strong_alias(_mq_receive, mq_receive)
620 __strong_alias(_msgrcv, msgrcv)
621 __strong_alias(_msgsnd, msgsnd)
622 __strong_alias(___msync13, __msync13)
623 __strong_alias(___nanosleep50, __nanosleep50)
624 __strong_alias(_open, open)
625 __strong_alias(_poll, poll)
626 __strong_alias(_pread, pread)
627 __strong_alias(_pwrite, pwrite)
628 __strong_alias(_read, read)
629 __strong_alias(_readv, readv)
630 __strong_alias(_write, write)
631 __strong_alias(_writev, writev)
632
633 #endif /* !lint */
634