thr_syscalls.c revision 164583
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 164583 2006-11-24 09:57:38Z 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 "namespace.h"
68#include <sys/types.h>
69#include <sys/mman.h>
70#include <sys/param.h>
71#include <sys/select.h>
72#include <sys/signalvar.h>
73#include <sys/socket.h>
74#include <sys/stat.h>
75#include <sys/time.h>
76#include <sys/uio.h>
77#include <sys/wait.h>
78#include <aio.h>
79#include <dirent.h>
80#include <errno.h>
81#include <fcntl.h>
82#include <poll.h>
83#include <signal.h>
84#include <stdarg.h>
85#include <stdio.h>
86#include <stdlib.h>
87#include <string.h>
88#include <termios.h>
89#include <unistd.h>
90#include <pthread.h>
91#include "un-namespace.h"
92
93#include "thr_private.h"
94
95extern int	__creat(const char *, mode_t);
96extern int	__pselect(int, fd_set *, fd_set *, fd_set *,
97			const struct timespec *, const sigset_t *);
98extern unsigned	__sleep(unsigned int);
99extern int	__system(const char *);
100extern int	__tcdrain(int);
101extern int	__usleep(useconds_t);
102extern pid_t	__wait(int *);
103extern pid_t	__waitpid(pid_t, int *, int);
104extern int	__sys_aio_suspend(const struct aiocb * const[], int,
105			const struct timespec *);
106extern int	__sys_accept(int, struct sockaddr *, socklen_t *);
107extern int	__sys_connect(int, const struct sockaddr *, socklen_t);
108extern int	__sys_fsync(int);
109extern int	__sys_msync(void *, size_t, int);
110extern int	__sys_poll(struct pollfd *, unsigned, int);
111extern ssize_t	__sys_recv(int, void *, size_t, int);
112extern ssize_t	__sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
113extern ssize_t	__sys_recvmsg(int, struct msghdr *, int);
114extern int	__sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
115extern int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
116			off_t *, int);
117extern ssize_t	__sys_sendmsg(int, const struct msghdr *, int);
118extern ssize_t	__sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
119extern ssize_t	__sys_readv(int, const struct iovec *, int);
120extern pid_t	__sys_wait4(pid_t, int *, int, struct rusage *);
121extern ssize_t	__sys_writev(int, const struct iovec *, int);
122
123int	___creat(const char *, mode_t);
124int	___pselect(int, fd_set *, fd_set *, fd_set *,
125		const struct timespec *, const sigset_t *);
126unsigned	___sleep(unsigned);
127int	___system(const char *);
128int	___tcdrain(int);
129int	___usleep(useconds_t useconds);
130pid_t	___wait(int *);
131pid_t	___waitpid(pid_t, int *, int);
132int	__accept(int, struct sockaddr *, socklen_t *);
133int	__aio_suspend(const struct aiocb * const iocbs[], int,
134		const struct timespec *);
135int	__close(int);
136int	__connect(int, const struct sockaddr *, socklen_t);
137int	__fcntl(int, int,...);
138int	__fsync(int);
139int	__msync(void *, size_t, int);
140int	__nanosleep(const struct timespec *, struct timespec *);
141int	__open(const char *, int,...);
142int	__poll(struct pollfd *, unsigned int, int);
143ssize_t	__read(int, void *buf, size_t);
144ssize_t	__readv(int, const struct iovec *, int);
145ssize_t	__recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *);
146ssize_t	__recvmsg(int, struct msghdr *, int);
147int	__select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
148ssize_t	__sendmsg(int, const struct msghdr *, int);
149ssize_t	__sendto(int, const void *, size_t, int,
150		const struct sockaddr *, socklen_t);
151pid_t	__wait3(int *, int, struct rusage *);
152pid_t	__wait4(pid_t, int *, int, struct rusage *);
153ssize_t	__write(int, const void *, size_t);
154ssize_t	__writev(int, const struct iovec *, int);
155int	_vfork(void);
156
157__weak_reference(__accept, accept);
158
159int
160__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
161{
162	struct pthread *curthread;
163	int ret;
164
165	curthread = _get_curthread();
166	_thr_cancel_enter(curthread);
167	ret = __sys_accept(s, addr, addrlen);
168	_thr_cancel_leave(curthread);
169
170 	return (ret);
171}
172
173__weak_reference(__aio_suspend, aio_suspend);
174
175int
176__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
177    timespec *timeout)
178{
179	struct pthread *curthread = _get_curthread();
180	int ret;
181
182	_thr_cancel_enter(curthread);
183	ret = __sys_aio_suspend(iocbs, niocb, timeout);
184	_thr_cancel_leave(curthread);
185
186	return (ret);
187}
188
189__weak_reference(__close, close);
190
191int
192__close(int fd)
193{
194	struct pthread	*curthread = _get_curthread();
195	int	ret;
196
197	_thr_cancel_enter(curthread);
198	ret = __sys_close(fd);
199	_thr_cancel_leave(curthread);
200
201	return (ret);
202}
203
204__weak_reference(__connect, connect);
205
206int
207__connect(int fd, const struct sockaddr *name, socklen_t namelen)
208{
209	struct pthread *curthread = _get_curthread();
210	int ret;
211
212	_thr_cancel_enter(curthread);
213	ret = __sys_connect(fd, name, namelen);
214	_thr_cancel_leave(curthread);
215
216 	return (ret);
217}
218
219__weak_reference(___creat, creat);
220
221int
222___creat(const char *path, mode_t mode)
223{
224	struct pthread *curthread = _get_curthread();
225	int ret;
226
227	_thr_cancel_enter(curthread);
228	ret = __creat(path, mode);
229	_thr_cancel_leave(curthread);
230
231	return ret;
232}
233
234__weak_reference(__fcntl, fcntl);
235
236int
237__fcntl(int fd, int cmd,...)
238{
239	struct pthread *curthread = _get_curthread();
240	int	ret;
241	va_list	ap;
242
243	_thr_cancel_enter(curthread);
244
245	va_start(ap, cmd);
246	switch (cmd) {
247	case F_DUPFD:
248		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
249		break;
250	case F_SETFD:
251	case F_SETFL:
252		ret = __sys_fcntl(fd, cmd, va_arg(ap, int));
253		break;
254	case F_GETFD:
255	case F_GETFL:
256		ret = __sys_fcntl(fd, cmd);
257		break;
258	default:
259		ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
260	}
261	va_end(ap);
262
263	_thr_cancel_leave(curthread);
264
265	return (ret);
266}
267
268__weak_reference(__fsync, fsync);
269
270int
271__fsync(int fd)
272{
273	struct pthread *curthread = _get_curthread();
274	int	ret;
275
276	_thr_cancel_enter(curthread);
277	ret = __sys_fsync(fd);
278	_thr_cancel_leave(curthread);
279
280	return (ret);
281}
282
283__weak_reference(__msync, msync);
284
285int
286__msync(void *addr, size_t len, int flags)
287{
288	struct pthread *curthread = _get_curthread();
289	int	ret;
290
291	_thr_cancel_enter(curthread);
292	ret = __sys_msync(addr, len, flags);
293	_thr_cancel_leave(curthread);
294
295	return ret;
296}
297
298__weak_reference(__nanosleep, nanosleep);
299
300int
301__nanosleep(const struct timespec *time_to_sleep,
302    struct timespec *time_remaining)
303{
304	struct pthread *curthread = _get_curthread();
305	int		ret;
306
307	_thr_cancel_enter(curthread);
308	ret = __sys_nanosleep(time_to_sleep, time_remaining);
309	_thr_cancel_leave(curthread);
310
311	return (ret);
312}
313
314__weak_reference(__open, open);
315
316int
317__open(const char *path, int flags,...)
318{
319	struct pthread *curthread = _get_curthread();
320	int	ret;
321	int	mode = 0;
322	va_list	ap;
323
324	_thr_cancel_enter(curthread);
325
326	/* Check if the file is being created: */
327	if (flags & O_CREAT) {
328		/* Get the creation mode: */
329		va_start(ap, flags);
330		mode = va_arg(ap, int);
331		va_end(ap);
332	}
333
334	ret = __sys_open(path, flags, mode);
335
336	_thr_cancel_leave(curthread);
337
338	return ret;
339}
340
341__weak_reference(__poll, poll);
342
343int
344__poll(struct pollfd *fds, unsigned int nfds, int timeout)
345{
346	struct pthread *curthread = _get_curthread();
347	int ret;
348
349	_thr_cancel_enter(curthread);
350	ret = __sys_poll(fds, nfds, timeout);
351	_thr_cancel_leave(curthread);
352
353	return ret;
354}
355
356__weak_reference(___pselect, pselect);
357
358int
359___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
360	const struct timespec *timo, const sigset_t *mask)
361{
362	struct pthread *curthread = _get_curthread();
363	int ret;
364
365	_thr_cancel_enter(curthread);
366	ret = __pselect(count, rfds, wfds, efds, timo, mask);
367	_thr_cancel_leave(curthread);
368
369	return (ret);
370}
371
372__weak_reference(__read, read);
373
374ssize_t
375__read(int fd, void *buf, size_t nbytes)
376{
377	struct pthread *curthread = _get_curthread();
378	ssize_t	ret;
379
380	_thr_cancel_enter(curthread);
381	ret = __sys_read(fd, buf, nbytes);
382	_thr_cancel_leave(curthread);
383
384	return ret;
385}
386
387__weak_reference(__readv, readv);
388
389ssize_t
390__readv(int fd, const struct iovec *iov, int iovcnt)
391{
392	struct pthread *curthread = _get_curthread();
393	ssize_t ret;
394
395	_thr_cancel_enter(curthread);
396	ret = __sys_readv(fd, iov, iovcnt);
397	_thr_cancel_leave(curthread);
398
399	return ret;
400}
401
402__weak_reference(__recvfrom, recvfrom);
403
404ssize_t
405__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
406    socklen_t *fl)
407{
408	struct pthread *curthread = _get_curthread();
409	ssize_t ret;
410
411	_thr_cancel_enter(curthread);
412	ret = __sys_recvfrom(s, b, l, f, from, fl);
413	_thr_cancel_leave(curthread);
414	return (ret);
415}
416
417__weak_reference(__recvmsg, recvmsg);
418
419ssize_t
420__recvmsg(int s, struct msghdr *m, int f)
421{
422	struct pthread *curthread = _get_curthread();
423	ssize_t ret;
424
425	_thr_cancel_enter(curthread);
426	ret = __sys_recvmsg(s, m, f);
427	_thr_cancel_leave(curthread);
428	return (ret);
429}
430
431__weak_reference(__select, select);
432
433int
434__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
435	struct timeval *timeout)
436{
437	struct pthread *curthread = _get_curthread();
438	int ret;
439
440	_thr_cancel_enter(curthread);
441	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
442	_thr_cancel_leave(curthread);
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
454	_thr_cancel_enter(curthread);
455	ret = __sys_sendmsg(s, m, f);
456	_thr_cancel_leave(curthread);
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
469	_thr_cancel_enter(curthread);
470	ret = __sys_sendto(s, m, l, f, t, tl);
471	_thr_cancel_leave(curthread);
472	return (ret);
473}
474
475__weak_reference(___sleep, sleep);
476
477unsigned int
478___sleep(unsigned int seconds)
479{
480	struct pthread *curthread = _get_curthread();
481	unsigned int	ret;
482
483	_thr_cancel_enter(curthread);
484	ret = __sleep(seconds);
485	_thr_cancel_leave(curthread);
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	ret;
497
498	_thr_cancel_enter(curthread);
499	ret = __system(string);
500	_thr_cancel_leave(curthread);
501
502	return ret;
503}
504
505__weak_reference(___tcdrain, tcdrain);
506
507int
508___tcdrain(int fd)
509{
510	struct pthread *curthread = _get_curthread();
511	int	ret;
512
513	_thr_cancel_enter(curthread);
514	ret = __tcdrain(fd);
515	_thr_cancel_leave(curthread);
516
517	return (ret);
518}
519
520__weak_reference(___usleep, usleep);
521
522int
523___usleep(useconds_t useconds)
524{
525	struct pthread *curthread = _get_curthread();
526	int		ret;
527
528	_thr_cancel_enter(curthread);
529	ret = __usleep(useconds);
530	_thr_cancel_leave(curthread);
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	pid_t	ret;
550
551	_thr_cancel_enter(curthread);
552	ret = __wait(istat);
553	_thr_cancel_leave(curthread);
554
555	return ret;
556}
557
558__weak_reference(__wait3, wait3);
559
560pid_t
561__wait3(int *status, int options, struct rusage *rusage)
562{
563	struct pthread *curthread = _get_curthread();
564	pid_t ret;
565
566	_thr_cancel_enter(curthread);
567	ret = _wait4(WAIT_ANY, status, options, rusage);
568	_thr_cancel_leave(curthread);
569
570	return (ret);
571}
572
573__weak_reference(__wait4, wait4);
574
575pid_t
576__wait4(pid_t pid, int *status, int options, struct rusage *rusage)
577{
578	struct pthread *curthread = _get_curthread();
579	pid_t ret;
580
581	_thr_cancel_enter(curthread);
582	ret = __sys_wait4(pid, status, options, rusage);
583	_thr_cancel_leave(curthread);
584
585	return ret;
586}
587
588__weak_reference(___waitpid, waitpid);
589
590pid_t
591___waitpid(pid_t wpid, int *status, int options)
592{
593	struct pthread *curthread = _get_curthread();
594	pid_t	ret;
595
596	_thr_cancel_enter(curthread);
597	ret = __waitpid(wpid, status, options);
598	_thr_cancel_leave(curthread);
599
600	return ret;
601}
602
603__weak_reference(__write, write);
604
605ssize_t
606__write(int fd, const void *buf, size_t nbytes)
607{
608	struct pthread *curthread = _get_curthread();
609	ssize_t	ret;
610
611	_thr_cancel_enter(curthread);
612	ret = __sys_write(fd, buf, nbytes);
613	_thr_cancel_leave(curthread);
614
615	return ret;
616}
617
618__weak_reference(__writev, writev);
619
620ssize_t
621__writev(int fd, const struct iovec *iov, int iovcnt)
622{
623	struct pthread *curthread = _get_curthread();
624	ssize_t ret;
625
626	_thr_cancel_enter(curthread);
627	ret = __sys_writev(fd, iov, iovcnt);
628	_thr_cancel_leave(curthread);
629
630	return ret;
631}
632