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