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