thr_syscalls.c revision 144518
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 144518 2005-04-02 01:20:00Z 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 pid_t __wait(int *);
101extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
102extern pid_t __waitpid(pid_t, int *, int);
103
104__weak_reference(__accept, accept);
105int
106__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
107{
108	struct pthread *curthread;
109	int oldcancel;
110	int ret;
111
112	curthread = _get_curthread();
113	oldcancel = _thr_cancel_enter(curthread);
114	ret = __sys_accept(s, addr, addrlen);
115	_thr_cancel_leave(curthread, oldcancel);
116
117 	return (ret);
118}
119
120__weak_reference(_aio_suspend, aio_suspend);
121
122int
123_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
124    timespec *timeout)
125{
126	struct pthread *curthread = _get_curthread();
127	int oldcancel;
128	int ret;
129
130	oldcancel = _thr_cancel_enter(curthread);
131	ret = __sys_aio_suspend(iocbs, niocb, timeout);
132	_thr_cancel_leave(curthread, oldcancel);
133
134	return (ret);
135}
136
137__weak_reference(__close, close);
138
139int
140__close(int fd)
141{
142	struct pthread	*curthread = _get_curthread();
143	int	oldcancel;
144	int	ret;
145
146	oldcancel = _thr_cancel_enter(curthread);
147	ret = __sys_close(fd);
148	_thr_cancel_leave(curthread, oldcancel);
149
150	return (ret);
151}
152
153__weak_reference(__connect, connect);
154
155int
156__connect(int fd, const struct sockaddr *name, socklen_t namelen)
157{
158	struct pthread *curthread = _get_curthread();
159	int oldcancel;
160	int ret;
161
162	curthread = _get_curthread();
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 = pthread_kill(pthread_self(), sig);
358		if (ret != 0) {
359			errno = ret;
360			ret = -1;
361		}
362	}
363	return (ret);
364}
365
366__weak_reference(__read, read);
367
368ssize_t
369__read(int fd, void *buf, size_t nbytes)
370{
371	struct pthread *curthread = _get_curthread();
372	int oldcancel;
373	ssize_t	ret;
374
375	oldcancel = _thr_cancel_enter(curthread);
376	ret = __sys_read(fd, buf, nbytes);
377	_thr_cancel_leave(curthread, oldcancel);
378
379	return ret;
380}
381
382__weak_reference(__readv, readv);
383
384ssize_t
385__readv(int fd, const struct iovec *iov, int iovcnt)
386{
387	struct pthread *curthread = _get_curthread();
388	int oldcancel;
389	ssize_t ret;
390
391	oldcancel = _thr_cancel_enter(curthread);
392	ret = __sys_readv(fd, iov, iovcnt);
393	_thr_cancel_leave(curthread, oldcancel);
394
395	return ret;
396}
397
398__weak_reference(__recvfrom, recvfrom);
399
400ssize_t
401__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
402    socklen_t *fl)
403{
404	struct pthread *curthread = _get_curthread();
405	int oldcancel;
406	ssize_t ret;
407
408	oldcancel = _thr_cancel_enter(curthread);
409	ret = __sys_recvfrom(s, b, l, f, from, fl);
410	_thr_cancel_leave(curthread, oldcancel);
411	return (ret);
412}
413
414__weak_reference(__recvmsg, recvmsg);
415
416ssize_t
417__recvmsg(int s, struct msghdr *m, int f)
418{
419	struct pthread *curthread = _get_curthread();
420	ssize_t ret;
421	int oldcancel;
422
423	oldcancel = _thr_cancel_enter(curthread);
424	ret = __sys_recvmsg(s, m, f);
425	_thr_cancel_leave(curthread, oldcancel);
426	return (ret);
427}
428
429__weak_reference(__select, select);
430
431int
432__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
433	struct timeval *timeout)
434{
435	struct pthread *curthread = _get_curthread();
436	int oldcancel;
437	int ret;
438
439	oldcancel = _thr_cancel_enter(curthread);
440	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
441	_thr_cancel_leave(curthread, oldcancel);
442	return ret;
443}
444
445__weak_reference(__sendmsg, sendmsg);
446
447ssize_t
448__sendmsg(int s, const struct msghdr *m, int f)
449{
450	struct pthread *curthread = _get_curthread();
451	ssize_t ret;
452	int oldcancel;
453
454	oldcancel = _thr_cancel_enter(curthread);
455	ret = __sys_sendmsg(s, m, f);
456	_thr_cancel_leave(curthread, oldcancel);
457	return (ret);
458}
459
460__weak_reference(__sendto, sendto);
461
462ssize_t
463__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
464    socklen_t tl)
465{
466	struct pthread *curthread = _get_curthread();
467	ssize_t ret;
468	int oldcancel;
469
470	oldcancel = _thr_cancel_enter(curthread);
471	ret = __sys_sendto(s, m, l, f, t, tl);
472	_thr_cancel_leave(curthread, oldcancel);
473	return (ret);
474}
475
476unsigned int
477_sleep(unsigned int seconds)
478{
479	struct pthread *curthread = _get_curthread();
480	int		oldcancel;
481	unsigned int	ret;
482
483	oldcancel = _thr_cancel_enter(curthread);
484	ret = __sleep(seconds);
485	_thr_cancel_leave(curthread, oldcancel);
486
487	return (ret);
488}
489
490__weak_reference(_system, system);
491
492int
493_system(const char *string)
494{
495	struct pthread *curthread = _get_curthread();
496	int	oldcancel;
497	int	ret;
498
499	oldcancel = _thr_cancel_enter(curthread);
500	ret = __system(string);
501	_thr_cancel_leave(curthread, oldcancel);
502
503	return ret;
504}
505
506__weak_reference(_tcdrain, tcdrain);
507
508int
509_tcdrain(int fd)
510{
511	struct pthread *curthread = _get_curthread();
512	int	oldcancel;
513	int	ret;
514
515	oldcancel = _thr_cancel_enter(curthread);
516	ret = __tcdrain(fd);
517	_thr_cancel_leave(curthread, oldcancel);
518
519	return (ret);
520}
521
522__weak_reference(_vfork, vfork);
523
524int
525_vfork(void)
526{
527	return (fork());
528}
529
530__weak_reference(_wait, wait);
531
532pid_t
533_wait(int *istat)
534{
535	struct pthread *curthread = _get_curthread();
536	int	oldcancel;
537	pid_t	ret;
538
539	oldcancel = _thr_cancel_enter(curthread);
540	ret = __wait(istat);
541	_thr_cancel_leave(curthread, oldcancel);
542
543	return ret;
544}
545
546__weak_reference(__wait4, wait4);
547
548pid_t
549__wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
550{
551	struct pthread *curthread = _get_curthread();
552	int oldcancel;
553	pid_t ret;
554
555	oldcancel = _thr_cancel_enter(curthread);
556	ret = __sys_wait4(pid, istat, options, rusage);
557	_thr_cancel_leave(curthread, oldcancel);
558
559	return ret;
560}
561
562__weak_reference(_waitpid, waitpid);
563
564pid_t
565_waitpid(pid_t wpid, int *status, int options)
566{
567	struct pthread *curthread = _get_curthread();
568	int	oldcancel;
569	pid_t	ret;
570
571	oldcancel = _thr_cancel_enter(curthread);
572	ret = __waitpid(wpid, status, options);
573	_thr_cancel_leave(curthread, oldcancel);
574
575	return ret;
576}
577
578__weak_reference(__write, write);
579
580ssize_t
581__write(int fd, const void *buf, size_t nbytes)
582{
583	struct pthread *curthread = _get_curthread();
584	int	oldcancel;
585	ssize_t	ret;
586
587	oldcancel = _thr_cancel_enter(curthread);
588	ret = __sys_write(fd, buf, nbytes);
589	_thr_cancel_leave(curthread, oldcancel);
590
591	return ret;
592}
593
594__weak_reference(__writev, writev);
595
596ssize_t
597__writev(int fd, const struct iovec *iov, int iovcnt)
598{
599	struct pthread *curthread = _get_curthread();
600	int	oldcancel;
601	ssize_t ret;
602
603	oldcancel = _thr_cancel_enter(curthread);
604	ret = __sys_writev(fd, iov, iovcnt);
605	_thr_cancel_leave(curthread, oldcancel);
606
607	return ret;
608}
609