pthread_cancelstub.c revision 1.21 1 /* $NetBSD: pthread_cancelstub.c,v 1.21 2008/09/29 08:48:15 ad 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.21 2008/09/29 08:48:15 ad 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 #include <unistd.h>
63
64 #include <signal.h>
65 #include <sys/mman.h>
66 #include <sys/select.h>
67 #include <sys/socket.h>
68
69 #include <compat/sys/mman.h>
70
71 #include "pthread.h"
72 #include "pthread_int.h"
73
74 int pthread__cancel_stub_binder;
75
76 int _sys_accept(int, struct sockaddr *, socklen_t *);
77 int _sys_aio_suspend(const struct aiocb * const [], int,
78 const struct timespec *);
79 int _sys_close(int);
80 int _sys_connect(int, const struct sockaddr *, socklen_t);
81 int _sys_fcntl(int, int, ...);
82 int _sys_fdatasync(int);
83 int _sys_fsync(int);
84 int _sys_fsync_range(int, int, off_t, off_t);
85 int _sys_mq_send(mqd_t, const char *, size_t, unsigned);
86 ssize_t _sys_mq_receive(mqd_t, char *, size_t, unsigned *);
87 int _sys_mq_timedsend(mqd_t, const char *, size_t, unsigned,
88 const struct timespec *);
89 ssize_t _sys_mq_timedreceive(mqd_t, char *, size_t, unsigned *,
90 const struct timespec *);
91 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
92 int _sys_msgsnd(int, const void *, size_t, int);
93 int _sys___msync13(void *, size_t, int);
94 int _sys_open(const char *, int, ...);
95 int _sys_poll(struct pollfd *, nfds_t, int);
96 int _sys_pollts(struct pollfd *, nfds_t, const struct timespec *,
97 const sigset_t *);
98 ssize_t _sys_pread(int, void *, size_t, off_t);
99 int _sys_pselect(int, fd_set *, fd_set *, fd_set *,
100 const struct timespec *, const sigset_t *);
101 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
102 ssize_t _sys_read(int, void *, size_t);
103 ssize_t _sys_readv(int, const struct iovec *, int);
104 int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
105 int _sys_wait4(pid_t, int *, int, struct rusage *);
106 ssize_t _sys_write(int, const void *, size_t);
107 ssize_t _sys_writev(int, const struct iovec *, int);
108 int _sys___sigsuspend14(const sigset_t *);
109 int _sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict,
110 const struct timespec * __restrict);
111 int __sigsuspend14(const sigset_t *);
112
113 #define TESTCANCEL(id) do { \
114 if (__predict_false((id)->pt_cancel)) \
115 pthread__cancelled(); \
116 } while (/*CONSTCOND*/0)
117
118
119 int
120 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
121 {
122 int retval;
123 pthread_t self;
124
125 self = pthread__self();
126 TESTCANCEL(self);
127 retval = _sys_accept(s, addr, addrlen);
128 TESTCANCEL(self);
129
130 return retval;
131 }
132
133 int
134 close(int d)
135 {
136 int retval;
137 pthread_t self;
138
139 self = pthread__self();
140 TESTCANCEL(self);
141 retval = _sys_close(d);
142 TESTCANCEL(self);
143
144 return retval;
145 }
146
147 int
148 connect(int s, const struct sockaddr *addr, socklen_t namelen)
149 {
150 int retval;
151 pthread_t self;
152
153 self = pthread__self();
154 TESTCANCEL(self);
155 retval = _sys_connect(s, addr, namelen);
156 TESTCANCEL(self);
157
158 return retval;
159 }
160
161 int
162 fcntl(int fd, int cmd, ...)
163 {
164 int retval;
165 pthread_t self;
166 va_list ap;
167
168 self = pthread__self();
169 TESTCANCEL(self);
170 va_start(ap, cmd);
171 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
172 va_end(ap);
173 TESTCANCEL(self);
174
175 return retval;
176 }
177
178 int
179 fdatasync(int d)
180 {
181 int retval;
182 pthread_t self;
183
184 self = pthread__self();
185 TESTCANCEL(self);
186 retval = _sys_fdatasync(d);
187 TESTCANCEL(self);
188
189 return retval;
190 }
191
192 int
193 fsync(int d)
194 {
195 int retval;
196 pthread_t self;
197
198 self = pthread__self();
199 TESTCANCEL(self);
200 retval = _sys_fsync(d);
201 TESTCANCEL(self);
202
203 return retval;
204 }
205
206 int
207 fsync_range(int d, int f, off_t s, off_t e)
208 {
209 int retval;
210 pthread_t self;
211
212 self = pthread__self();
213 TESTCANCEL(self);
214 retval = _sys_fsync_range(d, f, s, e);
215 TESTCANCEL(self);
216
217 return retval;
218 }
219
220 ssize_t
221 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
222 {
223 ssize_t retval;
224 pthread_t self;
225
226 self = pthread__self();
227 TESTCANCEL(self);
228 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
229 TESTCANCEL(self);
230
231 return retval;
232 }
233
234 int
235 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
236 {
237 int retval;
238 pthread_t self;
239
240 self = pthread__self();
241 TESTCANCEL(self);
242 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
243 TESTCANCEL(self);
244
245 return retval;
246 }
247
248 int
249 __msync13(void *addr, size_t len, int flags)
250 {
251 int retval;
252 pthread_t self;
253
254 self = pthread__self();
255 TESTCANCEL(self);
256 retval = _sys___msync13(addr, len, flags);
257 TESTCANCEL(self);
258
259 return retval;
260 }
261
262 int
263 open(const char *path, int flags, ...)
264 {
265 int retval;
266 pthread_t self;
267 va_list ap;
268
269 self = pthread__self();
270 TESTCANCEL(self);
271 va_start(ap, flags);
272 retval = _sys_open(path, flags, va_arg(ap, mode_t));
273 va_end(ap);
274 TESTCANCEL(self);
275
276 return retval;
277 }
278
279 int
280 poll(struct pollfd *fds, nfds_t nfds, int timeout)
281 {
282 int retval;
283 pthread_t self;
284
285 self = pthread__self();
286 TESTCANCEL(self);
287 retval = _sys_poll(fds, nfds, timeout);
288 TESTCANCEL(self);
289
290 return retval;
291 }
292
293 int
294 pollts(struct pollfd *fds, nfds_t nfds, const struct timespec *ts,
295 const sigset_t *sigmask)
296 {
297 int retval;
298 pthread_t self;
299
300 self = pthread__self();
301 TESTCANCEL(self);
302 retval = _sys_pollts(fds, nfds, ts, sigmask);
303 TESTCANCEL(self);
304
305 return retval;
306 }
307
308 ssize_t
309 pread(int d, void *buf, size_t nbytes, off_t offset)
310 {
311 ssize_t retval;
312 pthread_t self;
313
314 self = pthread__self();
315 TESTCANCEL(self);
316 retval = _sys_pread(d, buf, nbytes, offset);
317 TESTCANCEL(self);
318
319 return retval;
320 }
321
322 int
323 pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
324 const struct timespec *timeout, const sigset_t *sigmask)
325 {
326 int retval;
327 pthread_t self;
328
329 self = pthread__self();
330 TESTCANCEL(self);
331 retval = _sys_pselect(nfds, readfds, writefds, exceptfds, timeout,
332 sigmask);
333 TESTCANCEL(self);
334
335 return retval;
336 }
337
338 ssize_t
339 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
340 {
341 ssize_t retval;
342 pthread_t self;
343
344 self = pthread__self();
345 TESTCANCEL(self);
346 retval = _sys_pwrite(d, buf, nbytes, offset);
347 TESTCANCEL(self);
348
349 return retval;
350 }
351
352 #ifdef _FORTIFY_SOURCE
353 #undef read
354 #endif
355
356 ssize_t
357 read(int d, void *buf, size_t nbytes)
358 {
359 ssize_t retval;
360 pthread_t self;
361
362 self = pthread__self();
363 TESTCANCEL(self);
364 retval = _sys_read(d, buf, nbytes);
365 TESTCANCEL(self);
366
367 return retval;
368 }
369
370 ssize_t
371 readv(int d, const struct iovec *iov, int iovcnt)
372 {
373 ssize_t retval;
374 pthread_t self;
375
376 self = pthread__self();
377 TESTCANCEL(self);
378 retval = _sys_readv(d, iov, iovcnt);
379 TESTCANCEL(self);
380
381 return retval;
382 }
383
384 int
385 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
386 struct timeval *timeout)
387 {
388 int retval;
389 pthread_t self;
390
391 self = pthread__self();
392 TESTCANCEL(self);
393 retval = _sys_select(nfds, readfds, writefds, exceptfds, timeout);
394 TESTCANCEL(self);
395
396 return retval;
397 }
398
399 pid_t
400 wait4(pid_t wpid, int *status, int options, struct rusage *rusage)
401 {
402 pid_t retval;
403 pthread_t self;
404
405 self = pthread__self();
406 TESTCANCEL(self);
407 retval = _sys_wait4(wpid, status, options, rusage);
408 TESTCANCEL(self);
409
410 return retval;
411 }
412
413 ssize_t
414 write(int d, const void *buf, size_t nbytes)
415 {
416 ssize_t retval;
417 pthread_t self;
418
419 self = pthread__self();
420 TESTCANCEL(self);
421 retval = _sys_write(d, buf, nbytes);
422 TESTCANCEL(self);
423
424 return retval;
425 }
426
427 ssize_t
428 writev(int d, const struct iovec *iov, int iovcnt)
429 {
430 ssize_t retval;
431 pthread_t self;
432
433 self = pthread__self();
434 TESTCANCEL(self);
435 retval = _sys_writev(d, iov, iovcnt);
436 TESTCANCEL(self);
437
438 return retval;
439 }
440
441 int
442 __sigsuspend14(const sigset_t *sigmask)
443 {
444 pthread_t self;
445 int retval;
446
447 self = pthread__self();
448 TESTCANCEL(self);
449 retval = _sys___sigsuspend14(sigmask);
450 TESTCANCEL(self);
451
452 return retval;
453 }
454
455 int
456 sigtimedwait(const sigset_t * __restrict set, siginfo_t * __restrict info,
457 const struct timespec * __restrict timeout)
458 {
459 pthread_t self;
460 int retval;
461
462 self = pthread__self();
463 TESTCANCEL(self);
464 retval = _sigtimedwait(set, info, timeout);
465 TESTCANCEL(self);
466
467 return retval;
468 }
469
470 __strong_alias(_close, close)
471 __strong_alias(_fcntl, fcntl)
472 __strong_alias(_fdatasync, fdatasync)
473 __strong_alias(_fsync, fsync)
474 __weak_alias(fsync_range, _fsync_range)
475 __strong_alias(_msgrcv, msgrcv)
476 __strong_alias(_msgsnd, msgsnd)
477 __strong_alias(___msync13, __msync13)
478 __strong_alias(_open, open)
479 __strong_alias(_poll, poll)
480 __weak_alias(pollts, _pollts)
481 __strong_alias(_pread, pread)
482 __strong_alias(_pselect, pselect)
483 __strong_alias(_pwrite, pwrite)
484 __strong_alias(_read, read)
485 __strong_alias(_readv, readv)
486 __strong_alias(_select, select)
487 __strong_alias(_wait4, wait4)
488 __strong_alias(_write, write)
489 __strong_alias(_writev, writev)
490
491 #ifndef PTHREAD__COMPAT
492 int
493 aio_suspend(const struct aiocb * const list[], int nent,
494 const struct timespec *timeout)
495 {
496 int retval;
497 pthread_t self;
498
499 self = pthread__self();
500 TESTCANCEL(self);
501 retval = _sys_aio_suspend(list, nent, timeout);
502 TESTCANCEL(self);
503
504 return retval;
505 }
506
507 int
508 mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
509 {
510 int retval;
511 pthread_t self;
512
513 self = pthread__self();
514 TESTCANCEL(self);
515 retval = _sys_mq_send(mqdes, msg_ptr, msg_len, msg_prio);
516 TESTCANCEL(self);
517
518 return retval;
519 }
520
521 ssize_t
522 mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
523 {
524 ssize_t retval;
525 pthread_t self;
526
527 self = pthread__self();
528 TESTCANCEL(self);
529 retval = _sys_mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
530 TESTCANCEL(self);
531
532 return retval;
533 }
534
535 int
536 mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
537 unsigned msg_prio, const struct timespec *abst)
538 {
539 int retval;
540 pthread_t self;
541
542 self = pthread__self();
543 TESTCANCEL(self);
544 retval = _sys_mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, abst);
545 TESTCANCEL(self);
546
547 return retval;
548 }
549
550 ssize_t
551 mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio,
552 const struct timespec *abst)
553 {
554 ssize_t retval;
555 pthread_t self;
556
557 self = pthread__self();
558 TESTCANCEL(self);
559 retval = _sys_mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, abst);
560 TESTCANCEL(self);
561
562 return retval;
563 }
564
565 __strong_alias(_aio_suspend, aio_suspend)
566 __strong_alias(_mq_send, mq_send)
567 __strong_alias(_mq_receive, mq_receive)
568 __strong_alias(_mq_timedsend, mq_timedsend)
569 __strong_alias(_mq_timedreceive, mq_timedreceive)
570 #endif /* !PTHREAD__COMPAT */
571
572 #endif /* !lint */
573