thr_private.h revision 35509
1210311Sjmallett/*
2210311Sjmallett * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
3210311Sjmallett * All rights reserved.
4210311Sjmallett *
5210311Sjmallett * Redistribution and use in source and binary forms, with or without
6210311Sjmallett * modification, are permitted provided that the following conditions
7210311Sjmallett * are met:
8210311Sjmallett * 1. Redistributions of source code must retain the above copyright
9210311Sjmallett *    notice, this list of conditions and the following disclaimer.
10210311Sjmallett * 2. Redistributions in binary form must reproduce the above copyright
11210311Sjmallett *    notice, this list of conditions and the following disclaimer in the
12210311Sjmallett *    documentation and/or other materials provided with the distribution.
13210311Sjmallett * 3. All advertising materials mentioning features or use of this software
14210311Sjmallett *    must display the following acknowledgement:
15210311Sjmallett *	This product includes software developed by John Birrell.
16210311Sjmallett * 4. Neither the name of the author nor the names of any co-contributors
17210311Sjmallett *    may be used to endorse or promote products derived from this software
18210311Sjmallett *    without specific prior written permission.
19210311Sjmallett *
20210311Sjmallett * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21210311Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22210311Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23210311Sjmallett * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24210311Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25210311Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26210311Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27210311Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28210311Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29210311Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30210311Sjmallett * SUCH DAMAGE.
31210311Sjmallett *
32210311Sjmallett * Private thread definitions for the uthread kernel.
33210311Sjmallett *
34210311Sjmallett */
35210311Sjmallett
36210311Sjmallett#ifndef _PTHREAD_PRIVATE_H
37210311Sjmallett#define _PTHREAD_PRIVATE_H
38210311Sjmallett
39210311Sjmallett/*
40210311Sjmallett * Evaluate the storage class specifier.
41210311Sjmallett */
42210311Sjmallett#ifdef GLOBAL_PTHREAD_PRIVATE
43210311Sjmallett#define SCLASS
44210311Sjmallett#else
45210311Sjmallett#define SCLASS extern
46210311Sjmallett#endif
47210311Sjmallett
48210311Sjmallett/*
49210311Sjmallett * Include files.
50210311Sjmallett */
51210311Sjmallett#include <setjmp.h>
52210311Sjmallett#include <signal.h>
53210311Sjmallett#include <sys/queue.h>
54210311Sjmallett#include <sys/types.h>
55210311Sjmallett#include <sys/time.h>
56210311Sjmallett#include <sched.h>
57210311Sjmallett
58210311Sjmallett/*
59210311Sjmallett * Kernel fatal error handler macro.
60210311Sjmallett */
61210311Sjmallett#define PANIC(string)   _thread_exit(__FILE__,__LINE__,string)
62210311Sjmallett
63210311Sjmallett/* Output debug messages like this: */
64210311Sjmallett#define	stdout_debug(_x)	_write(1,_x,strlen(_x));
65210311Sjmallett#define	stderr_debug(_x)	_write(2,_x,strlen(_x));
66210311Sjmallett
67210311Sjmallett/*
68210311Sjmallett * State change macro:
69210311Sjmallett */
70210311Sjmallett#define PTHREAD_NEW_STATE(thrd, newstate) {				\
71210311Sjmallett	(thrd)->state = newstate;					\
72210311Sjmallett	(thrd)->fname = __FILE__;					\
73210311Sjmallett	(thrd)->lineno = __LINE__;					\
74210311Sjmallett}
75210311Sjmallett
76210311Sjmallett/*
77210311Sjmallett * Queue definitions.
78210311Sjmallett */
79210311Sjmallettstruct pthread_queue {
80210311Sjmallett	struct pthread	*q_next;
81210311Sjmallett	struct pthread	*q_last;
82210311Sjmallett	void		*q_data;
83210311Sjmallett};
84210311Sjmallett
85210311Sjmallett/*
86210311Sjmallett * Static queue initialization values.
87210311Sjmallett */
88210311Sjmallett#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL }
89210311Sjmallett
90210311Sjmallett/*
91210311Sjmallett * Mutex definitions.
92210311Sjmallett */
93210311Sjmallettunion pthread_mutex_data {
94210311Sjmallett	void	*m_ptr;
95210311Sjmallett	int	m_count;
96210311Sjmallett};
97210311Sjmallett
98210311Sjmallettstruct pthread_mutex {
99210311Sjmallett	enum pthread_mutextype		m_type;
100210311Sjmallett	struct pthread_queue		m_queue;
101210311Sjmallett	struct pthread			*m_owner;
102210311Sjmallett	union pthread_mutex_data	m_data;
103210311Sjmallett	long				m_flags;
104210311Sjmallett
105210311Sjmallett	/*
106210311Sjmallett	 * Lock for accesses to this structure.
107210311Sjmallett	 */
108210311Sjmallett	long			access_lock;
109210311Sjmallett};
110210311Sjmallett
111210311Sjmallett/*
112210311Sjmallett * Flags for mutexes.
113210311Sjmallett */
114210311Sjmallett#define MUTEX_FLAGS_PRIVATE	0x01
115219695Sjmallett#define MUTEX_FLAGS_INITED	0x02
116210311Sjmallett#define MUTEX_FLAGS_BUSY	0x04
117210311Sjmallett
118210311Sjmallett/*
119210311Sjmallett * Static mutex initialization values.
120210311Sjmallett */
121210311Sjmallett#define PTHREAD_MUTEX_STATIC_INITIALIZER   \
122210311Sjmallett	{ MUTEX_TYPE_FAST, PTHREAD_QUEUE_INITIALIZER, \
123210311Sjmallett	NULL, { NULL }, MUTEX_FLAGS_INITED }
124
125struct pthread_mutex_attr {
126	enum pthread_mutextype	m_type;
127	long			m_flags;
128};
129
130/*
131 * Condition variable definitions.
132 */
133enum pthread_cond_type {
134	COND_TYPE_FAST,
135	COND_TYPE_MAX
136};
137
138struct pthread_cond {
139	enum pthread_cond_type	c_type;
140	struct pthread_queue	c_queue;
141	void			*c_data;
142	long			c_flags;
143
144	/*
145	 * Lock for accesses to this structure.
146	 */
147	long			access_lock;
148};
149
150struct pthread_cond_attr {
151	enum pthread_cond_type	c_type;
152	long			c_flags;
153};
154
155/*
156 * Flags for condition variables.
157 */
158#define COND_FLAGS_PRIVATE	0x01
159#define COND_FLAGS_INITED	0x02
160#define COND_FLAGS_BUSY		0x04
161
162/*
163 * Static cond initialization values.
164 */
165#define PTHREAD_COND_STATIC_INITIALIZER    \
166	{ COND_TYPE_FAST, PTHREAD_QUEUE_INITIALIZER, NULL, COND_FLAGS_INITED }
167
168/*
169 * Cleanup definitions.
170 */
171struct pthread_cleanup {
172	struct pthread_cleanup	*next;
173	void			(*routine) ();
174	void			*routine_arg;
175};
176
177struct pthread_attr {
178	int	schedparam_policy;
179	int	prio;
180	int	suspend;
181	int	flags;
182	void	*arg_attr;
183	void	(*cleanup_attr) ();
184	void	*stackaddr_attr;
185	size_t	stacksize_attr;
186};
187
188/*
189 * Thread creation state attributes.
190 */
191#define PTHREAD_CREATE_RUNNING			0
192#define PTHREAD_CREATE_SUSPENDED		1
193
194/*
195 * Miscellaneous definitions.
196 */
197#define PTHREAD_STACK_DEFAULT			65536
198#define PTHREAD_DEFAULT_PRIORITY		64
199#define PTHREAD_MAX_PRIORITY			126
200#define PTHREAD_MIN_PRIORITY			0
201#define _POSIX_THREAD_ATTR_STACKSIZE
202
203/*
204 * Clock resolution in nanoseconds.
205 */
206#define CLOCK_RES_NSEC				10000000
207
208/*
209 * Number of microseconds between incremental priority updates for
210 * threads that are ready to run, but denied being run.
211 */
212#define INC_PRIO_USEC				500000
213
214/*
215 * Time slice period in microseconds.
216 */
217#define TIMESLICE_USEC				100000
218
219struct pthread_key {
220	pthread_mutex_t mutex;
221	long            access_lock;
222	long            count;
223	void            (*destructor) ();
224};
225
226/*
227 * Thread states.
228 */
229enum pthread_state {
230	PS_RUNNING,
231	PS_SIGTHREAD,
232	PS_MUTEX_WAIT,
233	PS_COND_WAIT,
234	PS_FDLR_WAIT,
235	PS_FDLW_WAIT,
236	PS_FDR_WAIT,
237	PS_FDW_WAIT,
238	PS_FILE_WAIT,
239	PS_SELECT_WAIT,
240	PS_SLEEP_WAIT,
241	PS_WAIT_WAIT,
242	PS_SIGWAIT,
243	PS_JOIN,
244	PS_SUSPENDED,
245	PS_DEAD,
246	PS_STATE_MAX
247};
248
249
250/*
251 * File descriptor locking definitions.
252 */
253#define FD_READ             0x1
254#define FD_WRITE            0x2
255#define FD_RDWR             (FD_READ | FD_WRITE)
256
257/*
258 * File descriptor table structure.
259 */
260struct fd_table_entry {
261	/*
262	 * Lock for accesses to this file descriptor table
263	 * entry. This is passed to _spinlock() to provide atomic
264	 * access to this structure. It does *not* represent the
265	 * state of the lock on the file descriptor.
266	 */
267	long			access_lock;
268	struct pthread_queue	r_queue;	/* Read queue.                        */
269	struct pthread_queue	w_queue;	/* Write queue.                       */
270	struct pthread		*r_owner;	/* Ptr to thread owning read lock.    */
271	struct pthread		*w_owner;	/* Ptr to thread owning write lock.   */
272	char			*r_fname;	/* Ptr to read lock source file name  */
273	int			r_lineno;	/* Read lock source line number.      */
274	char			*w_fname;	/* Ptr to write lock source file name */
275	int			w_lineno;	/* Write lock source line number.     */
276	int			r_lockcount;	/* Count for FILE read locks.         */
277	int			w_lockcount;	/* Count for FILE write locks.        */
278	int			flags;		/* Flags used in open.                */
279};
280
281struct pthread_select_data {
282	int	nfds;
283	fd_set	readfds;
284	fd_set	writefds;
285	fd_set	exceptfds;
286};
287
288union pthread_wait_data {
289	pthread_mutex_t	*mutex;
290	pthread_cond_t	*cond;
291	const sigset_t	*sigwait;	/* Waiting on a signal in sigwait */
292	struct {
293		short	fd;		/* Used when thread waiting on fd */
294		short	branch;		/* Line number, for debugging.    */
295		char	*fname;		/* Source file name for debugging.*/
296	} fd;
297	struct pthread_select_data * select_data;
298};
299
300/*
301 * Thread structure.
302 */
303struct pthread {
304	/*
305	 * Magic value to help recognize a valid thread structure
306	 * from an invalid one:
307	 */
308#define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)
309	u_int32_t		magic;
310	char			*name;
311
312	/*
313	 * Lock for accesses to this thread structure.
314	 */
315	long			access_lock;
316
317	/*
318	 * Pointer to the next thread in the thread linked list.
319	 */
320	struct pthread	*nxt;
321
322	/*
323	 * Thread start routine, argument, stack pointer and thread
324	 * attributes.
325	 */
326	void			*(*start_routine)(void *);
327	void			*arg;
328	void			*stack;
329	struct pthread_attr	attr;
330
331#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__)
332	/*
333	 * Saved floating point registers on systems where they are not
334	 * saved in the signal context.
335	 */
336	char	saved_fp[108];
337#endif
338
339	/*
340	 * Saved signal context used in call to sigreturn by
341	 * _thread_kern_sched if sig_saved is TRUE.
342	 */
343	struct  sigcontext saved_sigcontext;
344
345	/*
346	 * Saved jump buffer used in call to longjmp by _thread_kern_sched
347	 * if sig_saved is FALSE.
348	 */
349	jmp_buf	saved_jmp_buf;
350
351	/*
352	 * TRUE if the last state saved was a signal context. FALSE if the
353	 * last state saved was a jump buffer.
354	 */
355	int	sig_saved;
356
357	/*
358	 * Current signal mask and pending signals.
359	 */
360	sigset_t	sigmask;
361	sigset_t	sigpend;
362
363	/* Thread state: */
364	enum pthread_state	state;
365
366	/* Time that this thread was last made active. */
367	struct  timeval		last_active;
368
369	/* Time that this thread was last made inactive. */
370	struct  timeval		last_inactive;
371
372	/*
373	 * Number of microseconds accumulated by this thread when
374	 * time slicing is active.
375	 */
376	long	slice_usec;
377
378	/*
379	 * Incremental priority accumulated by thread while it is ready to
380	 * run but is denied being run.
381	 */
382	int	inc_prio;
383
384	/*
385	 * Time to wake up thread. This is used for sleeping threads and
386	 * for any operation which may time out (such as select).
387	 */
388	struct timespec	wakeup_time;
389
390	/* TRUE if operation has timed out. */
391	int	timeout;
392
393	/*
394	 * Error variable used instead of errno. The function __error()
395	 * returns a pointer to this.
396	 */
397	int	error;
398
399	/* Join queue for waiting threads: */
400	struct pthread_queue	join_queue;
401
402	/*
403	 * The current thread can belong to only one queue at a time.
404	 *
405	 * Pointer to queue (if any) on which the current thread is waiting.
406	 *
407	 * XXX The queuing should be changed to use the TAILQ entry below.
408	 * XXX For the time being, it's hybrid.
409	 */
410	struct pthread_queue	*queue;
411
412	/* Pointer to next element in queue. */
413	struct pthread	*qnxt;
414
415	/* Queue entry for this thread: */
416	TAILQ_ENTRY(pthread) qe;
417
418	/* Wait data. */
419	union pthread_wait_data data;
420
421	/*
422	 * Set to TRUE if a blocking operation was
423	 * interrupted by a signal:
424	 */
425	int		interrupted;
426
427	/* Signal number when in state PS_SIGWAIT: */
428	int		signo;
429
430	/* Miscellaneous data. */
431	char		flags;
432	char		pthread_priority;
433	void		*ret;
434	const void	**specific_data;
435	int		specific_data_count;
436
437	/* Cleanup handlers Link List */
438	struct pthread_cleanup *cleanup;
439	char			*fname;	/* Ptr to source file name  */
440	int			lineno;	/* Source line number.      */
441};
442
443/*
444 * Global variables for the uthread kernel.
445 */
446
447/* Kernel thread structure used when there are no running threads: */
448SCLASS struct pthread   _thread_kern_thread;
449
450/* Ptr to the thread structure for the running thread: */
451SCLASS struct pthread   * volatile _thread_run
452#ifdef GLOBAL_PTHREAD_PRIVATE
453= &_thread_kern_thread;
454#else
455;
456#endif
457
458/*
459 * Ptr to the thread running in single-threaded mode or NULL if
460 * running multi-threaded (default POSIX behaviour).
461 */
462SCLASS struct pthread   * volatile _thread_single
463#ifdef GLOBAL_PTHREAD_PRIVATE
464= NULL;
465#else
466;
467#endif
468
469/* Ptr to the first thread in the thread linked list: */
470SCLASS struct pthread   * volatile _thread_link_list
471#ifdef GLOBAL_PTHREAD_PRIVATE
472= NULL;
473#else
474;
475#endif
476
477/*
478 * Array of kernel pipe file descriptors that are used to ensure that
479 * no signals are missed in calls to _select.
480 */
481SCLASS int              _thread_kern_pipe[2]
482#ifdef GLOBAL_PTHREAD_PRIVATE
483= {
484	-1,
485	-1
486};
487#else
488;
489#endif
490SCLASS int              _thread_kern_in_select
491#ifdef GLOBAL_PTHREAD_PRIVATE
492= 0;
493#else
494;
495#endif
496SCLASS int              _thread_kern_in_sched
497#ifdef GLOBAL_PTHREAD_PRIVATE
498= 0;
499#else
500;
501#endif
502
503/* Last time that an incremental priority update was performed: */
504SCLASS struct timeval   kern_inc_prio_time
505#ifdef GLOBAL_PTHREAD_PRIVATE
506= { 0, 0 };
507#else
508;
509#endif
510
511/* Dead threads: */
512SCLASS struct pthread * volatile _thread_dead
513#ifdef GLOBAL_PTHREAD_PRIVATE
514= NULL;
515#else
516;
517#endif
518
519/* Initial thread: */
520SCLASS struct pthread *_thread_initial
521#ifdef GLOBAL_PTHREAD_PRIVATE
522= NULL;
523#else
524;
525#endif
526
527/* Default thread attributes: */
528SCLASS struct pthread_attr pthread_attr_default
529#ifdef GLOBAL_PTHREAD_PRIVATE
530= { SCHED_RR, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING,
531	PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
532#else
533;
534#endif
535
536/* Default mutex attributes: */
537SCLASS struct pthread_mutex_attr pthread_mutexattr_default
538#ifdef GLOBAL_PTHREAD_PRIVATE
539= { MUTEX_TYPE_FAST, 0 };
540#else
541;
542#endif
543
544/* Default condition variable attributes: */
545SCLASS struct pthread_cond_attr pthread_condattr_default
546#ifdef GLOBAL_PTHREAD_PRIVATE
547= { COND_TYPE_FAST, 0 };
548#else
549;
550#endif
551
552/*
553 * Standard I/O file descriptors need special flag treatment since
554 * setting one to non-blocking does all on *BSD. Sigh. This array
555 * is used to store the initial flag settings.
556 */
557SCLASS int	_pthread_stdio_flags[3];
558
559/* File table information: */
560SCLASS struct fd_table_entry **_thread_fd_table
561#ifdef GLOBAL_PTHREAD_PRIVATE
562= NULL;
563#else
564;
565#endif
566
567SCLASS const int dtablecount
568#ifdef GLOBAL_PTHREAD_PRIVATE
569= 4096/sizeof(struct fd_table_entry);
570#else
571;
572#endif
573SCLASS int    _thread_dtablesize        /* Descriptor table size.           */
574#ifdef GLOBAL_PTHREAD_PRIVATE
575= 1024;
576#else
577;
578#endif
579
580/*
581 * Array of signal actions for this process.
582 */
583struct  sigaction _thread_sigact[NSIG];
584
585/* Undefine the storage class specifier: */
586#undef  SCLASS
587
588/*
589 * Function prototype definitions.
590 */
591__BEGIN_DECLS
592char    *__ttyname_basic(int);
593char    *__ttyname_r_basic(int, char *, size_t);
594char    *ttyname_r(int, char *, size_t);
595int     _find_dead_thread(pthread_t);
596int     _find_thread(pthread_t);
597int     _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
598int     _thread_fd_lock(int, int, struct timespec *,char *fname,int lineno);
599void    _dispatch_signals(void);
600void    _thread_signal(pthread_t, int);
601void    _lock_dead_thread_list(void);
602void    _lock_thread(void);
603void    _lock_thread_list(void);
604void    _unlock_dead_thread_list(void);
605void    _unlock_thread(void);
606void    _unlock_thread_list(void);
607void    _thread_exit(char *, int, char *);
608void    _thread_fd_unlock(int, int);
609void    *_thread_cleanup(pthread_t);
610void    _thread_cleanupspecific(void);
611void    _thread_dump_info(void);
612void    _thread_init(void);
613void    _thread_kern_sched(struct sigcontext *);
614void    _thread_kern_sched_state(enum pthread_state,char *fname,int lineno);
615void    _thread_kern_set_timeout(struct timespec *);
616void    _thread_sig_handler(int, int, struct sigcontext *);
617void    _thread_start(void);
618void    _thread_start_sig_handler(void);
619void	_thread_seterrno(pthread_t,int);
620void    _thread_queue_init(struct pthread_queue *);
621void    _thread_queue_enq(struct pthread_queue *, struct pthread *);
622int     _thread_queue_remove(struct pthread_queue *, struct pthread *);
623int     _thread_fd_table_init(int fd);
624struct pthread *_thread_queue_get(struct pthread_queue *);
625struct pthread *_thread_queue_deq(struct pthread_queue *);
626
627/* #include <signal.h> */
628int     _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *);
629int     _thread_sys_sigpending(sigset_t *);
630int     _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *);
631int     _thread_sys_sigsuspend(const sigset_t *);
632int     _thread_sys_siginterrupt(int, int);
633int     _thread_sys_sigpause(int);
634int     _thread_sys_sigreturn(struct sigcontext *);
635int     _thread_sys_sigstack(const struct sigstack *, struct sigstack *);
636int     _thread_sys_sigvec(int, struct sigvec *, struct sigvec *);
637void    _thread_sys_psignal(unsigned int, const char *);
638void    (*_thread_sys_signal(int, void (*)(int)))(int);
639
640/* #include <sys/stat.h> */
641#ifdef  _SYS_STAT_H_
642int     _thread_sys_fchmod(int, mode_t);
643int     _thread_sys_fstat(int, struct stat *);
644int     _thread_sys_fchflags(int, u_long);
645#endif
646
647/* #include <sys/mount.h> */
648#ifdef  _SYS_MOUNT_H_
649int     _thread_sys_fstatfs(int, struct statfs *);
650#endif
651int     _thread_sys_pipe(int *);
652
653/* #include <sys/socket.h> */
654#ifdef  _SYS_SOCKET_H_
655int     _thread_sys_accept(int, struct sockaddr *, int *);
656int     _thread_sys_bind(int, const struct sockaddr *, int);
657int     _thread_sys_connect(int, const struct sockaddr *, int);
658int     _thread_sys_getpeername(int, struct sockaddr *, int *);
659int     _thread_sys_getsockname(int, struct sockaddr *, int *);
660int     _thread_sys_getsockopt(int, int, int, void *, int *);
661int     _thread_sys_listen(int, int);
662int     _thread_sys_setsockopt(int, int, int, const void *, int);
663int     _thread_sys_shutdown(int, int);
664int     _thread_sys_socket(int, int, int);
665int     _thread_sys_socketpair(int, int, int, int *);
666ssize_t _thread_sys_recv(int, void *, size_t, int);
667ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, int *);
668ssize_t _thread_sys_recvmsg(int, struct msghdr *, int);
669ssize_t _thread_sys_send(int, const void *, size_t, int);
670ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int);
671ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, int);
672#endif
673
674/* #include <stdio.h> */
675#ifdef  _STDIO_H_
676FILE    *_thread_sys_fdopen(int, const char *);
677FILE    *_thread_sys_fopen(const char *, const char *);
678FILE    *_thread_sys_freopen(const char *, const char *, FILE *);
679FILE    *_thread_sys_popen(const char *, const char *);
680FILE    *_thread_sys_tmpfile(void);
681char    *_thread_sys_ctermid(char *);
682char    *_thread_sys_cuserid(char *);
683char    *_thread_sys_fgetln(FILE *, size_t *);
684char    *_thread_sys_fgets(char *, int, FILE *);
685char    *_thread_sys_gets(char *);
686char    *_thread_sys_tempnam(const char *, const char *);
687char    *_thread_sys_tmpnam(char *);
688int     _thread_sys_fclose(FILE *);
689int     _thread_sys_feof(FILE *);
690int     _thread_sys_ferror(FILE *);
691int     _thread_sys_fflush(FILE *);
692int     _thread_sys_fgetc(FILE *);
693int     _thread_sys_fgetpos(FILE *, fpos_t *);
694int     _thread_sys_fileno(FILE *);
695int     _thread_sys_fprintf(FILE *, const char *, ...);
696int     _thread_sys_fpurge(FILE *);
697int     _thread_sys_fputc(int, FILE *);
698int     _thread_sys_fputs(const char *, FILE *);
699int     _thread_sys_fscanf(FILE *, const char *, ...);
700int     _thread_sys_fseek(FILE *, long, int);
701int     _thread_sys_fsetpos(FILE *, const fpos_t *);
702int     _thread_sys_getc(FILE *);
703int     _thread_sys_getchar(void);
704int     _thread_sys_getw(FILE *);
705int     _thread_sys_pclose(FILE *);
706int     _thread_sys_printf(const char *, ...);
707int     _thread_sys_putc(int, FILE *);
708int     _thread_sys_putchar(int);
709int     _thread_sys_puts(const char *);
710int     _thread_sys_putw(int, FILE *);
711int     _thread_sys_remove(const char *);
712int     _thread_sys_rename (const char *, const char *);
713int     _thread_sys_scanf(const char *, ...);
714int     _thread_sys_setlinebuf(FILE *);
715int     _thread_sys_setvbuf(FILE *, char *, int, size_t);
716int     _thread_sys_snprintf(char *, size_t, const char *, ...);
717int     _thread_sys_sprintf(char *, const char *, ...);
718int     _thread_sys_sscanf(const char *, const char *, ...);
719int     _thread_sys_ungetc(int, FILE *);
720int     _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_);
721int     _thread_sys_vprintf(const char *, _BSD_VA_LIST_);
722int     _thread_sys_vscanf(const char *, _BSD_VA_LIST_);
723int     _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
724int     _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_);
725int     _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_);
726long    _thread_sys_ftell(FILE *);
727size_t  _thread_sys_fread(void *, size_t, size_t, FILE *);
728size_t  _thread_sys_fwrite(const void *, size_t, size_t, FILE *);
729void    _thread_sys_clearerr(FILE *);
730void    _thread_sys_perror(const char *);
731void    _thread_sys_rewind(FILE *);
732void    _thread_sys_setbuf(FILE *, char *);
733void    _thread_sys_setbuffer(FILE *, char *, int);
734#endif
735
736/* #include <unistd.h> */
737#ifdef  _UNISTD_H_
738char    *_thread_sys_ttyname(int);
739int     _thread_sys_close(int);
740int     _thread_sys_dup(int);
741int     _thread_sys_dup2(int, int);
742int     _thread_sys_exect(const char *, char * const *, char * const *);
743int     _thread_sys_execve(const char *, char * const *, char * const *);
744int     _thread_sys_fchdir(int);
745int     _thread_sys_fchown(int, uid_t, gid_t);
746int     _thread_sys_fsync(int);
747int     _thread_sys_ftruncate(int, off_t);
748int     _thread_sys_pause(void);
749int     _thread_sys_pipe(int *);
750int     _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
751off_t   _thread_sys_lseek(int, off_t, int);
752pid_t   _thread_sys_fork(void);
753pid_t   _thread_sys_tcgetpgrp(int);
754ssize_t _thread_sys_read(int, void *, size_t);
755ssize_t _thread_sys_write(int, const void *, size_t);
756void	_thread_sys__exit(int);
757#endif
758
759/* #include <fcntl.h> */
760#ifdef  _SYS_FCNTL_H_
761int     _thread_sys_creat(const char *, mode_t);
762int     _thread_sys_fcntl(int, int, ...);
763int     _thread_sys_flock(int, int);
764int     _thread_sys_open(const char *, int, ...);
765#endif
766
767/* #include <sys/ioctl.h> */
768#ifdef  _SYS_IOCTL_H_
769int     _thread_sys_ioctl(int, unsigned long, ...);
770#endif
771
772/* #include <dirent.h> */
773#ifdef  _DIRENT_H_
774DIR     *___thread_sys_opendir2(const char *, int);
775DIR     *_thread_sys_opendir(const char *);
776int     _thread_sys_alphasort(const void *, const void *);
777int     _thread_sys_scandir(const char *, struct dirent ***,
778	int (*)(struct dirent *), int (*)(const void *, const void *));
779int     _thread_sys_closedir(DIR *);
780int     _thread_sys_getdirentries(int, char *, int, long *);
781long    _thread_sys_telldir(const DIR *);
782struct  dirent *_thread_sys_readdir(DIR *);
783void    _thread_sys_rewinddir(DIR *);
784void    _thread_sys_seekdir(DIR *, long);
785#endif
786
787/* #include <sys/uio.h> */
788#ifdef  _SYS_UIO_H_
789ssize_t _thread_sys_readv(int, const struct iovec *, int);
790ssize_t _thread_sys_writev(int, const struct iovec *, int);
791#endif
792
793/* #include <sys/wait.h> */
794#ifdef  WNOHANG
795pid_t   _thread_sys_wait(int *);
796pid_t   _thread_sys_waitpid(pid_t, int *, int);
797pid_t   _thread_sys_wait3(int *, int, struct rusage *);
798pid_t   _thread_sys_wait4(pid_t, int *, int, struct rusage *);
799#endif
800__END_DECLS
801
802#endif  /* !_PTHREAD_PRIVATE_H */
803