thr_syscalls.c revision 151972
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 151972 2005-11-02 14:06:29Z davidxu $
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	oldcancel = _thr_cancel_enter(curthread);
164	ret = __sys_connect(fd, name, namelen);
165	_thr_cancel_leave(curthread, oldcancel);
166
167 	return (ret);
168}
169
170__weak_reference(___creat, creat);
171
172int
173___creat(const char *path, mode_t mode)
174{
175	struct pthread *curthread = _get_curthread();
176	int oldcancel;
177	int ret;
178
179	oldcancel = _thr_cancel_enter(curthread);
180	ret = __creat(path, mode);
181	_thr_cancel_leave(curthread, oldcancel);
182
183	return ret;
184}
185
186__weak_reference(__fcntl, fcntl);
187
188int
189__fcntl(int fd, int cmd,...)
190{
191	struct pthread *curthread = _get_curthread();
192	int	oldcancel;
193	int	ret;
194	va_list	ap;
195
196	oldcancel = _thr_cancel_enter(curthread);
197
198	va_start(ap, cmd);
199	switch (cmd) {
200	case F_DUPFD:
201		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
202		break;
203	case F_SETFD:
204	case F_SETFL:
205		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
206		break;
207	case F_GETFD:
208	case F_GETFL:
209		ret = __sys_fcntl(fd, cmd);
210		break;
211	default:
212		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
213	}
214	va_end(ap);
215
216	_thr_cancel_leave(curthread, oldcancel);
217
218	return (ret);
219}
220
221__weak_reference(__fsync, fsync);
222
223int
224__fsync(int fd)
225{
226	struct pthread *curthread = _get_curthread();
227	int	oldcancel;
228	int	ret;
229
230	oldcancel = _thr_cancel_enter(curthread);
231	ret = __sys_fsync(fd);
232	_thr_cancel_leave(curthread, oldcancel);
233
234	return (ret);
235}
236
237__weak_reference(__msync, msync);
238
239int
240__msync(void *addr, size_t len, int flags)
241{
242	struct pthread *curthread = _get_curthread();
243	int	oldcancel;
244	int	ret;
245
246	oldcancel = _thr_cancel_enter(curthread);
247	ret = __sys_msync(addr, len, flags);
248	_thr_cancel_leave(curthread, oldcancel);
249
250	return ret;
251}
252
253__weak_reference(__nanosleep, nanosleep);
254
255int
256__nanosleep(const struct timespec *time_to_sleep,
257    struct timespec *time_remaining)
258{
259	struct pthread *curthread = _get_curthread();
260	int		oldcancel;
261	int		ret;
262
263	oldcancel = _thr_cancel_enter(curthread);
264	ret = __sys_nanosleep(time_to_sleep, time_remaining);
265	_thr_cancel_leave(curthread, oldcancel);
266
267	return (ret);
268}
269
270__weak_reference(__open, open);
271
272int
273__open(const char *path, int flags,...)
274{
275	struct pthread *curthread = _get_curthread();
276	int	oldcancel;
277	int	ret;
278	int	mode = 0;
279	va_list	ap;
280
281	oldcancel = _thr_cancel_enter(curthread);
282
283	/* Check if the file is being created: */
284	if (flags & O_CREAT) {
285		/* Get the creation mode: */
286		va_start(ap, flags);
287		mode = va_arg(ap, int);
288		va_end(ap);
289	}
290
291	ret = __sys_open(path, flags, mode);
292
293	_thr_cancel_leave(curthread, oldcancel);
294
295	return ret;
296}
297
298__weak_reference(_pause, pause);
299
300int
301_pause(void)
302{
303	struct pthread *curthread = _get_curthread();
304	int	oldcancel;
305	int	ret;
306
307	oldcancel = _thr_cancel_enter(curthread);
308	ret = __pause();
309	_thr_cancel_leave(curthread, oldcancel);
310
311	return ret;
312}
313
314__weak_reference(__poll, poll);
315
316int
317__poll(struct pollfd *fds, unsigned int nfds, int timeout)
318{
319	struct pthread *curthread = _get_curthread();
320	int oldcancel;
321	int ret;
322
323	oldcancel = _thr_cancel_enter(curthread);
324	ret = __sys_poll(fds, nfds, timeout);
325	_thr_cancel_leave(curthread, oldcancel);
326
327	return ret;
328}
329
330__weak_reference(_pselect, pselect);
331
332int
333_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
334	const struct timespec *timo, const sigset_t *mask)
335{
336	struct pthread *curthread = _get_curthread();
337	int oldcancel;
338	int ret;
339
340	oldcancel = _thr_cancel_enter(curthread);
341	ret = __pselect(count, rfds, wfds, efds, timo, mask);
342	_thr_cancel_leave(curthread, oldcancel);
343
344	return (ret);
345}
346
347__weak_reference(_raise, raise);
348
349int
350_raise(int sig)
351{
352	int ret;
353
354	if (!_thr_isthreaded())
355		ret = kill(getpid(), sig);
356	else
357		ret = _thr_send_sig(_get_curthread(), sig);
358	return (ret);
359}
360
361__weak_reference(__read, read);
362
363ssize_t
364__read(int fd, void *buf, size_t nbytes)
365{
366	struct pthread *curthread = _get_curthread();
367	int oldcancel;
368	ssize_t	ret;
369
370	oldcancel = _thr_cancel_enter(curthread);
371	ret = __sys_read(fd, buf, nbytes);
372	_thr_cancel_leave(curthread, oldcancel);
373
374	return ret;
375}
376
377__weak_reference(__readv, readv);
378
379ssize_t
380__readv(int fd, const struct iovec *iov, int iovcnt)
381{
382	struct pthread *curthread = _get_curthread();
383	int oldcancel;
384	ssize_t ret;
385
386	oldcancel = _thr_cancel_enter(curthread);
387	ret = __sys_readv(fd, iov, iovcnt);
388	_thr_cancel_leave(curthread, oldcancel);
389
390	return ret;
391}
392
393__weak_reference(__recvfrom, recvfrom);
394
395ssize_t
396__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
397    socklen_t *fl)
398{
399	struct pthread *curthread = _get_curthread();
400	int oldcancel;
401	ssize_t ret;
402
403	oldcancel = _thr_cancel_enter(curthread);
404	ret = __sys_recvfrom(s, b, l, f, from, fl);
405	_thr_cancel_leave(curthread, oldcancel);
406	return (ret);
407}
408
409__weak_reference(__recvmsg, recvmsg);
410
411ssize_t
412__recvmsg(int s, struct msghdr *m, int f)
413{
414	struct pthread *curthread = _get_curthread();
415	ssize_t ret;
416	int oldcancel;
417
418	oldcancel = _thr_cancel_enter(curthread);
419	ret = __sys_recvmsg(s, m, f);
420	_thr_cancel_leave(curthread, oldcancel);
421	return (ret);
422}
423
424__weak_reference(__select, select);
425
426int
427__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
428	struct timeval *timeout)
429{
430	struct pthread *curthread = _get_curthread();
431	int oldcancel;
432	int ret;
433
434	oldcancel = _thr_cancel_enter(curthread);
435	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
436	_thr_cancel_leave(curthread, oldcancel);
437	return ret;
438}
439
440__weak_reference(__sendmsg, sendmsg);
441
442ssize_t
443__sendmsg(int s, const struct msghdr *m, int f)
444{
445	struct pthread *curthread = _get_curthread();
446	ssize_t ret;
447	int oldcancel;
448
449	oldcancel = _thr_cancel_enter(curthread);
450	ret = __sys_sendmsg(s, m, f);
451	_thr_cancel_leave(curthread, oldcancel);
452	return (ret);
453}
454
455__weak_reference(__sendto, sendto);
456
457ssize_t
458__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
459    socklen_t tl)
460{
461	struct pthread *curthread = _get_curthread();
462	ssize_t ret;
463	int oldcancel;
464
465	oldcancel = _thr_cancel_enter(curthread);
466	ret = __sys_sendto(s, m, l, f, t, tl);
467	_thr_cancel_leave(curthread, oldcancel);
468	return (ret);
469}
470
471__weak_reference(_sleep, sleep);
472
473unsigned int
474_sleep(unsigned int seconds)
475{
476	struct pthread *curthread = _get_curthread();
477	int		oldcancel;
478	unsigned int	ret;
479
480	oldcancel = _thr_cancel_enter(curthread);
481	ret = __sleep(seconds);
482	_thr_cancel_leave(curthread, oldcancel);
483
484	return (ret);
485}
486
487__weak_reference(_system, system);
488
489int
490_system(const char *string)
491{
492	struct pthread *curthread = _get_curthread();
493	int	oldcancel;
494	int	ret;
495
496	oldcancel = _thr_cancel_enter(curthread);
497	ret = __system(string);
498	_thr_cancel_leave(curthread, oldcancel);
499
500	return ret;
501}
502
503__weak_reference(_tcdrain, tcdrain);
504
505int
506_tcdrain(int fd)
507{
508	struct pthread *curthread = _get_curthread();
509	int	oldcancel;
510	int	ret;
511
512	oldcancel = _thr_cancel_enter(curthread);
513	ret = __tcdrain(fd);
514	_thr_cancel_leave(curthread, oldcancel);
515
516	return (ret);
517}
518
519__weak_reference(_usleep, usleep);
520
521int
522_usleep(useconds_t useconds)
523{
524	struct pthread *curthread = _get_curthread();
525	int		oldcancel;
526	int		ret;
527
528	oldcancel = _thr_cancel_enter(curthread);
529	ret = __usleep(useconds);
530	_thr_cancel_leave(curthread, oldcancel);
531
532	return (ret);
533}
534
535__weak_reference(_vfork, vfork);
536
537int
538_vfork(void)
539{
540	return (fork());
541}
542
543__weak_reference(_wait, wait);
544
545pid_t
546_wait(int *istat)
547{
548	struct pthread *curthread = _get_curthread();
549	int	oldcancel;
550	pid_t	ret;
551
552	oldcancel = _thr_cancel_enter(curthread);
553	ret = __wait(istat);
554	_thr_cancel_leave(curthread, oldcancel);
555
556	return ret;
557}
558
559__weak_reference(__wait4, wait4);
560
561pid_t
562__wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
563{
564	struct pthread *curthread = _get_curthread();
565	int oldcancel;
566	pid_t ret;
567
568	oldcancel = _thr_cancel_enter(curthread);
569	ret = __sys_wait4(pid, istat, options, rusage);
570	_thr_cancel_leave(curthread, oldcancel);
571
572	return ret;
573}
574
575__weak_reference(_waitpid, waitpid);
576
577pid_t
578_waitpid(pid_t wpid, int *status, int options)
579{
580	struct pthread *curthread = _get_curthread();
581	int	oldcancel;
582	pid_t	ret;
583
584	oldcancel = _thr_cancel_enter(curthread);
585	ret = __waitpid(wpid, status, options);
586	_thr_cancel_leave(curthread, oldcancel);
587
588	return ret;
589}
590
591__weak_reference(__write, write);
592
593ssize_t
594__write(int fd, const void *buf, size_t nbytes)
595{
596	struct pthread *curthread = _get_curthread();
597	int	oldcancel;
598	ssize_t	ret;
599
600	oldcancel = _thr_cancel_enter(curthread);
601	ret = __sys_write(fd, buf, nbytes);
602	_thr_cancel_leave(curthread, oldcancel);
603
604	return ret;
605}
606
607__weak_reference(__writev, writev);
608
609ssize_t
610__writev(int fd, const struct iovec *iov, int iovcnt)
611{
612	struct pthread *curthread = _get_curthread();
613	int	oldcancel;
614	ssize_t ret;
615
616	oldcancel = _thr_cancel_enter(curthread);
617	ret = __sys_writev(fd, iov, iovcnt);
618	_thr_cancel_leave(curthread, oldcancel);
619
620	return ret;
621}
622