thr_syscalls.c revision 148658
1/*
2 * Copyright (C) 2005 David Xu <davidxu@freebsd.org>.
3 * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
4 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice(s), this list of conditions and the following disclaimer as
12 *    the first lines of this file unmodified other than the possible
13 *    addition of one or more copyright notices.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice(s), this list of conditions and the following disclaimer in
16 *    the documentation and/or other materials provided with the
17 *    distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
23 * 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
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD: head/lib/libthr/thread/thr_syscalls.c 148658 2005-08-03 00:47:31Z deischen $
32 */
33
34/*
35 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 *    notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 *    notice, this list of conditions and the following disclaimer in the
45 *    documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 *    must display the following acknowledgement:
48 *	This product includes software developed by John Birrell.
49 * 4. Neither the name of the author nor the names of any co-contributors
50 *    may be used to endorse or promote products derived from this software
51 *    without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 *
65 */
66
67#include <sys/types.h>
68#include <sys/mman.h>
69#include <sys/param.h>
70#include <sys/select.h>
71#include <sys/signalvar.h>
72#include <sys/socket.h>
73#include <sys/stat.h>
74#include <sys/time.h>
75#include <sys/uio.h>
76#include <sys/wait.h>
77#include <aio.h>
78#include <dirent.h>
79#include <errno.h>
80#include <fcntl.h>
81#include <poll.h>
82#include <signal.h>
83#include <stdarg.h>
84#include <stdio.h>
85#include <stdlib.h>
86#include <string.h>
87#include <termios.h>
88#include <unistd.h>
89#include <pthread.h>
90
91#include "thr_private.h"
92
93extern int __creat(const char *, mode_t);
94extern int __pause(void);
95extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
96		const struct timespec *timo, const sigset_t *mask);
97extern unsigned int __sleep(unsigned int);
98extern int __system(const char *);
99extern int __tcdrain(int);
100extern int __usleep(useconds_t);
101extern pid_t __wait(int *);
102extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
103extern pid_t __waitpid(pid_t, int *, int);
104
105__weak_reference(__accept, accept);
106int
107__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
108{
109	struct pthread *curthread;
110	int oldcancel;
111	int ret;
112
113	curthread = _get_curthread();
114	oldcancel = _thr_cancel_enter(curthread);
115	ret = __sys_accept(s, addr, addrlen);
116	_thr_cancel_leave(curthread, oldcancel);
117
118 	return (ret);
119}
120
121__weak_reference(_aio_suspend, aio_suspend);
122
123int
124_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
125    timespec *timeout)
126{
127	struct pthread *curthread = _get_curthread();
128	int oldcancel;
129	int ret;
130
131	oldcancel = _thr_cancel_enter(curthread);
132	ret = __sys_aio_suspend(iocbs, niocb, timeout);
133	_thr_cancel_leave(curthread, oldcancel);
134
135	return (ret);
136}
137
138__weak_reference(__close, close);
139
140int
141__close(int fd)
142{
143	struct pthread	*curthread = _get_curthread();
144	int	oldcancel;
145	int	ret;
146
147	oldcancel = _thr_cancel_enter(curthread);
148	ret = __sys_close(fd);
149	_thr_cancel_leave(curthread, oldcancel);
150
151	return (ret);
152}
153
154__weak_reference(__connect, connect);
155
156int
157__connect(int fd, const struct sockaddr *name, socklen_t namelen)
158{
159	struct pthread *curthread = _get_curthread();
160	int oldcancel;
161	int ret;
162
163	curthread = _get_curthread();
164	oldcancel = _thr_cancel_enter(curthread);
165	ret = __sys_connect(fd, name, namelen);
166	_thr_cancel_leave(curthread, oldcancel);
167
168 	return (ret);
169}
170
171__weak_reference(___creat, creat);
172
173int
174___creat(const char *path, mode_t mode)
175{
176	struct pthread *curthread = _get_curthread();
177	int oldcancel;
178	int ret;
179
180	oldcancel = _thr_cancel_enter(curthread);
181	ret = __creat(path, mode);
182	_thr_cancel_leave(curthread, oldcancel);
183
184	return ret;
185}
186
187__weak_reference(__fcntl, fcntl);
188
189int
190__fcntl(int fd, int cmd,...)
191{
192	struct pthread *curthread = _get_curthread();
193	int	oldcancel;
194	int	ret;
195	va_list	ap;
196
197	oldcancel = _thr_cancel_enter(curthread);
198
199	va_start(ap, cmd);
200	switch (cmd) {
201	case F_DUPFD:
202		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
203		break;
204	case F_SETFD:
205	case F_SETFL:
206		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
207		break;
208	case F_GETFD:
209	case F_GETFL:
210		ret = __sys_fcntl(fd, cmd);
211		break;
212	default:
213		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
214	}
215	va_end(ap);
216
217	_thr_cancel_leave(curthread, oldcancel);
218
219	return (ret);
220}
221
222__weak_reference(__fsync, fsync);
223
224int
225__fsync(int fd)
226{
227	struct pthread *curthread = _get_curthread();
228	int	oldcancel;
229	int	ret;
230
231	oldcancel = _thr_cancel_enter(curthread);
232	ret = __sys_fsync(fd);
233	_thr_cancel_leave(curthread, oldcancel);
234
235	return (ret);
236}
237
238__weak_reference(__msync, msync);
239
240int
241__msync(void *addr, size_t len, int flags)
242{
243	struct pthread *curthread = _get_curthread();
244	int	oldcancel;
245	int	ret;
246
247	oldcancel = _thr_cancel_enter(curthread);
248	ret = __sys_msync(addr, len, flags);
249	_thr_cancel_leave(curthread, oldcancel);
250
251	return ret;
252}
253
254__weak_reference(__nanosleep, nanosleep);
255
256int
257__nanosleep(const struct timespec *time_to_sleep,
258    struct timespec *time_remaining)
259{
260	struct pthread *curthread = _get_curthread();
261	int		oldcancel;
262	int		ret;
263
264	oldcancel = _thr_cancel_enter(curthread);
265	ret = __sys_nanosleep(time_to_sleep, time_remaining);
266	_thr_cancel_leave(curthread, oldcancel);
267
268	return (ret);
269}
270
271__weak_reference(__open, open);
272
273int
274__open(const char *path, int flags,...)
275{
276	struct pthread *curthread = _get_curthread();
277	int	oldcancel;
278	int	ret;
279	int	mode = 0;
280	va_list	ap;
281
282	oldcancel = _thr_cancel_enter(curthread);
283
284	/* Check if the file is being created: */
285	if (flags & O_CREAT) {
286		/* Get the creation mode: */
287		va_start(ap, flags);
288		mode = va_arg(ap, int);
289		va_end(ap);
290	}
291
292	ret = __sys_open(path, flags, mode);
293
294	_thr_cancel_leave(curthread, oldcancel);
295
296	return ret;
297}
298
299__weak_reference(_pause, pause);
300
301int
302_pause(void)
303{
304	struct pthread *curthread = _get_curthread();
305	int	oldcancel;
306	int	ret;
307
308	oldcancel = _thr_cancel_enter(curthread);
309	ret = __pause();
310	_thr_cancel_leave(curthread, oldcancel);
311
312	return ret;
313}
314
315__weak_reference(__poll, poll);
316
317int
318__poll(struct pollfd *fds, unsigned int nfds, int timeout)
319{
320	struct pthread *curthread = _get_curthread();
321	int oldcancel;
322	int ret;
323
324	oldcancel = _thr_cancel_enter(curthread);
325	ret = __sys_poll(fds, nfds, timeout);
326	_thr_cancel_leave(curthread, oldcancel);
327
328	return ret;
329}
330
331__weak_reference(_pselect, pselect);
332
333int
334_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
335	const struct timespec *timo, const sigset_t *mask)
336{
337	struct pthread *curthread = _get_curthread();
338	int oldcancel;
339	int ret;
340
341	oldcancel = _thr_cancel_enter(curthread);
342	ret = __pselect(count, rfds, wfds, efds, timo, mask);
343	_thr_cancel_leave(curthread, oldcancel);
344
345	return (ret);
346}
347
348__weak_reference(_raise, raise);
349
350int
351_raise(int sig)
352{
353	int ret;
354
355	if (!_thr_isthreaded())
356		ret = kill(getpid(), sig);
357	else {
358		ret = pthread_kill(pthread_self(), sig);
359		if (ret != 0) {
360			errno = ret;
361			ret = -1;
362		}
363	}
364	return (ret);
365}
366
367__weak_reference(__read, read);
368
369ssize_t
370__read(int fd, void *buf, size_t nbytes)
371{
372	struct pthread *curthread = _get_curthread();
373	int oldcancel;
374	ssize_t	ret;
375
376	oldcancel = _thr_cancel_enter(curthread);
377	ret = __sys_read(fd, buf, nbytes);
378	_thr_cancel_leave(curthread, oldcancel);
379
380	return ret;
381}
382
383__weak_reference(__readv, readv);
384
385ssize_t
386__readv(int fd, const struct iovec *iov, int iovcnt)
387{
388	struct pthread *curthread = _get_curthread();
389	int oldcancel;
390	ssize_t ret;
391
392	oldcancel = _thr_cancel_enter(curthread);
393	ret = __sys_readv(fd, iov, iovcnt);
394	_thr_cancel_leave(curthread, oldcancel);
395
396	return ret;
397}
398
399__weak_reference(__recvfrom, recvfrom);
400
401ssize_t
402__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
403    socklen_t *fl)
404{
405	struct pthread *curthread = _get_curthread();
406	int oldcancel;
407	ssize_t ret;
408
409	oldcancel = _thr_cancel_enter(curthread);
410	ret = __sys_recvfrom(s, b, l, f, from, fl);
411	_thr_cancel_leave(curthread, oldcancel);
412	return (ret);
413}
414
415__weak_reference(__recvmsg, recvmsg);
416
417ssize_t
418__recvmsg(int s, struct msghdr *m, int f)
419{
420	struct pthread *curthread = _get_curthread();
421	ssize_t ret;
422	int oldcancel;
423
424	oldcancel = _thr_cancel_enter(curthread);
425	ret = __sys_recvmsg(s, m, f);
426	_thr_cancel_leave(curthread, oldcancel);
427	return (ret);
428}
429
430__weak_reference(__select, select);
431
432int
433__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
434	struct timeval *timeout)
435{
436	struct pthread *curthread = _get_curthread();
437	int oldcancel;
438	int ret;
439
440	oldcancel = _thr_cancel_enter(curthread);
441	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
442	_thr_cancel_leave(curthread, oldcancel);
443	return ret;
444}
445
446__weak_reference(__sendmsg, sendmsg);
447
448ssize_t
449__sendmsg(int s, const struct msghdr *m, int f)
450{
451	struct pthread *curthread = _get_curthread();
452	ssize_t ret;
453	int oldcancel;
454
455	oldcancel = _thr_cancel_enter(curthread);
456	ret = __sys_sendmsg(s, m, f);
457	_thr_cancel_leave(curthread, oldcancel);
458	return (ret);
459}
460
461__weak_reference(__sendto, sendto);
462
463ssize_t
464__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
465    socklen_t tl)
466{
467	struct pthread *curthread = _get_curthread();
468	ssize_t ret;
469	int oldcancel;
470
471	oldcancel = _thr_cancel_enter(curthread);
472	ret = __sys_sendto(s, m, l, f, t, tl);
473	_thr_cancel_leave(curthread, oldcancel);
474	return (ret);
475}
476
477__weak_reference(_sleep, sleep);
478
479unsigned int
480_sleep(unsigned int seconds)
481{
482	struct pthread *curthread = _get_curthread();
483	int		oldcancel;
484	unsigned int	ret;
485
486	oldcancel = _thr_cancel_enter(curthread);
487	ret = __sleep(seconds);
488	_thr_cancel_leave(curthread, oldcancel);
489
490	return (ret);
491}
492
493__weak_reference(_system, system);
494
495int
496_system(const char *string)
497{
498	struct pthread *curthread = _get_curthread();
499	int	oldcancel;
500	int	ret;
501
502	oldcancel = _thr_cancel_enter(curthread);
503	ret = __system(string);
504	_thr_cancel_leave(curthread, oldcancel);
505
506	return ret;
507}
508
509__weak_reference(_tcdrain, tcdrain);
510
511int
512_tcdrain(int fd)
513{
514	struct pthread *curthread = _get_curthread();
515	int	oldcancel;
516	int	ret;
517
518	oldcancel = _thr_cancel_enter(curthread);
519	ret = __tcdrain(fd);
520	_thr_cancel_leave(curthread, oldcancel);
521
522	return (ret);
523}
524
525__weak_reference(_usleep, usleep);
526
527int
528_usleep(useconds_t useconds)
529{
530	struct pthread *curthread = _get_curthread();
531	int		oldcancel;
532	int		ret;
533
534	oldcancel = _thr_cancel_enter(curthread);
535	ret = __usleep(useconds);
536	_thr_cancel_leave(curthread, oldcancel);
537
538	return (ret);
539}
540
541__weak_reference(_vfork, vfork);
542
543int
544_vfork(void)
545{
546	return (fork());
547}
548
549__weak_reference(_wait, wait);
550
551pid_t
552_wait(int *istat)
553{
554	struct pthread *curthread = _get_curthread();
555	int	oldcancel;
556	pid_t	ret;
557
558	oldcancel = _thr_cancel_enter(curthread);
559	ret = __wait(istat);
560	_thr_cancel_leave(curthread, oldcancel);
561
562	return ret;
563}
564
565__weak_reference(__wait4, wait4);
566
567pid_t
568__wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
569{
570	struct pthread *curthread = _get_curthread();
571	int oldcancel;
572	pid_t ret;
573
574	oldcancel = _thr_cancel_enter(curthread);
575	ret = __sys_wait4(pid, istat, options, rusage);
576	_thr_cancel_leave(curthread, oldcancel);
577
578	return ret;
579}
580
581__weak_reference(_waitpid, waitpid);
582
583pid_t
584_waitpid(pid_t wpid, int *status, int options)
585{
586	struct pthread *curthread = _get_curthread();
587	int	oldcancel;
588	pid_t	ret;
589
590	oldcancel = _thr_cancel_enter(curthread);
591	ret = __waitpid(wpid, status, options);
592	_thr_cancel_leave(curthread, oldcancel);
593
594	return ret;
595}
596
597__weak_reference(__write, write);
598
599ssize_t
600__write(int fd, const void *buf, size_t nbytes)
601{
602	struct pthread *curthread = _get_curthread();
603	int	oldcancel;
604	ssize_t	ret;
605
606	oldcancel = _thr_cancel_enter(curthread);
607	ret = __sys_write(fd, buf, nbytes);
608	_thr_cancel_leave(curthread, oldcancel);
609
610	return ret;
611}
612
613__weak_reference(__writev, writev);
614
615ssize_t
616__writev(int fd, const struct iovec *iov, int iovcnt)
617{
618	struct pthread *curthread = _get_curthread();
619	int	oldcancel;
620	ssize_t ret;
621
622	oldcancel = _thr_cancel_enter(curthread);
623	ret = __sys_writev(fd, iov, iovcnt);
624	_thr_cancel_leave(curthread, oldcancel);
625
626	return ret;
627}
628