pthread_cancelstub.c revision 1.10 1 /* $NetBSD: pthread_cancelstub.c,v 1.10 2005/03/10 00:34:23 kleink Exp $ */
2
3 /*-
4 * Copyright (c) 2002 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.
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("$NetBSD: pthread_cancelstub.c,v 1.10 2005/03/10 00:34:23 kleink Exp $");
41
42 /*
43 * This is necessary because the fsync_range() name is always weak (it is
44 * not a POSIX function).
45 */
46 #define fsync_range _fsync_range
47
48 /*
49 * XXX this is necessary to get the prototypes for the __sigsuspend14
50 * XXX and __msync13 internal names, instead of the application-visible
51 * XXX sigsuspend and msync names. It's kind of gross, but we're pretty
52 * XXX intimate with libc already.
53 */
54 #define __LIBC12_SOURCE__
55
56 #include <sys/msg.h>
57 #include <sys/types.h>
58 #include <sys/uio.h>
59 #include <sys/wait.h>
60 #include <fcntl.h>
61 #include <poll.h>
62 #include <stdarg.h>
63 #include <unistd.h>
64
65 #include <signal.h>
66 #include <sys/mman.h>
67 #include <sys/socket.h>
68
69 #include "pthread.h"
70 #include "pthread_int.h"
71
72 int pthread__cancel_stub_binder;
73
74 int _sys_accept(int, struct sockaddr *, socklen_t *);
75 int _sys_close(int);
76 int _sys_connect(int, const struct sockaddr *, socklen_t);
77 int _sys_fcntl(int, int, ...);
78 int _sys_fdatasync(int);
79 int _sys_fsync(int);
80 int _sys_fsync_range(int, int, off_t, off_t);
81 ssize_t _sys_msgrcv(int, void *, size_t, long, int);
82 int _sys_msgsnd(int, const void *, size_t, int);
83 int _sys___msync13(void *, size_t, int);
84 int _sys_open(const char *, int, ...);
85 int _sys_poll(struct pollfd *, nfds_t, int);
86 ssize_t _sys_pread(int, void *, size_t, off_t);
87 ssize_t _sys_pwrite(int, const void *, size_t, off_t);
88 ssize_t _sys_read(int, void *, size_t);
89 ssize_t _sys_readv(int, const struct iovec *, int);
90 int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
91 int _sys_wait4(pid_t, int *, int, struct rusage *);
92 ssize_t _sys_write(int, const void *, size_t);
93 ssize_t _sys_writev(int, const struct iovec *, int);
94
95 #define TESTCANCEL(id) do { \
96 if (__predict_false((id)->pt_cancel)) \
97 pthread_exit(PTHREAD_CANCELED); \
98 } while (/*CONSTCOND*/0)
99
100
101 int
102 accept(int s, struct sockaddr *addr, socklen_t *addrlen)
103 {
104 int retval;
105 pthread_t self;
106
107 self = pthread__self();
108 TESTCANCEL(self);
109 retval = _sys_accept(s, addr, addrlen);
110 TESTCANCEL(self);
111
112 return retval;
113 }
114
115 int
116 close(int d)
117 {
118 int retval;
119 pthread_t self;
120
121 self = pthread__self();
122 TESTCANCEL(self);
123 retval = _sys_close(d);
124 TESTCANCEL(self);
125
126 return retval;
127 }
128
129 int
130 connect(int s, const struct sockaddr *addr, socklen_t namelen)
131 {
132 int retval;
133 pthread_t self;
134
135 self = pthread__self();
136 TESTCANCEL(self);
137 retval = _sys_connect(s, addr, namelen);
138 TESTCANCEL(self);
139
140 return retval;
141 }
142
143 int
144 fcntl(int fd, int cmd, ...)
145 {
146 int retval;
147 pthread_t self;
148 va_list ap;
149
150 self = pthread__self();
151 TESTCANCEL(self);
152 va_start(ap, cmd);
153 retval = _sys_fcntl(fd, cmd, va_arg(ap, void *));
154 va_end(ap);
155 TESTCANCEL(self);
156
157 return retval;
158 }
159
160 int
161 fdatasync(int d)
162 {
163 int retval;
164 pthread_t self;
165
166 self = pthread__self();
167 TESTCANCEL(self);
168 retval = _sys_fdatasync(d);
169 TESTCANCEL(self);
170
171 return retval;
172 }
173
174 int
175 fsync(int d)
176 {
177 int retval;
178 pthread_t self;
179
180 self = pthread__self();
181 TESTCANCEL(self);
182 retval = _sys_fsync(d);
183 TESTCANCEL(self);
184
185 return retval;
186 }
187
188 int
189 fsync_range(int d, int f, off_t s, off_t e)
190 {
191 int retval;
192 pthread_t self;
193
194 self = pthread__self();
195 TESTCANCEL(self);
196 retval = _sys_fsync_range(d, f, s, e);
197 TESTCANCEL(self);
198
199 return retval;
200 }
201
202 ssize_t
203 msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
204 {
205 ssize_t retval;
206 pthread_t self;
207
208 self = pthread__self();
209 TESTCANCEL(self);
210 retval = _sys_msgrcv(msgid, msgp, msgsz, msgtyp, msgflg);
211 TESTCANCEL(self);
212
213 return retval;
214 }
215
216 int
217 msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg)
218 {
219 int retval;
220 pthread_t self;
221
222 self = pthread__self();
223 TESTCANCEL(self);
224 retval = _sys_msgsnd(msgid, msgp, msgsz, msgflg);
225 TESTCANCEL(self);
226
227 return retval;
228 }
229
230 int
231 __msync13(void *addr, size_t len, int flags)
232 {
233 int retval;
234 pthread_t self;
235
236 self = pthread__self();
237 TESTCANCEL(self);
238 retval = _sys___msync13(addr, len, flags);
239 TESTCANCEL(self);
240
241 return retval;
242 }
243
244 int
245 open(const char *path, int flags, ...)
246 {
247 int retval;
248 pthread_t self;
249 va_list ap;
250
251 self = pthread__self();
252 TESTCANCEL(self);
253 va_start(ap, flags);
254 retval = _sys_open(path, flags, va_arg(ap, mode_t));
255 va_end(ap);
256 TESTCANCEL(self);
257
258 return retval;
259 }
260
261 int
262 poll(struct pollfd *fds, nfds_t nfds, int timeout)
263 {
264 int retval;
265 pthread_t self;
266
267 self = pthread__self();
268 TESTCANCEL(self);
269 retval = _sys_poll(fds, nfds, timeout);
270 TESTCANCEL(self);
271
272 return retval;
273 }
274
275 ssize_t
276 pread(int d, void *buf, size_t nbytes, off_t offset)
277 {
278 ssize_t retval;
279 pthread_t self;
280
281 self = pthread__self();
282 TESTCANCEL(self);
283 retval = _sys_pread(d, buf, nbytes, offset);
284 TESTCANCEL(self);
285
286 return retval;
287 }
288
289 ssize_t
290 pwrite(int d, const void *buf, size_t nbytes, off_t offset)
291 {
292 ssize_t retval;
293 pthread_t self;
294
295 self = pthread__self();
296 TESTCANCEL(self);
297 retval = _sys_pwrite(d, buf, nbytes, offset);
298 TESTCANCEL(self);
299
300 return retval;
301 }
302
303 ssize_t
304 read(int d, void *buf, size_t nbytes)
305 {
306 ssize_t retval;
307 pthread_t self;
308
309 self = pthread__self();
310 TESTCANCEL(self);
311 retval = _sys_read(d, buf, nbytes);
312 TESTCANCEL(self);
313
314 return retval;
315 }
316
317 ssize_t
318 readv(int d, const struct iovec *iov, int iovcnt)
319 {
320 ssize_t retval;
321 pthread_t self;
322
323 self = pthread__self();
324 TESTCANCEL(self);
325 retval = _sys_readv(d, iov, iovcnt);
326 TESTCANCEL(self);
327
328 return retval;
329 }
330
331 int
332 select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
333 struct timeval *timeout)
334 {
335 int retval;
336 pthread_t self;
337
338 self = pthread__self();
339 TESTCANCEL(self);
340 retval = _sys_select(nfds, readfds, writefds, exceptfds, timeout);
341 TESTCANCEL(self);
342
343 return retval;
344 }
345
346 pid_t
347 wait4(pid_t wpid, int *status, int options, struct rusage *rusage)
348 {
349 pid_t retval;
350 pthread_t self;
351
352 self = pthread__self();
353 TESTCANCEL(self);
354 retval = _sys_wait4(wpid, status, options, rusage);
355 TESTCANCEL(self);
356
357 return retval;
358 }
359
360 ssize_t
361 write(int d, const void *buf, size_t nbytes)
362 {
363 ssize_t retval;
364 pthread_t self;
365
366 self = pthread__self();
367 TESTCANCEL(self);
368 retval = _sys_write(d, buf, nbytes);
369 TESTCANCEL(self);
370
371 return retval;
372 }
373
374 ssize_t
375 writev(int d, const struct iovec *iov, int iovcnt)
376 {
377 ssize_t retval;
378 pthread_t self;
379
380 self = pthread__self();
381 TESTCANCEL(self);
382 retval = _sys_writev(d, iov, iovcnt);
383 TESTCANCEL(self);
384
385 return retval;
386 }
387
388
389 __strong_alias(_close, close)
390 __strong_alias(_fcntl, fcntl)
391 __strong_alias(_fdatasync, fdatasync)
392 __strong_alias(_fsync, fsync)
393 __weak_alias(fsync_range, _fsync_range)
394 __strong_alias(_msgrcv, msgrcv)
395 __strong_alias(_msgsnd, msgsnd)
396 __strong_alias(___msync13, __msync13)
397 __strong_alias(_open, open)
398 __strong_alias(_poll, poll)
399 __strong_alias(_pread, pread)
400 __strong_alias(_pwrite, pwrite)
401 __strong_alias(_read, read)
402 __strong_alias(_readv, readv)
403 __strong_alias(_select, select)
404 __strong_alias(_wait4, wait4)
405 __strong_alias(_write, write)
406 __strong_alias(_writev, writev)
407