summaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /lib/libpthread
initial import of NetBSD tree
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/COPYRIGHT31
-rw-r--r--lib/libpthread/Makefile22
-rw-r--r--lib/libpthread/README85
-rw-r--r--lib/libpthread/arch/i386/Makefile.inc4
-rw-r--r--lib/libpthread/arch/i386/machdep.c136
-rw-r--r--lib/libpthread/arch/i386/machdep.h58
-rw-r--r--lib/libpthread/arch/i386/syscall.S174
-rw-r--r--lib/libpthread/include/cond.h91
-rw-r--r--lib/libpthread/include/engine.h86
-rw-r--r--lib/libpthread/include/fd.h106
-rw-r--r--lib/libpthread/include/fd_pipe.h54
-rw-r--r--lib/libpthread/include/kernel.h50
-rw-r--r--lib/libpthread/include/mutex.h93
-rw-r--r--lib/libpthread/include/posix.h21
-rw-r--r--lib/libpthread/include/pthread_attr.h73
-rw-r--r--lib/libpthread/include/pthread_once.h53
-rw-r--r--lib/libpthread/include/queue.h67
-rw-r--r--lib/libpthread/include/stdio.h354
-rw-r--r--lib/libpthread/include/util.h89
-rw-r--r--lib/libpthread/pthreads/Makefile.inc9
-rw-r--r--lib/libpthread/pthreads/cond.c208
-rw-r--r--lib/libpthread/pthreads/fd.c562
-rw-r--r--lib/libpthread/pthreads/fd_kern.c647
-rw-r--r--lib/libpthread/pthreads/fd_pipe.c268
-rw-r--r--lib/libpthread/pthreads/file.c117
-rw-r--r--lib/libpthread/pthreads/globals.c67
-rw-r--r--lib/libpthread/pthreads/malloc.c361
-rw-r--r--lib/libpthread/pthreads/mutex.c227
-rw-r--r--lib/libpthread/pthreads/pthread.c204
-rw-r--r--lib/libpthread/pthreads/pthread_attr.c100
-rw-r--r--lib/libpthread/pthreads/pthread_detach.c90
-rw-r--r--lib/libpthread/pthreads/pthread_join.c113
-rw-r--r--lib/libpthread/pthreads/pthread_once.c61
-rw-r--r--lib/libpthread/pthreads/queue.c123
-rw-r--r--lib/libpthread/pthreads/signal.c445
-rw-r--r--lib/libpthread/pthreads/sleep.c256
-rw-r--r--lib/libpthread/stdio/Makefile.inc18
-rw-r--r--lib/libpthread/stdio/README40
-rw-r--r--lib/libpthread/stdio/clrerr.c50
-rw-r--r--lib/libpthread/stdio/fclose.c71
-rw-r--r--lib/libpthread/stdio/fdopen.c92
-rw-r--r--lib/libpthread/stdio/feof.c54
-rw-r--r--lib/libpthread/stdio/ferror.c54
-rw-r--r--lib/libpthread/stdio/fflush.c97
-rw-r--r--lib/libpthread/stdio/fgetc.c51
-rw-r--r--lib/libpthread/stdio/fgetline.c169
-rw-r--r--lib/libpthread/stdio/fgetpos.c50
-rw-r--r--lib/libpthread/stdio/fgets.c108
-rw-r--r--lib/libpthread/stdio/fileno.c54
-rw-r--r--lib/libpthread/stdio/findfp.c151
-rw-r--r--lib/libpthread/stdio/flags.c90
-rw-r--r--lib/libpthread/stdio/floatio.h47
-rw-r--r--lib/libpthread/stdio/fopen.c89
-rw-r--r--lib/libpthread/stdio/fprintf.c70
-rw-r--r--lib/libpthread/stdio/fpurge.c72
-rw-r--r--lib/libpthread/stdio/fputc.c54
-rw-r--r--lib/libpthread/stdio/fputs.c66
-rw-r--r--lib/libpthread/stdio/fread.c83
-rw-r--r--lib/libpthread/stdio/freopen.c146
-rw-r--r--lib/libpthread/stdio/fscanf.c72
-rw-r--r--lib/libpthread/stdio/fseek.c246
-rw-r--r--lib/libpthread/stdio/fsetpos.c53
-rw-r--r--lib/libpthread/stdio/ftell.c89
-rw-r--r--lib/libpthread/stdio/funopen.c100
-rw-r--r--lib/libpthread/stdio/fvwrite.c188
-rw-r--r--lib/libpthread/stdio/fvwrite.h54
-rw-r--r--lib/libpthread/stdio/fwalk.c131
-rw-r--r--lib/libpthread/stdio/fwrite.c77
-rw-r--r--lib/libpthread/stdio/getc.c57
-rw-r--r--lib/libpthread/stdio/getc_unlocked.c54
-rw-r--r--lib/libpthread/stdio/getchar.c57
-rw-r--r--lib/libpthread/stdio/getchar_unlocked.c53
-rw-r--r--lib/libpthread/stdio/gets.c69
-rw-r--r--lib/libpthread/stdio/getw.c50
-rw-r--r--lib/libpthread/stdio/glue.h48
-rw-r--r--lib/libpthread/stdio/local.h88
-rw-r--r--lib/libpthread/stdio/makebuf.c119
-rw-r--r--lib/libpthread/stdio/mktemp.c126
-rw-r--r--lib/libpthread/stdio/perror.c67
-rw-r--r--lib/libpthread/stdio/printf.c54
-rw-r--r--lib/libpthread/stdio/putc.c59
-rw-r--r--lib/libpthread/stdio/putc_unlocked.c55
-rw-r--r--lib/libpthread/stdio/putchar.c59
-rw-r--r--lib/libpthread/stdio/putchar_unlocked.c55
-rw-r--r--lib/libpthread/stdio/puts.c70
-rw-r--r--lib/libpthread/stdio/putw.c63
-rw-r--r--lib/libpthread/stdio/refill.c183
-rw-r--r--lib/libpthread/stdio/remove.c48
-rw-r--r--lib/libpthread/stdio/rewind.c54
-rw-r--r--lib/libpthread/stdio/rget.c57
-rw-r--r--lib/libpthread/stdio/scanf.c71
-rw-r--r--lib/libpthread/stdio/setbuf.c51
-rw-r--r--lib/libpthread/stdio/setbuffer.c63
-rw-r--r--lib/libpthread/stdio/setvbuf.c153
-rw-r--r--lib/libpthread/stdio/snprintf.c77
-rw-r--r--lib/libpthread/stdio/sprintf.c76
-rw-r--r--lib/libpthread/stdio/sscanf.c78
-rw-r--r--lib/libpthread/stdio/stdio.c92
-rw-r--r--lib/libpthread/stdio/strerror.c67
-rw-r--r--lib/libpthread/stdio/tempnam.c87
-rw-r--r--lib/libpthread/stdio/tmpfile.c80
-rw-r--r--lib/libpthread/stdio/tmpnam.c55
-rw-r--r--lib/libpthread/stdio/ungetc.c154
-rw-r--r--lib/libpthread/stdio/vfprintf.c774
-rw-r--r--lib/libpthread/stdio/vfscanf.c749
-rw-r--r--lib/libpthread/stdio/vprintf.c49
-rw-r--r--lib/libpthread/stdio/vscanf.c53
-rw-r--r--lib/libpthread/stdio/vsnprintf.c61
-rw-r--r--lib/libpthread/stdio/vsprintf.c59
-rw-r--r--lib/libpthread/stdio/vsscanf.c60
-rw-r--r--lib/libpthread/stdio/wbuf.c88
-rw-r--r--lib/libpthread/stdio/wsetup.c92
112 files changed, 12925 insertions, 0 deletions
diff --git a/lib/libpthread/COPYRIGHT b/lib/libpthread/COPYRIGHT
new file mode 100644
index 00000000000..1fb4e43cf26
--- /dev/null
+++ b/lib/libpthread/COPYRIGHT
@@ -0,0 +1,31 @@
+Copyright (c) 1993 by Chris Provenzano and contributors, proven@mit.edu
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Chris Provenzano,
+ the University of California, Berkeley, and contributors.
+4. Neither the name of Chris Provenzano, the University, nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO, THE REGENTS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/lib/libpthread/Makefile b/lib/libpthread/Makefile
new file mode 100644
index 00000000000..85978519fe8
--- /dev/null
+++ b/lib/libpthread/Makefile
@@ -0,0 +1,22 @@
+# from: @(#)Makefile 5.2 (Berkeley) 3/5/91
+
+LIB=pthread
+NOPIC= no
+CPPFLAGS+= -DPTHREAD_KERNEL -I. -I${.CURDIR}/include -I${.CURDIR}/arch/${MACHINE}
+CFLAGS+= ${CPPFLAGS}
+
+.include "${.CURDIR}/arch/${MACHINE}/Makefile.inc"
+.include "${.CURDIR}/pthreads/Makefile.inc"
+.include "${.CURDIR}/stdio/Makefile.inc"
+
+all beforedepend: pthread
+
+CLEANFILES+=pthread
+
+pthread:
+ if [ ! -e pthread ]; then \
+ ln -s ${.CURDIR}/include pthread; \
+ fi
+
+.include <bsd.lib.mk>
+
diff --git a/lib/libpthread/README b/lib/libpthread/README
new file mode 100644
index 00000000000..f546325d948
--- /dev/null
+++ b/lib/libpthread/README
@@ -0,0 +1,85 @@
+This pthread package is/will be based on the POSIX1003.4a Draft 7 pthread
+standard, and Frank Mullers paper on signal handelling presented
+at the Winter 93 USENIX conference.
+
+It is currently being designed and written by me, Chris Provenzano.
+All bug, comments, and questions can be sent me at either
+proven@athena.mit.edu or proven@sun-lamp.cs.berkeley.edu
+PLEASE, don't send questions, bugs or patches to any of the *BSD* mailing lists.
+
+Thanks goes to John Carr jfc@mit.edu for porting this to the IBM/RT,
+and for his bug reports and fixes, Greg Hudson and Mark Eichin for the
+testing they've done, and all the others.
+
+PORTING
+One of the goals of this user space implementation of pthreads is that it
+be portable. I have minimized the ammount of assembler code necessary,
+but some is.
+
+If you want to port it to another platform here are a few basic hints.
+
+There are currently three files you'll have to creat for your
+architecture, machdep.h, machdep.c and syscall.S.
+The first two are necessary to get the context switch section of
+the pthread package running, the third is for all the syscalls.
+
+To do an initial port, create an appropriate machdep.h, and machdep.c
+and define PTHREAD_INITIAL_PORT in the Makefile
+
+Comment out references to the stdio package.
+
+INCLUDE FILES AND PORTING
+To continue to make this package portable, some basic rules on includes
+files must be followed.
+
+pthread.h should be included first (if it is to be included).
+machdep.h should define size_t if the system doesn't define it already
+
+posix.h should be included last. This file is used to correct non
+POSIX features, after everything else has been defined.
+
+INTERNAL LOCKING
+To prevent deadlocks the following rules were used for locks.
+
+1. Local locks for mutex queues and other like things are only locked
+ by running threads, at NO time will a local lock be held by
+ a thread in a non running state.
+2. Only threads that are in a run state can attempt to lock another thread,
+ this way, we can assume that the lock will be released shortly, and don't
+ have to unlock the local lock.
+3. The only time a thread will have a pthread->lock and is not in a run
+ state is when it is in the reschedule routine.
+4. The reschedule routine assumes all local locks have been released,
+ there is a lock on the currently running thread (pthread_run),
+ and that this thread is being rescheduled to a non running state.
+ It is safe to unlock the currently running threads lock after it
+ has been rescheduled.
+5. The reschedule routine locks the kernel, sets the state of the currently
+ running thread, unlocks the currently running thread, calls the
+ context switch routines.
+6 the kernel lock is used only ...
+
+
+7. The order of locking is ...
+
+1 local locks
+2 pthread->lock /* Assumes it will get it soon */
+3 pthread_run->lock /* Assumes it will get it soon, but must release 2 */
+4 kernel lock /* Currently assumes it will ALWAYS get it. */
+
+8. The kernel lock will be changed to a spin lock for systems that
+already support kernel threads, this way we can mutiplex threads onto
+kernel threads.
+9. There are points where the kernel is locked and it needs to get
+either a local lock or a pthread lock, if at these points the code
+fails to get the lock the kernel gives up and sets a flag which will
+be checked at a later point.
+10. Interrupts are dissabled while the kernel is locked, the interrupt
+mask must be checked afterwards or cleared in some way, after interrputs
+have been reenabled, this allows back to back interrupts, but should always
+avoid missing one.
+
+Copyright (c) 1993 Chris Provenzano. All rights reserved.
+
+This product includes software developed by the Univeristy of California,
+Berkeley and its contributors.
diff --git a/lib/libpthread/arch/i386/Makefile.inc b/lib/libpthread/arch/i386/Makefile.inc
new file mode 100644
index 00000000000..85468b9aa69
--- /dev/null
+++ b/lib/libpthread/arch/i386/Makefile.inc
@@ -0,0 +1,4 @@
+# Machine dependent sources
+.PATH: ${.CURDIR}/arch/${MACHINE}
+
+SRCS+= machdep.c syscall.S
diff --git a/lib/libpthread/arch/i386/machdep.c b/lib/libpthread/arch/i386/machdep.c
new file mode 100644
index 00000000000..2437cead1b1
--- /dev/null
+++ b/lib/libpthread/arch/i386/machdep.c
@@ -0,0 +1,136 @@
+/* ==== machdep.c ============================================================
+ * Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
+ *
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Machine dependent functions for NetBSD on i386
+ *
+ * 1.00 93/08/04 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: machdep.c,v 1.1 1995/10/18 08:43:03 deraadt Exp $";
+#endif
+
+#include "pthread.h"
+
+/* ==========================================================================
+ * machdep_save_state()
+ */
+int machdep_save_state(void)
+{
+ return(_setjmp(pthread_run->machdep_data.machdep_state));
+}
+
+/* ==========================================================================
+ * machdep_restore_state()
+ */
+void machdep_restore_state(void)
+{
+ _longjmp(pthread_run->machdep_data.machdep_state, 1);
+}
+
+/* ==========================================================================
+ * machdep_set_thread_timer()
+ */
+void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
+{
+ if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
+ PANIC();
+ }
+}
+
+/* ==========================================================================
+ * machdep_unset_thread_timer()
+ */
+void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
+{
+ struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
+
+ if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
+ PANIC();
+ }
+}
+
+/* ==========================================================================
+ * machdep_pthread_cleanup()
+ */
+void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
+{
+ return(machdep_pthread->machdep_stack);
+}
+
+/* ==========================================================================
+ * machdep_pthread_start()
+ */
+void machdep_pthread_start(void)
+{
+ context_switch_done();
+ sig_check_and_resume();
+
+ /* Run current threads start routine with argument */
+ pthread_exit(pthread_run->machdep_data.start_routine
+ (pthread_run->machdep_data.start_argument));
+
+ /* should never reach here */
+ PANIC();
+}
+
+/* ==========================================================================
+ * machdep_pthread_create()
+ */
+void machdep_pthread_create(struct machdep_pthread *machdep_pthread,
+ void *(* start_routine)(), void *start_argument, long stack_size,
+ void *stack_start, long nsec)
+{
+ machdep_pthread->machdep_stack = stack_start;
+
+ machdep_pthread->start_routine = start_routine;
+ machdep_pthread->start_argument = start_argument;
+
+ machdep_pthread->machdep_timer.it_value.tv_sec = 0;
+ machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
+ machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
+ machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
+
+ _setjmp(machdep_pthread->machdep_state);
+ /*
+ * Set up new stact frame so that it looks like it
+ * returned from a longjmp() to the beginning of
+ * machdep_pthread_start().
+ */
+ machdep_pthread->machdep_state[0] = (int)machdep_pthread_start;
+
+ /* Stack starts high and builds down. */
+ machdep_pthread->machdep_state[2] =
+ (int)machdep_pthread->machdep_stack + stack_size;
+}
diff --git a/lib/libpthread/arch/i386/machdep.h b/lib/libpthread/arch/i386/machdep.h
new file mode 100644
index 00000000000..10521b02235
--- /dev/null
+++ b/lib/libpthread/arch/i386/machdep.h
@@ -0,0 +1,58 @@
+/* ==== machdep.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+/*
+ * The first machine dependent functions are the SEMAPHORES
+ * needing the test and set instruction.
+ */
+#define SEMAPHORE_CLEAR 0
+#define SEMAPHORE_SET 1
+
+#define SEMAPHORE_TEST_AND_SET(lock) \
+({ \
+volatile long temp = SEMAPHORE_SET; \
+ \
+__asm__("xchgl %0,(%2)" \
+ :"=r" (temp) \
+ :"0" (temp),"r" (lock)); \
+temp; \
+})
+
+#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
+
+/*
+ * Minimum stack size
+ */
+#define PTHREAD_STACK_MIN 1024
+
diff --git a/lib/libpthread/arch/i386/syscall.S b/lib/libpthread/arch/i386/syscall.S
new file mode 100644
index 00000000000..1b91abed0c8
--- /dev/null
+++ b/lib/libpthread/arch/i386/syscall.S
@@ -0,0 +1,174 @@
+/* ==== syscall.S ============================================================
+ * Copyright (c) 1990 The Regents of the University of California.
+ * Copyright (c) 1993 Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Machine dependent syscalls for i386/i486/i586
+ *
+ * 1.00 93/08/26 proven
+ * -Started coding this file.
+ *
+ * 1.01 93/11/13 proven
+ * -The functions readv() and writev() added.
+ */
+
+#ifndef lint
+ .text
+ .asciz "$Id: syscall.S,v 1.1 1995/10/18 08:43:03 deraadt Exp $";
+#endif
+
+#if defined(SYSLIBC_SCCS) && !defined(lint)
+ .asciz "@(#)syscall.s 5.1 (Berkeley) 4/23/90"
+#endif /* SYSLIBC_SCCS and not lint */
+
+#include <machine/asm.h>
+#include <sys/syscall.h>
+
+#define SYSCALL(x) \
+ .globl _machdep_sys_/**/x; \
+ \
+_machdep_sys_/**/x:; \
+ \
+ movl $(SYS_/**/x), %eax; \
+ .byte 0x9a; .long 0; .word 7; \
+ jb 1b; \
+ ret;
+
+/*
+ * Initial asm stuff for all functions.
+ */
+ .text
+ .align 2
+
+
+/* ==========================================================================
+ * error code for all syscalls. The error value is returned as the negative
+ * of the errno value.
+ */
+
+1:
+ neg %eax
+ ret
+
+/* ==========================================================================
+ * machdep_sys_write()
+ */
+SYSCALL(write)
+
+/* ==========================================================================
+ * machdep_sys_read()
+ */
+SYSCALL(read)
+
+/* ==========================================================================
+ * machdep_sys_open()
+ */
+SYSCALL(open)
+
+/* ==========================================================================
+ * machdep_sys_close()
+ */
+SYSCALL(close)
+
+/* ==========================================================================
+ * machdep_sys_fcntl()
+ */
+SYSCALL(fcntl)
+
+/* ==========================================================================
+ * machdep_sys_lseek()
+ */
+SYSCALL(lseek)
+
+/* ==========================================================================
+ * Nonstandard calls used to make the system work
+ *
+ * ==========================================================================
+ * machdep_sys_select()
+ */
+SYSCALL(select)
+
+/* ==========================================================================
+ * Berkeley socket stuff
+ *
+ * ==========================================================================
+ * machdep_sys_socket()
+ */
+SYSCALL(socket)
+
+/* ==========================================================================
+ * machdep_sys_bind()
+ */
+SYSCALL(bind)
+
+/* ==========================================================================
+ * machdep_sys_connect()
+ */
+SYSCALL(connect)
+
+/* ==========================================================================
+ * machdep_sys_accept()
+ */
+SYSCALL(accept)
+
+/* ==========================================================================
+ * machdep_sys_listen()
+ */
+SYSCALL(listen)
+
+/* ==========================================================================
+ * machdep_sys_getsockopt()
+ */
+SYSCALL(getsockopt)
+
+/* ==========================================================================
+ * machdep_sys_readv()
+ */
+SYSCALL(readv)
+
+/* ==========================================================================
+ * machdep_sys_writev()
+ */
+SYSCALL(writev)
+
+/* ==========================================================================
+ * machdep_sys_getpeername()
+ */
+SYSCALL(getpeername)
+
+/* ==========================================================================
+ * machdep_sys_getsockname()
+ */
+SYSCALL(getsockname)
+
diff --git a/lib/libpthread/include/cond.h b/lib/libpthread/include/cond.h
new file mode 100644
index 00000000000..ed76126cc98
--- /dev/null
+++ b/lib/libpthread/include/cond.h
@@ -0,0 +1,91 @@
+/* ==== cond.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: cond.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: cond.h,v 1.17 1994/02/07 03:31:53 proven Exp $
+ *
+ * Description : mutex header.
+ *
+ * 1.00 93/10/30 proven
+ * -Started coding this file.
+ */
+
+/*
+ * New cond structures
+ */
+enum pthread_cond_type {
+ COND_TYPE_FAST,
+ COND_TYPE_STATIC_FAST,
+ COND_TYPE_METERED,
+ COND_TYPE_DEBUG, /* Debug conds will have lots of options */
+ COND_TYPE_MAX
+};
+
+typedef struct pthread_cond {
+ enum pthread_cond_type c_type;
+ struct pthread_queue c_queue;
+ semaphore c_lock;
+ void * c_data;
+ long c_flags;
+} pthread_cond_t;
+
+typedef struct pthread_cond_attr {
+ enum pthread_cond_type c_type;
+ long c_flags;
+} pthread_condattr_t;
+
+/*
+ * Flags for conds.
+ */
+#define COND_FLAGS_PRIVATE 0x01
+#define COND_FLAGS_INITED 0x02
+#define COND_FLAGS_BUSY 0x04
+
+/*
+ * Static cond initialization values.
+ */
+#define PTHREAD_COND_INITIALIZER \
+{ COND_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \
+ NULL, SEMAPHORE_CLEAR, COND_FLAGS_INITED }
+
+/*
+ * New functions
+ */
+
+__BEGIN_DECLS
+
+int pthread_cond_init __P((pthread_cond_t *, pthread_condattr_t *));
+int pthread_cond_wait __P((pthread_cond_t *, pthread_mutex_t *));
+int pthread_cond_signal __P((pthread_cond_t *));
+int pthread_cond_broadcast __P((pthread_cond_t *));
+int pthread_cond_destroy __P((pthread_cond_t *));
+
+__END_DECLS
+
diff --git a/lib/libpthread/include/engine.h b/lib/libpthread/include/engine.h
new file mode 100644
index 00000000000..3539686755c
--- /dev/null
+++ b/lib/libpthread/include/engine.h
@@ -0,0 +1,86 @@
+/* ==== engine.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <unistd.h>
+#include <setjmp.h>
+#include <sys/time.h>
+
+#if defined(PTHREAD_KERNEL)
+#include "machdep.h"
+#endif
+
+/*
+ * New types
+ */
+typedef long semaphore;
+
+#define SIGMAX 31
+
+/*
+ * New Strutures
+ */
+struct machdep_pthread {
+ void *(*start_routine)(void *);
+ void *start_argument;
+ void *machdep_stack;
+ struct itimerval machdep_timer;
+ jmp_buf machdep_state;
+};
+
+/*
+ * Static machdep_pthread initialization values.
+ * For initial thread only.
+ */
+#define MACHDEP_PTHREAD_INIT \
+{ NULL, NULL, NULL, { { 0, 0 }, { 0, 0 } }, 0 }
+
+/*
+ * Some fd flag defines that are necessary to distinguish between posix
+ * behavior and bsd4.3 behavior.
+ */
+#define __FD_NONBLOCK O_NONBLOCK
+
+/*
+ * New functions
+ */
+
+__BEGIN_DECLS
+
+#if defined(PTHREAD_KERNEL)
+
+int semaphore_text_and_set __P((semaphore *));
+int machdep_save_state __P((void));
+
+#endif
+
+__END_DECLS
diff --git a/lib/libpthread/include/fd.h b/lib/libpthread/include/fd.h
new file mode 100644
index 00000000000..654a497aa70
--- /dev/null
+++ b/lib/libpthread/include/fd.h
@@ -0,0 +1,106 @@
+/* ==== fd.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: fd.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: fd.h,v 1.17 1994/02/07 03:31:54 proven Exp $
+ *
+ * Description : Basic fd header.
+ *
+ * 1.00 93/08/14 proven
+ * -Started coding this file.
+ *
+ * 1.01 93/11/13 proven
+ * -The functions readv() and writev() added
+ */
+
+/*
+ * New pthread types.
+ */
+enum fd_type {
+ FD_NT, /* Not tested */
+ FD_NIU, /* Known to be not in use */
+ FD_HALF_DUPLEX, /* Files, and seeking devices */
+ FD_FULL_DUPLEX /* pipes, sockets, drivers, ... */
+};
+
+
+#define FD_READ 0x1
+#define FD_WRITE 0x2
+#define FD_RDWR (FD_READ | FD_WRITE)
+
+struct fd_ops {
+ int (*write)();
+ int (*read)();
+ int (*close)();
+ int (*fcntl)();
+ int (*writev)();
+ int (*readv)();
+ int (*seek)();
+};
+
+union fd_data {
+ void *ptr;
+ int i;
+};
+
+struct fd_table_entry {
+ struct pthread_queue r_queue;
+ struct pthread_queue w_queue;
+ struct pthread *r_owner;
+ struct pthread *w_owner;
+ semaphore lock;
+ struct fd_table_entry *next;
+ struct fd_ops *ops;
+ enum fd_type type;
+ int lockcount; /* Count for FILE locks */
+ int count;
+
+ /* data that needs to be passed to the type dependent fd */
+ int flags;
+ union fd_data fd;
+};
+
+/*
+ * Important data structure
+ */
+extern struct fd_table_entry *fd_table[];
+extern int dtablesize;
+
+/*
+ * New functions
+ */
+
+__BEGIN_DECLS
+
+#if defined(PTHREAD_KERNEL)
+
+#endif
+
+__END_DECLS
diff --git a/lib/libpthread/include/fd_pipe.h b/lib/libpthread/include/fd_pipe.h
new file mode 100644
index 00000000000..6ec808ff687
--- /dev/null
+++ b/lib/libpthread/include/fd_pipe.h
@@ -0,0 +1,54 @@
+/* ==== fd_pipe.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: fd_pipe.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: fd_pipe.h,v 1.17 1994/02/07 03:31:56 proven Exp $
+ *
+ * Description : The new fast ITC pipe header.
+ *
+ * 1.00 93/08/14 proven
+ * -Started coding this file.
+ */
+
+struct __pipe {
+ semaphore lock;
+ char * buf;
+ int size;
+ int flags;
+ int count;
+ int offset;
+ struct pthread * wait;
+ char * wait_buf;
+ size_t wait_size;
+};
+
+#define RD_CLOSED 0x01
+#define WR_CLOSED 0x02
+
diff --git a/lib/libpthread/include/kernel.h b/lib/libpthread/include/kernel.h
new file mode 100644
index 00000000000..29e066f7ae7
--- /dev/null
+++ b/lib/libpthread/include/kernel.h
@@ -0,0 +1,50 @@
+/* ==== kernel.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: kernel.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: kernel.h,v 1.17 1994/02/07 03:31:57 proven Exp $
+ *
+ * Description : mutex header.
+ *
+ * 1.00 93/07/22 proven
+ * -Started coding this file.
+ */
+
+/*
+ * Defines only for the pthread user kernel.
+ */
+#if defined(PTHREAD_KERNEL)
+
+#define PANIC() abort()
+
+/* Time each rr thread gets */
+#define PTHREAD_RR_TIMEOUT 100000000
+
+#endif
diff --git a/lib/libpthread/include/mutex.h b/lib/libpthread/include/mutex.h
new file mode 100644
index 00000000000..d8e5d8939d2
--- /dev/null
+++ b/lib/libpthread/include/mutex.h
@@ -0,0 +1,93 @@
+/* ==== mutex.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: mutex.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: mutex.h,v 1.17 1994/02/07 03:31:59 proven Exp $
+ *
+ * Description : mutex header.
+ *
+ * 1.00 93/07/20 proven
+ * -Started coding this file.
+ */
+
+/*
+ * New mutex structures
+ */
+enum pthread_mutex_type {
+ MUTEX_TYPE_FAST,
+ MUTEX_TYPE_STATIC_FAST,
+ MUTEX_TYPE_RECURSIVE,
+ MUTEX_TYPE_METERED,
+ MUTEX_TYPE_DEBUG, /* Debug mutexes will have lots of options */
+ MUTEX_TYPE_MAX
+};
+
+typedef struct pthread_mutex {
+ enum pthread_mutex_type m_type;
+ struct pthread_queue m_queue;
+ struct pthread *m_owner;
+ semaphore m_lock;
+ void *m_data;
+ long m_flags;
+} pthread_mutex_t;
+
+typedef struct pthread_mutex_attr {
+ enum pthread_mutex_type m_type;
+ long m_flags;
+} pthread_mutexattr_t;
+
+/*
+ * Flags for mutexes.
+ */
+#define MUTEX_FLAGS_PRIVATE 0x01
+#define MUTEX_FLAGS_INITED 0x02
+#define MUTEX_FLAGS_BUSY 0x04
+
+/*
+ * Static mutex initialization values.
+ */
+#define PTHREAD_MUTEX_INITIALIZER \
+{ MUTEX_TYPE_STATIC_FAST, PTHREAD_QUEUE_INITIALIZER, \
+ NULL, SEMAPHORE_CLEAR, NULL, MUTEX_FLAGS_INITED }
+
+/*
+ * New functions
+ */
+
+__BEGIN_DECLS
+
+int pthread_mutex_init __P((pthread_mutex_t *, pthread_mutexattr_t *));
+int pthread_mutex_lock __P((pthread_mutex_t *));
+int pthread_mutex_unlock __P((pthread_mutex_t *));
+int pthread_mutex_trylock __P((pthread_mutex_t *));
+int pthread_mutex_destroy __P((pthread_mutex_t *));
+
+__END_DECLS
+
diff --git a/lib/libpthread/include/posix.h b/lib/libpthread/include/posix.h
new file mode 100644
index 00000000000..a3a8ef049c6
--- /dev/null
+++ b/lib/libpthread/include/posix.h
@@ -0,0 +1,21 @@
+/* ==== posix.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
+ *
+ * Description : Convert an Ultrix-4.2 system to a more or less POSIX system.
+ *
+ * $Id: posix.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: posix-netbsd-0.9.h,v 1.17 1994/02/07 03:32:24 proven Exp $
+ *
+ * 1.00 93/07/20 proven
+ * -Started coding this file.
+ */
+
+#ifndef _PTHREAD_POSIX_H_
+#define _PTHREAD_POSIX_H_
+
+#include <sys/cdefs.h>
+
+/* Make sure we have size_t defined */
+#include <stdlib.h>
+#include <stdarg.h>
+
+#endif
diff --git a/lib/libpthread/include/pthread_attr.h b/lib/libpthread/include/pthread_attr.h
new file mode 100644
index 00000000000..3cfe54c29c1
--- /dev/null
+++ b/lib/libpthread/include/pthread_attr.h
@@ -0,0 +1,73 @@
+/* ==== pthread_attr.h ========================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: pthread_attr.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: pthread_attr.h,v 1.17 1994/02/07 03:32:02 proven Exp $
+ *
+ * Description : Basic pthread attributes header.
+ *
+ * 1.00 93/11/03 proven
+ * -Started coding this file.
+ */
+
+#define _POSIX_THREAD_ATTR_STACKSIZE
+
+#define PTHREAD_STACK_DEFAULT 65536
+
+/*
+ * New pthread attribute types.
+ */
+enum pthread_sched_attr {
+ SCHED_RR,
+ SCHED_IO,
+ SCHED_FIFO,
+ SCHED_OTHER,
+};
+
+typedef struct pthread_attr {
+ enum pthread_sched_attr sched_attr;
+ void * stackaddr_attr;
+ size_t stacksize_attr;
+} pthread_attr_t;
+
+/*
+ * New functions
+ */
+
+__BEGIN_DECLS
+
+int pthread_attr_init __P((pthread_attr_t *));
+int pthread_attr_destroy __P((pthread_attr_t *));
+int pthread_attr_setstacksize __P((pthread_attr_t *, size_t));
+int pthread_attr_getstacksize __P((pthread_attr_t *, size_t *));
+int pthread_attr_setstackaddr __P((pthread_attr_t *, void *));
+int pthread_attr_getstackaddr __P((pthread_attr_t *, void **));
+
+__END_DECLS
diff --git a/lib/libpthread/include/pthread_once.h b/lib/libpthread/include/pthread_once.h
new file mode 100644
index 00000000000..971bc493d1b
--- /dev/null
+++ b/lib/libpthread/include/pthread_once.h
@@ -0,0 +1,53 @@
+/* ==== pthread_once.h ========================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: pthread_once.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: pthread_once.h,v 1.17 1994/02/07 03:32:04 proven Exp $
+ *
+ * Description : mutex header.
+ *
+ * 1.00 93/12/12 proven
+ * -Started coding this file.
+ */
+
+/* New pthread_once structures */
+typedef int pthread_once_t;
+
+/* Static pthread_once_t initialization value. */
+#define PTHREAD_ONCE_INIT 0
+
+/* New functions */
+
+__BEGIN_DECLS
+
+int pthread_once __P((pthread_once_t *, void (*init_routine)(void)));
+
+__END_DECLS
+
diff --git a/lib/libpthread/include/queue.h b/lib/libpthread/include/queue.h
new file mode 100644
index 00000000000..d4d34b53861
--- /dev/null
+++ b/lib/libpthread/include/queue.h
@@ -0,0 +1,67 @@
+/* ==== queue.h ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: queue.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: queue.h,v 1.17 1994/02/07 03:39:52 proven Exp $
+ *
+ * Description : mutex header.
+ *
+ * 1.00 93/07/20 proven
+ * -Started coding this file.
+ */
+
+/*
+ * New queue structures
+ */
+struct pthread_queue {
+ struct pthread *q_next;
+ struct pthread *q_last;
+ void *q_data;
+};
+
+/*
+ * Static queue initialization values.
+ */
+#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL }
+
+/*
+ * New functions
+ * Should make pthread_queue_get a macro
+ */
+
+__BEGIN_DECLS
+
+void pthread_queue_init __P((struct pthread_queue *));
+void pthread_queue_enq __P((struct pthread_queue *, struct pthread *));
+void pthread_queue_remove __P((struct pthread_queue *, struct pthread *));
+struct pthread *pthread_queue_get __P((struct pthread_queue *));
+struct pthread *pthread_queue_deq __P((struct pthread_queue *));
+
+__END_DECLS
diff --git a/lib/libpthread/include/stdio.h b/lib/libpthread/include/stdio.h
new file mode 100644
index 00000000000..5819547d7b2
--- /dev/null
+++ b/lib/libpthread/include/stdio.h
@@ -0,0 +1,354 @@
+/* ==== stdio.h ============================================================
+ * Copyright (c) 1990 The Regents of the University of California.
+ * Copyright (c) 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)stdio.h 5.17 (Berkeley) 6/3/91
+ * $Id: stdio.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: stdio.h,v 1.18 1994/02/07 03:32:06 proven Exp $
+ */
+
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+#include <sys/cdefs.h>
+#include <pthread/posix.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+typedef long fpos_t; /* Must match off_t <sys/types.h> */
+
+#define _FSTDIO /* Define for new stdio with functions. */
+
+/*
+ * NB: to fit things in six character monocase externals, the stdio
+ * code uses the prefix `__s' for stdio objects, typically followed
+ * by a three-character attempt at a mnemonic.
+ */
+
+/* stdio buffers */
+struct __sbuf {
+ unsigned char *_base;
+ int _size;
+};
+
+/*
+ * stdio state variables.
+ *
+ * The following always hold:
+ *
+ * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
+ * _lbfsize is -_bf._size, else _lbfsize is 0
+ * if _flags&__SRD, _w is 0
+ * if _flags&__SWR, _r is 0
+ *
+ * This ensures that the getc and putc macros (or inline functions) never
+ * try to write or read from a file that is in `read' or `write' mode.
+ * (Moreover, they can, and do, automatically switch from read mode to
+ * write mode, and back, on "r+" and "w+" files.)
+ *
+ * _lbfsize is used only to make the inline line-buffered output stream
+ * code as compact as possible.
+ *
+ * _ub, _up, and _ur are used when ungetc() pushes back more characters
+ * than fit in the current _bf, or when ungetc() pushes back a character
+ * that does not match the previous one in _bf. When this happens,
+ * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
+ * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
+ */
+typedef struct __sFILE {
+ unsigned char *_p; /* current position in (some) buffer */
+ int _r; /* read space left for getc() */
+ int _w; /* write space left for putc() */
+ short _flags; /* flags, below; this FILE is free if 0 */
+ short _file; /* fileno, if Unix descriptor, else -1 */
+ struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
+ int _lbfsize; /* 0 or -_bf._size, for inline putc */
+
+ /* separate buffer for long sequences of ungetc() */
+ struct __sbuf _ub; /* ungetc buffer */
+ unsigned char *_up; /* saved _p when _p is doing ungetc data */
+ int _ur; /* saved _r when _r is counting ungetc data */
+
+ /* tricks to meet minimum requirements even when malloc() fails */
+ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
+ unsigned char _nbuf[1]; /* guarantee a getc() buffer */
+
+ /* separate buffer for fgetline() when line crosses buffer boundary */
+ struct __sbuf _lb; /* buffer for fgetline() */
+
+ /* Unix stdio files get aligned to block boundaries on fseek() */
+ int _blksize; /* stat.st_blksize (may be != _bf._size) */
+ int _offset; /* current lseek offset */
+} FILE;
+
+__BEGIN_DECLS
+extern FILE __sF[];
+__END_DECLS
+
+#define __SLBF 0x0001 /* line buffered */
+#define __SNBF 0x0002 /* unbuffered */
+#define __SRD 0x0004 /* OK to read */
+#define __SWR 0x0008 /* OK to write */
+ /* RD and WR are never simultaneously asserted */
+#define __SRW 0x0010 /* open for reading & writing */
+#define __SEOF 0x0020 /* found EOF */
+#define __SERR 0x0040 /* found error */
+#define __SMBF 0x0080 /* _buf is from malloc */
+#define __SAPP 0x0100 /* fdopen()ed in append mode */
+#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
+#define __SOPT 0x0400 /* do fseek() optimisation */
+#define __SNPT 0x0800 /* do not do fseek() optimisation */
+#define __SOFF 0x1000 /* set iff _offset is in fact correct */
+#define __SMOD 0x2000 /* true => fgetline modified _p text */
+
+/*
+ * The following three definitions are for ANSI C, which took them
+ * from System V, which brilliantly took internal interface macros and
+ * made them official arguments to setvbuf(), without renaming them.
+ * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
+ *
+ * Although numbered as their counterparts above, the implementation
+ * does not rely on this.
+ */
+#define _IOFBF 0 /* setvbuf should set fully buffered */
+#define _IOLBF 1 /* setvbuf should set line buffered */
+#define _IONBF 2 /* setvbuf should set unbuffered */
+
+#define BUFSIZ 1024 /* size of buffer used by setbuf */
+#define EOF (-1)
+
+/*
+ * FOPEN_MAX is a minimum maximum, and should be the number of descriptors
+ * that the kernel can provide without allocation of a resource that can
+ * fail without the process sleeping. Do not use this for anything.
+ */
+#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
+#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
+
+/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
+#ifndef _ANSI_SOURCE
+#define P_tmpdir "/var/tmp/"
+#endif
+#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
+#ifndef TMP_MAX
+#define TMP_MAX 308915776
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0 /* set file offset to offset */
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1 /* set file offset to current plus offset */
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2 /* set file offset to EOF plus offset */
+#endif
+
+#define stdin (&__sF[0])
+#define stdout (&__sF[1])
+#define stderr (&__sF[2])
+
+/*
+ * Functions defined in ANSI C standard.
+ */
+__BEGIN_DECLS
+void clearerr __P((FILE *));
+int fclose __P((FILE *));
+int feof __P((FILE *));
+int ferror __P((FILE *));
+int fflush __P((FILE *));
+int fgetc __P((FILE *));
+int fgetpos __P((FILE *, fpos_t *));
+char * fgets __P((char *, size_t, FILE *));
+FILE * fopen __P((const char *, const char *));
+int fprintf __P((FILE *, const char *, ...));
+int fputc __P((int, FILE *));
+int fputs __P((const char *, FILE *));
+size_t fread __P((void *, size_t, size_t, FILE *));
+FILE * freopen __P((const char *, const char *, FILE *));
+int fscanf __P((FILE *, const char *, ...));
+int fseek __P((FILE *, long, int));
+int fsetpos __P((FILE *, const fpos_t *));
+long ftell __P((const FILE *));
+size_t fwrite __P((const void *, size_t, size_t, FILE *));
+int getc __P((FILE *));
+int getchar __P((void));
+char * gets __P((char *));
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+extern int sys_nerr; /* perror(3) external variables */
+extern char *sys_errlist[];
+#endif
+
+void perror __P((const char *));
+int printf __P((const char *, ...));
+int putc __P((int, FILE *));
+int putchar __P((int));
+int puts __P((const char *));
+int remove __P((const char *));
+int rename __P((const char *, const char *));
+void rewind __P((FILE *));
+int scanf __P((const char *, ...));
+void setbuf __P((FILE *, char *));
+int setvbuf __P((FILE *, char *, int, size_t));
+int sprintf __P((char *, const char *, ...));
+int sscanf __P((const char *, const char *, ...));
+FILE *tmpfile __P((void));
+char *tmpnam __P((char *));
+int ungetc __P((int, FILE *));
+int vfprintf __P((FILE *, const char *, va_list));
+int vprintf __P((const char *, va_list));
+int vsprintf __P((char *, const char *, va_list));
+__END_DECLS
+
+/*
+ * Functions defined in POSIX 1003.1.
+ */
+#ifndef _ANSI_SOURCE
+#define L_ctermid 1024 /* size for ctermid(); PATH_MAX */
+#define L_cuserid 9 /* size for cuserid(); UT_NAMESIZE + 1 */
+
+__BEGIN_DECLS
+char *ctermid __P((char *));
+char *cuserid __P((char *));
+FILE *fdopen __P((int, const char *));
+int fileno __P((FILE *));
+__END_DECLS
+#endif /* not ANSI */
+
+/*
+ * Routines that are purely local.
+ */
+#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+__BEGIN_DECLS
+char *fgetline __P((FILE *, size_t *));
+int fpurge __P((FILE *));
+int getw __P((FILE *));
+int pclose __P((FILE *));
+FILE *popen __P((const char *, const char *));
+int putw __P((int, FILE *));
+void setbuffer __P((FILE *, char *, int));
+int setlinebuf __P((FILE *));
+char *tempnam __P((const char *, const char *));
+int snprintf __P((char *, size_t, const char *, ...));
+int vsnprintf __P((char *, size_t, const char *, va_list));
+int vscanf __P((const char *, va_list));
+int vsscanf __P((const char *, const char *, va_list));
+__END_DECLS
+
+/*
+ * This is a #define because the function is used internally and
+ * (unlike vfscanf) the name __svfscanf is guaranteed not to collide
+ * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined.
+ */
+#define vfscanf __svfscanf
+
+/*
+ * Stdio function-access interface.
+ */
+__BEGIN_DECLS
+FILE *funopen __P((const void *,
+ int (*)(void *, char *, int),
+ int (*)(void *, const char *, int),
+ fpos_t (*)(void *, fpos_t, int),
+ int (*)(void *)));
+__END_DECLS
+#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
+#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
+#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
+
+/*
+ * Functions internal to the implementation.
+ */
+__BEGIN_DECLS
+int __srget __P((FILE *));
+int __svfscanf __P((FILE *, const char *, va_list));
+int __swbuf __P((int, FILE *));
+__END_DECLS
+
+/*
+ * The __sfoo macros are here so that we can
+ * define function versions in the C library.
+ */
+#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
+static __inline int __getc(FILE *_p)
+{
+ int ret;
+ flockfile(_p);
+ ret = __sgetc(_p);
+ funlockfile(_p);
+ return(ret);
+}
+
+#define getc(fp) __gets(fp)
+#define getchar() getc(stdin)
+#define getc_unlocked(fp) __sgetc(fp)
+#define getchar_unlocked() getc_unlocked(stdin)
+
+static __inline int __sputc(int _c, FILE *_p)
+{
+ if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
+ return (*_p->_p++ = _c);
+ else
+ return (__swbuf(_c, _p));
+}
+
+static __inline int __putc(int _c, FILE *_p)
+{
+ int ret;
+ flockfile(_p);
+ ret = __sputc(_c, _p);
+ funlockfile(_p);
+ return(ret);
+}
+
+#define putc(x, fp) __putc(x, fp);
+#define putchar(x) putc(x, stdout)
+#define putc_unlocked(x, fp) __sputc(x, fp)
+#define putchar_unlocked(x) putc_unlocked(x, stdout)
+
+#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
+#define __sferror(p) (((p)->_flags & __SERR) != 0)
+#define __sfileno(p) ((p)->_file)
+
+#define feof(p) __sfeof(p)
+#define ferror(p) __sferror(p)
+
+#ifndef _ANSI_SOURCE
+#define fileno(p) __sfileno(p)
+#endif
+
+#endif
diff --git a/lib/libpthread/include/util.h b/lib/libpthread/include/util.h
new file mode 100644
index 00000000000..249975df57a
--- /dev/null
+++ b/lib/libpthread/include/util.h
@@ -0,0 +1,89 @@
+/* ==== util.h ============================================================
+ * Copyright (c) 1991, 1992, 1993 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: util.h,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: util.h,v 1.15 1994/02/07 03:32:07 proven Exp $
+ *
+ * Description : Header file for generic utility functions.
+ *
+ * 91/08/31 proven - Added exchange.
+ * Exchange any two objects of any size in any table.
+ *
+ * 91/10/06 proven - Cleaned out all the old junk.
+ *
+ * 91/03/06 proven - Added getint.
+ */
+
+#ifndef _PTHREAD_UTIL_H
+#define _PTHREAD_UTIL_H
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Stuff only pthread internals really uses */
+#if defined(PTHREAD_KERNEL)
+
+#undef FALSE
+#undef TRUE
+
+typedef enum Boolean {
+ FALSE,
+ TRUE,
+} Boolean;
+
+#define OK 0
+#define NUL '\0'
+#define NOTOK -1
+
+#if ! defined(min)
+#define min(a,b) (((a)<(b))?(a):(b))
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/* Alingn the size to the next multiple of 4 bytes */
+#define ALIGN4(size) ((size + 3) & ~3)
+#define ALIGN8(size) ((size + 7) & ~7)
+
+#ifdef DEBUG
+#define DEBUG0(s) printf(s)
+#define DEBUG1(s,a) printf(s,a)
+#define DEBUG2(s,a,b) printf(s,a,b)
+#define DEBUG3(s,a,b,c) printf(s,a,b,c)
+#else
+#define DEBUG0(s)
+#define DEBUG1(s)
+#define DEBUG2(s)
+#define DEBUG3(s)
+#endif
+
+#endif
+
+#endif
diff --git a/lib/libpthread/pthreads/Makefile.inc b/lib/libpthread/pthreads/Makefile.inc
new file mode 100644
index 00000000000..86c63233c1a
--- /dev/null
+++ b/lib/libpthread/pthreads/Makefile.inc
@@ -0,0 +1,9 @@
+# from: @(#)Makefile.inc 5.6 (Berkeley) 6/4/91
+
+# pthread sources
+.PATH: ${.CURDIR}/pthreads
+
+SRCS+= cond.c fd.c fd_kern.c fd_pipe.c file.c globals.c malloc.c mutex.c \
+ pthread.c pthread_attr.c queue.c signal.c pthread_join.c \
+ pthread_detach.c sleep.c
+
diff --git a/lib/libpthread/pthreads/cond.c b/lib/libpthread/pthreads/cond.c
new file mode 100644
index 00000000000..7251f550d16
--- /dev/null
+++ b/lib/libpthread/pthreads/cond.c
@@ -0,0 +1,208 @@
+/* ==== cond.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Condition cariable functions.
+ *
+ * 1.00 93/10/28 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: cond.c,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: cond.c,v 1.16 1994/02/07 02:18:35 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+/* ==========================================================================
+ * pthread_cond_init()
+ *
+ * In this implementation I don't need to allocate memory.
+ * ENOMEM, EAGAIN should never be returned. Arch that have
+ * weird constraints may need special coding.
+ */
+int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
+{
+ /* Only check if attr specifies some mutex type other than fast */
+ if ((cond_attr) && (cond_attr->c_type != COND_TYPE_FAST)) {
+ if (cond_attr->c_type >= COND_TYPE_MAX) {
+ return(EINVAL);
+ }
+ if (cond->c_flags & COND_FLAGS_INITED) {
+ return(EBUSY);
+ }
+ cond->c_type = cond_attr->c_type;
+ } else {
+ cond->c_type = COND_TYPE_FAST;
+ }
+ /* Set all other paramaters */
+ pthread_queue_init(&cond->c_queue);
+ cond->c_flags |= COND_FLAGS_INITED;
+ cond->c_lock = SEMAPHORE_CLEAR;
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_cond_destroy()
+ */
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ /* Only check if cond is of type other than fast */
+ switch(cond->c_type) {
+ case COND_TYPE_FAST:
+ break;
+ case COND_TYPE_STATIC_FAST:
+ default:
+ return(EINVAL);
+ break;
+ }
+
+ /* Cleanup cond, others might want to use it. */
+ pthread_queue_init(&cond->c_queue);
+ cond->c_flags |= COND_FLAGS_INITED;
+ cond->c_lock = SEMAPHORE_CLEAR;
+ cond->c_flags = 0;
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_cond_wait()
+ */
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ semaphore *lock, *plock;
+ int rval;
+
+ lock = &(cond->c_lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ switch (cond->c_type) {
+ /*
+ * Fast condition variables do not check for any error conditions.
+ */
+ case COND_TYPE_FAST:
+ case COND_TYPE_STATIC_FAST:
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_enq(&cond->c_queue, pthread_run);
+ pthread_mutex_unlock(mutex);
+ SEMAPHORE_RESET(lock);
+
+ /* Reschedule will unlock pthread_run */
+ reschedule(PS_COND_WAIT);
+
+ return(pthread_mutex_lock(mutex));
+ break;
+ default:
+ rval = EINVAL;
+ break;
+ }
+ SEMAPHORE_RESET(lock);
+ return(rval);
+}
+
+/* ==========================================================================
+ * pthread_cond_signal()
+ */
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ struct pthread *pthread;
+ semaphore *lock, *plock;
+ int rval;
+
+ lock = &(cond->c_lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ switch (cond->c_type) {
+ case COND_TYPE_FAST:
+ case COND_TYPE_STATIC_FAST:
+ if (pthread = pthread_queue_get(&cond->c_queue)) {
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_deq(&cond->c_queue);
+ pthread->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ }
+ rval = OK;
+ break;
+ default:
+ rval = EINVAL;
+ break;
+ }
+ SEMAPHORE_RESET(lock);
+ return(rval);
+}
+
+/* ==========================================================================
+ * pthread_cond_broadcast()
+ *
+ * Not much different then the above routine.
+ */
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ struct pthread *pthread;
+ semaphore *lock, *plock;
+ int rval;
+
+ lock = &(cond->c_lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ switch (cond->c_type) {
+ case COND_TYPE_FAST:
+ case COND_TYPE_STATIC_FAST:
+ while (pthread = pthread_queue_get(&cond->c_queue)) {
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_deq(&cond->c_queue);
+ pthread->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ }
+ rval = OK;
+ break;
+ default:
+ rval = EINVAL;
+ break;
+ }
+ SEMAPHORE_RESET(lock);
+ return(rval);
+}
diff --git a/lib/libpthread/pthreads/fd.c b/lib/libpthread/pthreads/fd.c
new file mode 100644
index 00000000000..2302f1d2068
--- /dev/null
+++ b/lib/libpthread/pthreads/fd.c
@@ -0,0 +1,562 @@
+/* ==== fd.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : All the syscalls dealing with fds.
+ *
+ * 1.00 93/08/14 proven
+ * -Started coding this file.
+ *
+ * 1.01 93/11/13 proven
+ * -The functions readv() and writev() added.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: fd.c,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: fd.c,v 1.16 1994/02/07 02:18:39 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread/posix.h>
+
+/*
+ * These first functions really should not be called by the user.
+ *
+ * I really should dynamically figure out what the table size is.
+ */
+int dtablesize = 64;
+static struct fd_table_entry fd_entry[64];
+
+/* ==========================================================================
+ * fd_init()
+ */
+void fd_init(void)
+{
+ int i;
+
+ for (i = 0; i < dtablesize; i++) {
+ fd_table[i] = &fd_entry[i];
+
+ fd_table[i]->ops = NULL;
+ fd_table[i]->type = FD_NT;
+ fd_table[i]->fd.i = NOTOK;
+ fd_table[i]->flags = 0;
+ fd_table[i]->count = 0;
+
+ pthread_queue_init(&(fd_table[i]->r_queue));
+ pthread_queue_init(&(fd_table[i]->w_queue));
+
+ fd_table[i]->r_owner = NULL;
+ fd_table[i]->w_owner = NULL;
+ fd_table[i]->lock = SEMAPHORE_CLEAR;
+ fd_table[i]->next = NULL;
+ fd_table[i]->lockcount = 0;
+ }
+
+ /* Currently only initialize first 3 fds. */
+ fd_kern_init(0);
+ fd_kern_init(1);
+ fd_kern_init(2);
+ printf ("Warning: threaded process may have changed open file descriptors\n");
+}
+
+/* ==========================================================================
+ * fd_allocate()
+ */
+int fd_allocate()
+{
+ semaphore *lock;
+ int i;
+
+ for (i = 0; i < dtablesize; i++) {
+ lock = &(fd_table[i]->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ continue;
+ }
+ if (fd_table[i]->count || fd_table[i]->r_owner
+ || fd_table[i]->w_owner) {
+ SEMAPHORE_RESET(lock);
+ continue;
+ }
+ if (fd_table[i]->type == FD_NT) {
+ /* Test to see if the kernel version is in use */
+ /* If so continue; */
+ }
+ fd_table[i]->count++;
+ SEMAPHORE_RESET(lock);
+ return(i);
+ }
+ pthread_run->error = ENFILE;
+ return(NOTOK);
+}
+
+/* ==========================================================================
+ * fd_free()
+ *
+ * Assumes fd is locked and owner by pthread_run
+ * Don't clear the queues, fd_unlock will do that.
+ */
+int fd_free(int fd)
+{
+ struct fd_table_entry *fd_valid;
+ int ret;
+
+ if (ret = --fd_table[fd]->count) {
+ /* Separate pthread queue into two distinct queues. */
+ fd_valid = fd_table[fd];
+ fd_table[fd] = fd_table[fd]->next;
+ fd_valid->next = fd_table[fd]->next;
+ }
+
+ fd_table[fd]->type = FD_NIU;
+ fd_table[fd]->fd.i = NOTOK;
+ fd_table[fd]->next = NULL;
+ fd_table[fd]->flags = 0;
+ fd_table[fd]->count = 0;
+ return(ret);
+}
+
+/* ==========================================================================
+ * fd_basic_unlock()
+ *
+ * The real work of unlock without the locking of fd_table[fd].lock.
+ */
+void fd_basic_unlock(int fd, int lock_type)
+{
+ struct pthread *pthread;
+ semaphore *plock;
+
+ if (fd_table[fd]->r_owner == pthread_run) {
+ if (pthread = pthread_queue_get(&fd_table[fd]->r_queue)) {
+
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_deq(&fd_table[fd]->r_queue);
+ fd_table[fd]->r_owner = pthread;
+ pthread->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ } else {
+ fd_table[fd]->r_owner = NULL;
+ }
+ }
+
+ if (fd_table[fd]->w_owner == pthread_run) {
+ if (pthread = pthread_queue_get(&fd_table[fd]->w_queue)) {
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_deq(&fd_table[fd]->r_queue);
+ fd_table[fd]->w_owner = pthread;
+ pthread->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ } else {
+ fd_table[fd]->w_owner = NULL;
+ }
+ }
+}
+
+/* ==========================================================================
+ * fd_unlock()
+ * If there is a lock count then the function fileunlock will do
+ * the unlocking, just return.
+ */
+void fd_unlock(int fd, int lock_type)
+{
+ semaphore *lock;
+
+ if (!(fd_table[fd]->lockcount)) {
+ lock = &(fd_table[fd]->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ fd_basic_unlock(fd, lock_type);
+ SEMAPHORE_RESET(lock);
+ }
+}
+
+/* ==========================================================================
+ * fd_basic_lock()
+ *
+ * The real work of lock without the locking of fd_table[fd].lock.
+ * Be sure to leave the lock the same way you found it. i.e. locked.
+ */
+int fd_basic_lock(unsigned int fd, int lock_type, semaphore * lock)
+{
+ semaphore *plock;
+
+ /* If not in use return EBADF error */
+ if (fd_table[fd]->type == FD_NIU) {
+ return(NOTOK);
+ }
+
+ /* If not tested, test it and see if it is valid */
+ if (fd_table[fd]->type == FD_NT) {
+ /* If not ok return EBADF error */
+ if (fd_kern_init(fd) != OK) {
+ return(NOTOK);
+ }
+ }
+ if ((fd_table[fd]->type == FD_HALF_DUPLEX) ||
+ (lock_type & FD_READ)) {
+ if (fd_table[fd]->r_owner) {
+ if (fd_table[fd]->r_owner != pthread_run) {
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_enq(&fd_table[fd]->r_queue, pthread_run);
+ SEMAPHORE_RESET(lock);
+
+ /* Reschedule will unlock pthread_run */
+ reschedule(PS_FDLR_WAIT);
+
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ } else {
+ if (!fd_table[fd]->lockcount) {
+ PANIC();
+ }
+ }
+ }
+ fd_table[fd]->r_owner = pthread_run;
+ }
+ if ((fd_table[fd]->type != FD_HALF_DUPLEX) &&
+ (lock_type & FD_WRITE)) {
+ if (fd_table[fd]->w_owner) {
+ if (fd_table[fd]->w_owner != pthread_run) {
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_enq(&fd_table[fd]->w_queue, pthread_run);
+ SEMAPHORE_RESET(lock);
+
+ /* Reschedule will unlock pthread_run */
+ reschedule(PS_FDLW_WAIT);
+
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ }
+ }
+ fd_table[fd]->w_owner = pthread_run;
+ }
+ if (!fd_table[fd]->count) {
+ fd_basic_unlock(fd, lock_type);
+ return(NOTOK);
+ }
+ return(OK);
+}
+
+/* ==========================================================================
+ * fd_lock()
+ */
+int fd_lock(unsigned int fd, int lock_type)
+{
+ semaphore *lock;
+ int error;
+
+ if (fd < dtablesize) {
+ lock = &(fd_table[fd]->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ error = fd_basic_lock(fd, lock_type, lock);
+ SEMAPHORE_RESET(lock);
+ return(error);
+ }
+ return(NOTOK);
+}
+
+
+/* ==========================================================================
+ * ======================================================================= */
+
+/* ==========================================================================
+ * read()
+ */
+ssize_t read(int fd, void *buf, size_t nbytes)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_READ)) == OK) {
+ ret = fd_table[fd]->ops->read(fd_table[fd]->fd,
+ fd_table[fd]->flags, buf, nbytes);
+ fd_unlock(fd, FD_READ);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * readv()
+ */
+int readv(int fd, const struct iovec *iov, int iovcnt)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_READ)) == OK) {
+ ret = fd_table[fd]->ops->readv(fd_table[fd]->fd,
+ fd_table[fd]->flags, iov, iovcnt);
+ fd_unlock(fd, FD_READ);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * write()
+ */
+ssize_t write(int fd, const void *buf, size_t nbytes)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_WRITE)) == OK) {
+ ret = fd_table[fd]->ops->write(fd_table[fd]->fd,
+ fd_table[fd]->flags, buf, nbytes);
+ fd_unlock(fd, FD_WRITE);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * writev()
+ */
+int writev(int fd, const struct iovec *iov, int iovcnt)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_WRITE)) == OK) {
+ ret = fd_table[fd]->ops->writev(fd_table[fd]->fd,
+ fd_table[fd]->flags, iov, iovcnt);
+ fd_unlock(fd, FD_WRITE);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * lseek()
+ */
+off_t lseek(int fd, off_t offset, int whence)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ ret = fd_table[fd]->ops->seek(fd_table[fd]->fd,
+ fd_table[fd]->flags, offset, whence);
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * close()
+ *
+ * The whole close procedure is a bit odd and needs a bit of a rethink.
+ * For now close() locks the fd, calls fd_free() which checks to see if
+ * there are any other fd values poinging to the same real fd. If so
+ * It breaks the wait queue into two sections those that are waiting on fd
+ * and those waiting on other fd's. Those that are waiting on fd are connected
+ * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT
+ * RELEASED). close() then calls fd_unlock which give the fd to the next queued
+ * element which determins that the fd is closed and then calls fd_unlock etc...
+ */
+int close(int fd)
+{
+ union fd_data realfd;
+ int ret, flags;
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ flags = fd_table[fd]->flags;
+ realfd = fd_table[fd]->fd;
+ if (fd_free(fd) == OK) {
+ ret = fd_table[fd]->ops->close(realfd, flags);
+ }
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * fd_basic_dup()
+ *
+ * Might need to do more than just what's below.
+ */
+static inline void fd_basic_dup(int fd, int newfd)
+{
+ fd_table[newfd]->next = fd_table[fd]->next;
+ fd_table[fd]->next = fd_table[newfd];
+ fd_table[fd]->count++;
+}
+
+/* ==========================================================================
+ * dup2()
+ *
+ * Always lock the lower number fd first to avoid deadlocks.
+ * newfd must be locked by hand so it can be closed if it is open,
+ * or it won't be opened while dup is in progress.
+ */
+int dup2(fd, newfd)
+{
+ union fd_data realfd;
+ semaphore *lock;
+ int ret, flags;
+
+ if (newfd < dtablesize) {
+ if (fd < newfd) {
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ /* Need to lock the newfd by hand */
+ lock = &(fd_table[newfd]->lock);
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Is it inuse */
+ if (fd_basic_lock(newfd, FD_RDWR, lock) == OK) {
+ /* free it and check close status */
+ flags = fd_table[fd]->flags;
+ realfd = fd_table[fd]->fd;
+ if (fd_free(fd) == OK) {
+ ret = fd_table[fd]->ops->close(realfd, flags);
+ } else {
+ /* Lots of work to do */
+ }
+ }
+ fd_basic_dup(fd, newfd);
+ }
+ fd_unlock(fd, FD_RDWR);
+ } else {
+ /* Need to lock the newfd by hand */
+ lock = &(fd_table[newfd]->lock);
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ }
+ /* Is it inuse */
+ if ((ret = fd_basic_lock(newfd, FD_RDWR, lock)) == OK) {
+ /* free it and check close status */
+ flags = fd_table[fd]->flags;
+ realfd = fd_table[fd]->fd;
+ if (fd_free(fd) == OK) {
+ ret = fd_table[fd]->ops->close(realfd, flags);
+ } else {
+ /* Lots of work to do */
+ }
+
+ fd_basic_dup(fd, newfd);
+ fd_unlock(fd, FD_RDWR);
+ }
+ SEMAPHORE_RESET(lock);
+ }
+ } else {
+ ret = NOTOK;
+ }
+ return(ret);
+
+}
+
+/* ==========================================================================
+ * dup()
+ */
+int dup(int fd)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ ret = fd_allocate();
+ fd_basic_dup(fd, ret);
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * fcntl()
+ */
+int fcntl(int fd, int cmd, ...)
+{
+ int ret, realfd, flags;
+ struct flock *flock;
+ semaphore *plock;
+ va_list ap;
+
+ flags = 0;
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ va_start(ap, cmd);
+ switch(cmd) {
+ case F_DUPFD:
+ ret = fd_allocate();
+ fd_basic_dup(va_arg(ap, int), ret);
+ break;
+ case F_SETFD:
+ flags = va_arg(ap, int);
+ case F_GETFD:
+ ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
+ fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK);
+ break;
+ case F_GETFL:
+ ret = fd_table[fd]->flags;
+ break;
+ case F_SETFL:
+ flags = va_arg(ap, int);
+ if ((ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
+ fd_table[fd]->flags, cmd, flags | __FD_NONBLOCK)) == OK) {
+ fd_table[fd]->flags = flags;
+ }
+ break;
+/* case F_SETLKW: */
+ /*
+ * Do the same as SETLK but if it fails with EACCES or EAGAIN
+ * block the thread and try again later, not implemented yet
+ */
+/* case F_SETLK: */
+/* case F_GETLK:
+ flock = va_arg(ap, struct flock*);
+ ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
+ fd_table[fd]->flags, cmd, flock);
+ break; */
+ default:
+ /* Might want to make va_arg use a union */
+ ret = fd_table[fd]->ops->fcntl(fd_table[fd]->fd,
+ fd_table[fd]->flags, cmd, va_arg(ap, void*));
+ break;
+ }
+ va_end(ap);
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
diff --git a/lib/libpthread/pthreads/fd_kern.c b/lib/libpthread/pthreads/fd_kern.c
new file mode 100644
index 00000000000..ed4f5d008fb
--- /dev/null
+++ b/lib/libpthread/pthreads/fd_kern.c
@@ -0,0 +1,647 @@
+/* ==== fd_kern.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Deals with the valid kernel fds.
+ *
+ * 1.00 93/09/27 proven
+ * -Started coding this file.
+ *
+ * 1.01 93/11/13 proven
+ * -The functions readv() and writev() added.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: fd_kern.c,v 1.1 1995/10/18 08:43:04 deraadt Exp $ $provenid: fd_kern.c,v 1.7 1994/02/07 02:18:49 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread/posix.h>
+
+/* ==========================================================================
+ * Variables used by both fd_kern_poll and fd_kern_wait
+ */
+static struct pthread *fd_wait_read, *fd_wait_write;
+static fd_set fd_set_read, fd_set_write;
+
+/* ==========================================================================
+ * fd_kern_poll()
+ *
+ * Called only from context_switch(). The kernel must be locked.
+ *
+ * This function uses a linked list of waiting pthreads, NOT a queue.
+ */
+static semaphore fd_wait_lock = SEMAPHORE_CLEAR;
+
+void fd_kern_poll()
+{
+ struct timeval __fd_kern_poll_timeout = { 0, 0 };
+ struct pthread **pthread;
+ semaphore *lock;
+ int count;
+
+ /* If someone has the lock then they are in RUNNING state, just return */
+ lock = &fd_wait_lock;
+ if (SEMAPHORE_TEST_AND_SET(lock)) {
+ return;
+ }
+ if (fd_wait_read || fd_wait_write) {
+ for (pthread = &fd_wait_read; *pthread; pthread = &((*pthread)->next)) {
+ FD_SET((*pthread)->fd, &fd_set_read);
+ }
+ for (pthread = &fd_wait_write; *pthread; pthread = &((*pthread)->next)) {
+ FD_SET((*pthread)->fd, &fd_set_write);
+ }
+
+ if ((count = machdep_sys_select(dtablesize, &fd_set_read,
+ &fd_set_write, NULL, &__fd_kern_poll_timeout)) < OK) {
+ if (count == -EINTR) {
+ SEMAPHORE_RESET(lock);
+ return;
+ }
+ PANIC();
+ }
+
+ for (pthread = &fd_wait_read; count && *pthread; ) {
+ if (FD_ISSET((*pthread)->fd, &fd_set_read)) {
+ /* Get lock on thread */
+
+ (*pthread)->state = PS_RUNNING;
+ *pthread = (*pthread)->next;
+ count--;
+ continue;
+ }
+ pthread = &((*pthread)->next);
+ }
+
+ for (pthread = &fd_wait_write; count && *pthread; ) {
+ if (FD_ISSET((*pthread)->fd, &fd_set_write)) {
+ semaphore *plock;
+
+ /* Get lock on thread */
+ plock = &(*pthread)->lock;
+ if (!(SEMAPHORE_TEST_AND_SET(plock))) {
+ /* Thread locked, skip it. */
+ (*pthread)->state = PS_RUNNING;
+ *pthread = (*pthread)->next;
+ SEMAPHORE_RESET(plock);
+ }
+ count--;
+ continue;
+ }
+ pthread = &((*pthread)->next);
+ }
+ }
+ SEMAPHORE_RESET(lock);
+}
+
+/* ==========================================================================
+ * fd_kern_wait()
+ *
+ * Called when there is no active thread to run.
+ */
+extern struct timeval __fd_kern_wait_timeout;
+
+void fd_kern_wait()
+{
+ struct pthread **pthread;
+ sigset_t sig_to_block;
+ int count;
+
+ if (fd_wait_read || fd_wait_write) {
+ for (pthread = &fd_wait_read; *pthread; pthread = &((*pthread)->next)) {
+ FD_SET((*pthread)->fd, &fd_set_read);
+ }
+ for (pthread = &fd_wait_write; *pthread; pthread = &((*pthread)->next)) {
+ FD_SET((*pthread)->fd, &fd_set_write);
+ }
+
+ /* Turn off interrupts for real while we set the timer. */
+
+ sigfillset(&sig_to_block);
+ sigprocmask(SIG_BLOCK, &sig_to_block, NULL);
+
+ machdep_unset_thread_timer();
+ __fd_kern_wait_timeout.tv_usec = 0;
+ __fd_kern_wait_timeout.tv_sec = 3600;
+
+ sigprocmask(SIG_UNBLOCK, &sig_to_block, NULL);
+
+ /*
+ * There is a small but finite chance that an interrupt will
+ * occure between the unblock and the select. Because of this
+ * sig_handler_real() sets the value of __fd_kern_wait_timeout
+ * to zero causing the select to do a poll instead of a wait.
+ */
+
+ while ((count = machdep_sys_select(dtablesize, &fd_set_read,
+ &fd_set_write, NULL, &__fd_kern_wait_timeout)) < OK) {
+ if (count == -EINTR) {
+ return;
+ }
+ PANIC();
+ }
+
+ for (pthread = &fd_wait_read; count && *pthread; ) {
+ if (FD_ISSET((*pthread)->fd, &fd_set_read)) {
+ /* Get lock on thread */
+
+ (*pthread)->state = PS_RUNNING;
+ *pthread = (*pthread)->next;
+ count--;
+ continue;
+ }
+ pthread = &((*pthread)->next);
+ }
+
+ for (pthread = &fd_wait_write; count && *pthread; ) {
+ if (FD_ISSET((*pthread)->fd, &fd_set_write)) {
+ semaphore *plock;
+
+ /* Get lock on thread */
+ plock = &(*pthread)->lock;
+ if (!(SEMAPHORE_TEST_AND_SET(plock))) {
+ /* Thread locked, skip it. */
+ (*pthread)->state = PS_RUNNING;
+ *pthread = (*pthread)->next;
+ SEMAPHORE_RESET(plock);
+ }
+ count--;
+ continue;
+ }
+ pthread = &((*pthread)->next);
+ }
+ } else {
+ /* No threads, waiting on I/O, do a sigsuspend */
+ sig_handler_pause();
+ }
+}
+
+/* ==========================================================================
+ * Special Note: All operations return the errno as a negative of the errno
+ * listed in errno.h
+ * ======================================================================= */
+
+/* ==========================================================================
+ * read()
+ */
+ssize_t __fd_kern_read(int fd, int flags, void *buf, size_t nbytes)
+{
+ semaphore *lock, *plock;
+ int ret;
+
+ while ((ret = machdep_sys_read(fd, buf, nbytes)) < OK) {
+ if (ret == -EWOULDBLOCK) {
+ /* Lock queue */
+ lock = &fd_wait_lock;
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDR_WAIT */
+ pthread_run->next = fd_wait_read;
+ fd_wait_read = pthread_run;
+ pthread_run->fd = fd;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDR_WAIT);
+ } else {
+ pthread_run->error = -ret;
+ ret = NOTOK;
+ break;
+ }
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * readv()
+ */
+int __fd_kern_readv(int fd, int flags, struct iovec *iov, int iovcnt)
+{
+ semaphore *lock, *plock;
+ int ret;
+
+ while ((ret = machdep_sys_readv(fd, iov, iovcnt)) < OK) {
+ if (ret == -EWOULDBLOCK) {
+ /* Lock queue */
+ lock = &fd_wait_lock;
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDR_WAIT */
+ pthread_run->next = fd_wait_read;
+ fd_wait_read = pthread_run;
+ pthread_run->fd = fd;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDR_WAIT);
+ } else {
+ pthread_run->error = -ret;
+ ret = NOTOK;
+ break;
+ }
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * write()
+ */
+ssize_t __fd_kern_write(int fd, int flags, const void *buf, size_t nbytes)
+{
+ semaphore *lock, *plock;
+ int ret;
+
+ while ((ret = machdep_sys_write(fd, buf, nbytes)) < OK) {
+ if (pthread_run->error == -EWOULDBLOCK) {
+ /* Lock queue */
+ lock = &fd_wait_lock;
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDW_WAIT */
+ pthread_run->next = fd_wait_write;
+ fd_wait_write = pthread_run;
+ pthread_run->fd = fd;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDW_WAIT);
+ } else {
+ pthread_run->error = ret;
+ break;
+ }
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * writev()
+ */
+int __fd_kern_writev(int fd, int flags, struct iovec *iov, int iovcnt)
+{
+ semaphore *lock, *plock;
+ int ret;
+
+ while ((ret = machdep_sys_writev(fd, iov, iovcnt)) < OK) {
+ if (pthread_run->error == -EWOULDBLOCK) {
+ /* Lock queue */
+ lock = &fd_wait_lock;
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDW_WAIT */
+ pthread_run->next = fd_wait_write;
+ fd_wait_write = pthread_run;
+ pthread_run->fd = fd;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDW_WAIT);
+ } else {
+ pthread_run->error = ret;
+ break;
+ }
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * For blocking version we really should set an interrupt
+ * fcntl()
+ */
+int __fd_kern_fcntl(int fd, int flags, int cmd, int arg)
+{
+ return(machdep_sys_fcntl(fd, cmd, arg));
+}
+
+/* ==========================================================================
+ * close()
+ */
+int __fd_kern_close(int fd, int flags)
+{
+ return(machdep_sys_close(fd));
+}
+
+/* ==========================================================================
+ * lseek()
+ */
+int __fd_kern_lseek(int fd, int flags, off_t offset, int whence)
+{
+ return(machdep_sys_lseek(fd, offset, whence));
+}
+
+/*
+ * File descriptor operations
+ */
+extern machdep_sys_close();
+
+/* Normal file operations */
+static struct fd_ops __fd_kern_ops = {
+ __fd_kern_write, __fd_kern_read, __fd_kern_close, __fd_kern_fcntl,
+ __fd_kern_readv, __fd_kern_writev, __fd_kern_lseek
+};
+
+/* NFS file opperations */
+
+/* FIFO file opperations */
+
+/* Device operations */
+
+/* ==========================================================================
+ * open()
+ *
+ * Because open could potentially block opening a file from a remote
+ * system, we want to make sure the call will timeout. We then try and open
+ * the file, and stat the file to determine what operations we should
+ * associate with the fd.
+ *
+ * This is not done yet
+ *
+ * A reqular file on the local system needs no special treatment.
+ */
+int open(const char *path, int flags, ...)
+{
+ int fd, mode, fd_kern;
+ struct stat stat_buf;
+ va_list ap;
+
+ /* If pthread scheduling == FIFO set a virtual timer */
+ if (flags & O_CREAT) {
+ va_start(ap, flags);
+ mode = va_arg(ap, int);
+ va_end(ap);
+ } else {
+ mode = 0;
+ }
+
+ if (!((fd = fd_allocate()) < OK)) {
+ fd_table[fd]->flags = flags;
+ flags |= __FD_NONBLOCK;
+
+ if (!((fd_kern = machdep_sys_open(path, flags, mode)) < OK)) {
+
+ /* fstat the file to determine what type it is */
+ if (fstat(fd_kern, &stat_buf)) {
+printf("error %d stating new fd %d\n", errno, fd);
+ }
+ if (S_ISREG(stat_buf.st_mode)) {
+ fd_table[fd]->ops = &(__fd_kern_ops);
+ fd_table[fd]->type = FD_HALF_DUPLEX;
+ } else {
+ fd_table[fd]->ops = &(__fd_kern_ops);
+ fd_table[fd]->type = FD_FULL_DUPLEX;
+ }
+ fd_table[fd]->fd = fd_kern;
+ return(fd);
+ }
+
+ pthread_run->error = - fd_kern;
+ fd_table[fd]->count = 0;
+ }
+ return(NOTOK);
+}
+
+/* ==========================================================================
+ * fd_kern_init()
+ *
+ * Assume the entry is locked before routine is invoked
+ *
+ * This may change. The problem is setting the fd to nonblocking changes
+ * the parents fd too, which may not be the desired result.
+ */
+static fd_kern_init_called = 0;
+void fd_kern_init(int fd)
+{
+ if ((fd_table[fd]->flags = machdep_sys_fcntl(fd, F_GETFL, NULL)) >= OK) {
+ machdep_sys_fcntl(fd, F_SETFL, fd_table[fd]->flags | __FD_NONBLOCK);
+ fd_table[fd]->ops = &(__fd_kern_ops);
+ fd_table[fd]->type = FD_HALF_DUPLEX;
+ fd_table[fd]->fd = fd;
+ fd_table[fd]->count = 1;
+
+ }
+}
+
+/* ==========================================================================
+ * Here are the berkeley socket functions. These are not POSIX.
+ * ======================================================================= */
+
+/* ==========================================================================
+ * socket()
+ */
+int socket(int af, int type, int protocol)
+{
+ int fd, fd_kern;
+
+ if (!((fd = fd_allocate()) < OK)) {
+
+ if (!((fd_kern = machdep_sys_socket(af, type, protocol)) < OK)) {
+ machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK);
+
+ /* Should fstat the file to determine what type it is */
+ fd_table[fd]->ops = & __fd_kern_ops;
+ fd_table[fd]->type = FD_FULL_DUPLEX;
+ fd_table[fd]->fd = fd_kern;
+ fd_table[fd]->flags = 0;
+ return(fd);
+ }
+
+ pthread_run->error = - fd_kern;
+ fd_table[fd]->count = 0;
+ }
+ return(NOTOK);
+}
+
+/* ==========================================================================
+ * bind()
+ */
+int bind(int fd, const struct sockaddr *name, int namelen)
+{
+ /* Not much to do in bind */
+ semaphore *plock;
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ if ((ret = machdep_sys_bind(fd_table[fd]->fd, name, namelen)) < OK) {
+ pthread_run->error = - ret;
+ }
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * connect()
+ */
+int connect(int fd, const struct sockaddr *name, int namelen)
+{
+ semaphore *lock, *plock;
+ struct sockaddr tmpname;
+ int ret, tmpnamelen;
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ if ((ret = machdep_sys_connect(fd_table[fd]->fd, name, namelen)) < OK) {
+ if ((ret == -EWOULDBLOCK) || (ret == -EINPROGRESS) ||
+ (ret == -EALREADY)) {
+ /* Lock queue */
+ lock = &fd_wait_lock;
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDW_WAIT */
+ pthread_run->fd = fd_table[fd]->fd.i;
+ pthread_run->next = fd_wait_write;
+ fd_wait_write = pthread_run;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDW_WAIT);
+
+ /* OK now lets see if it really worked */
+ if (((ret = machdep_sys_getpeername(fd_table[fd]->fd,
+ &tmpname, &tmpnamelen)) < OK) && (ret == -ENOTCONN)) {
+
+ /* Get the error, this function should not fail */
+ machdep_sys_getsockopt(fd_table[fd]->fd, SOL_SOCKET,
+ SO_ERROR, &pthread_run->error, &tmpnamelen);
+ }
+ } else {
+ pthread_run->error = -ret;
+ }
+ }
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * accept()
+ */
+int accept(int fd, struct sockaddr *name, int *namelen)
+{
+ semaphore *lock, *plock;
+ int ret, fd_kern;
+
+
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ while ((fd_kern = machdep_sys_accept(fd_table[fd]->fd, name, namelen)) < OK) {
+ if (fd_kern == -EWOULDBLOCK) {
+ /* Lock queue */
+ lock = &fd_wait_lock;
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDR_WAIT */
+ pthread_run->fd = fd_table[fd]->fd.i;
+ pthread_run->next = fd_wait_write;
+ pthread_run->next = fd_wait_read;
+ fd_wait_read = pthread_run;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDR_WAIT);
+ } else {
+ fd_unlock(fd, FD_RDWR);
+ return(fd_kern);
+ }
+ }
+ fd_unlock(fd, FD_RDWR);
+
+ if (!((ret = fd_allocate()) < OK)) {
+
+ /* This may be unnecessary */
+ machdep_sys_fcntl(fd_kern, F_SETFL, __FD_NONBLOCK);
+
+ /* Should fstat the file to determine what type it is */
+ fd_table[ret]->ops = & __fd_kern_ops;
+ fd_table[ret]->type = FD_FULL_DUPLEX;
+ fd_table[ret]->fd = fd_kern;
+ fd_table[ret]->flags = 0;
+ }
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * listen()
+ */
+int listen(int fd, int backlog)
+{
+ int ret;
+
+ if ((ret = fd_lock(fd, FD_RDWR)) == OK) {
+ ret = machdep_sys_listen(fd_table[fd]->fd, backlog);
+ fd_unlock(fd, FD_RDWR);
+ }
+ return(ret);
+}
diff --git a/lib/libpthread/pthreads/fd_pipe.c b/lib/libpthread/pthreads/fd_pipe.c
new file mode 100644
index 00000000000..d4cf6f2cb9e
--- /dev/null
+++ b/lib/libpthread/pthreads/fd_pipe.c
@@ -0,0 +1,268 @@
+/* ==== fd_pipe.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : The new fast ITC pipe routines.
+ *
+ * 1.00 93/08/14 proven
+ * -Started coding this file.
+ *
+ * 1.01 93/11/13 proven
+ * -The functions readv() and writev() added.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: fd_pipe.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: fd_pipe.c,v 1.16 1994/02/07 02:18:52 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <pthread/fd_pipe.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread/posix.h>
+
+/* ==========================================================================
+ * The pipe lock is never unlocked until all pthreads waiting are done with it
+ * read()
+ */
+ssize_t __pipe_read(struct __pipe *fd, int flags, void *buf, size_t nbytes)
+{
+ semaphore *lock, *plock;
+ int ret = 0;
+
+ if (flags & O_ACCMODE) { return(NOTOK); }
+
+ lock = &(fd->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ /* If there is nothing to read, go to sleep */
+ if (fd->count == 0) {
+ if (flags == WR_CLOSED) {
+ SEMAPHORE_RESET(lock);
+ return(0);
+ } /* Lock pthread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* queue pthread for a FDR_WAIT */
+ pthread_run->next = NULL;
+ fd->wait = pthread_run;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDR_WAIT);
+ ret = fd->size;
+ } else {
+ ret = MIN(nbytes, fd->count);
+ memcpy(buf, fd->buf + fd->offset, ret);
+ if (!(fd->count -= ret)) {
+ fd->offset = 0;
+ }
+
+ /* Should try to read more from the waiting writer */
+
+ if (fd->wait) {
+ plock = &(fd->wait->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ fd->wait->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ } else {
+ SEMAPHORE_RESET(lock);
+ }
+ }
+ return(ret);
+}
+
+/* ==========================================================================
+ * __pipe_write()
+ *
+ * First check to see if the read side is still open, then
+ * check to see if there is a thread in a read wait for this pipe, if so
+ * copy as much data as possible directly into the read waiting threads
+ * buffer. The write thread(whether or not there was a read thread)
+ * copies as much data as it can into the pipe buffer and it there
+ * is still data it goes to sleep.
+ */
+ssize_t __pipe_write(struct __pipe *fd, int flags, const void *buf, size_t nbytes) {
+ semaphore *lock, *plock;
+ int ret, count;
+
+ if (!(flags & O_ACCMODE)) { return(NOTOK); }
+
+ lock = &(fd->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ while (fd->flags != RD_CLOSED) {
+ if (fd->wait) {
+ /* Lock pthread */
+ plock = &(fd->wait->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* Copy data directly into waiting pthreads buf */
+ fd->wait_size = MIN(nbytes, fd->wait_size);
+ memcpy(fd->wait_buf, buf, fd->wait_size);
+ buf = (const char *)buf + fd->wait_size;
+ nbytes -= fd->wait_size;
+ ret = fd->wait_size;
+
+ /* Wake up waiting pthread */
+ fd->wait->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ fd->wait = NULL;
+ }
+
+ if (count = MIN(nbytes, fd->size - (fd->offset + fd->count))) {
+ memcpy(fd->buf + (fd->offset + fd->count), buf, count);
+ buf = (const char *)buf + count;
+ nbytes -= count;
+ ret += count;
+ }
+ if (nbytes) {
+ /* Lock pthread */
+ plock = &(fd->wait->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ fd->wait = pthread_run;
+ SEMAPHORE_RESET(lock);
+ reschedule(PS_FDW_WAIT);
+ } else {
+ return(ret);
+ }
+ }
+ return(NOTOK);
+}
+
+/* ==========================================================================
+ * __pipe_close()
+ *
+ * The whole close procedure is a bit odd and needs a bit of a rethink.
+ * For now close() locks the fd, calls fd_free() which checks to see if
+ * there are any other fd values poinging to the same real fd. If so
+ * It breaks the wait queue into two sections those that are waiting on fd
+ * and those waiting on other fd's. Those that are waiting on fd are connected
+ * to the fd_table[fd] queue, and the count is set to zero, (BUT THE LOCK IS NOT
+ * RELEASED). close() then calls fd_unlock which give the fd to the next queued
+ * element which determins that the fd is closed and then calls fd_unlock etc...
+ */
+int __pipe_close(struct __pipe *fd, int flags)
+{
+ semaphore *lock, *plock;
+
+ lock = &(fd->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ if (!(fd->flags)) {
+ if (fd->wait) {
+ if (flags & O_ACCMODE) {
+ fd->flags |= WR_CLOSED;
+ /* Lock pthread */
+ /* Write side closed, wake read side and return EOF */
+ plock = &((fd->wait)->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ fd->count = 0;
+
+ /* Wake up waiting pthread */
+ fd->wait->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ fd->wait = NULL;
+ } else {
+ /* Should send a signal */
+ fd->flags |= RD_CLOSED;
+ }
+ }
+ } else {
+ free(fd);
+ return(OK);
+ }
+ SEMAPHORE_RESET(lock);
+}
+
+/* ==========================================================================
+ * For those function that aren't implemented yet
+ * __pipe_enosys()
+ */
+static int __pipe_enosys()
+{
+ pthread_run->error = ENOSYS;
+ return(NOTOK);
+}
+
+/*
+ * File descriptor operations
+ */
+struct fd_ops fd_ops[] = {
+{ NULL, NULL, }, /* Non operations */
+{ __pipe_write, __pipe_read, __pipe_close, __pipe_enosys, __pipe_enosys,
+ __pipe_enosys },
+};
+
+/* ==========================================================================
+ * open()
+ */
+/* int __pipe_open(const char *path, int flags, ...) */
+int newpipe(int fd[2])
+{
+ struct __pipe *fd_data;
+
+ if ((!((fd[0] = fd_allocate()) < OK)) && (!((fd[1] = fd_allocate()) < OK))) {
+ fd_data = malloc(sizeof(struct __pipe));
+ fd_data->buf = malloc(4096);
+ fd_data->size = 4096;
+ fd_data->count = 0;
+ fd_data->offset = 0;
+
+ fd_data->wait = NULL;
+ fd_data->flags = 0;
+
+ fd_table[fd[0]]->fd.ptr = fd_data;
+ fd_table[fd[0]]->flags = O_RDONLY;
+ fd_table[fd[1]]->fd.ptr = fd_data;
+ fd_table[fd[1]]->flags = O_WRONLY;
+
+ return(OK);
+ }
+ return(NOTOK);
+}
+
diff --git a/lib/libpthread/pthreads/file.c b/lib/libpthread/pthreads/file.c
new file mode 100644
index 00000000000..f22b3761c5a
--- /dev/null
+++ b/lib/libpthread/pthreads/file.c
@@ -0,0 +1,117 @@
+/* ==== file.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : The locking functions for stdio.
+ *
+ * 1.00 93/09/04 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: file.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: file.c,v 1.16 1994/02/07 02:18:55 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <stdio.h>
+
+/* ==========================================================================
+ * flockfile()
+ */
+void flockfile(FILE *fp)
+{
+ semaphore *lock;
+ int fd;
+
+ fd = fileno(fp);
+ lock = &(fd_table[fd]->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ if (fd_table[fd]->r_owner != pthread_run) {
+ /* This might fail but POSIX doesn't give a damn. */
+ fd_basic_lock(fd, FD_RDWR, lock);
+ }
+ fd_table[fd]->lockcount++;
+ SEMAPHORE_RESET(lock);
+}
+
+/* ==========================================================================
+ * ftrylockfile()
+ */
+int ftrylockfile(FILE *fp)
+{
+ semaphore *lock;
+ int fd;
+
+ fd = fileno(fp);
+ lock = &(fd_table[fd]->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ if (fd_table[fd]->r_owner != pthread_run) {
+ if (!(fd_table[fd]->r_owner && fd_table[fd]->w_owner)) {
+ fd_basic_lock(fd, FD_RDWR, lock);
+ fd = OK;
+ } else {
+ fd = NOTOK;
+ }
+ } else {
+ fd_table[fd]->lockcount++;
+ fd = OK;
+ }
+ SEMAPHORE_RESET(lock);
+ return(fd);
+}
+
+/* ==========================================================================
+ * funlockfile()
+ */
+void funlockfile(FILE *fp)
+{
+ semaphore *lock;
+ int fd;
+
+ fd = fileno(fp);
+ lock = &(fd_table[fd]->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ if (fd_table[fd]->r_owner == pthread_run) {
+ if (--fd_table[fd]->lockcount == 0) {
+ fd_basic_unlock(fd, FD_RDWR);
+ }
+ }
+ SEMAPHORE_RESET(lock);
+}
+
diff --git a/lib/libpthread/pthreads/globals.c b/lib/libpthread/pthreads/globals.c
new file mode 100644
index 00000000000..00774e0a2f8
--- /dev/null
+++ b/lib/libpthread/pthreads/globals.c
@@ -0,0 +1,67 @@
+/* ==== globals.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Global variables.
+ *
+ * 1.00 93/07/26 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: globals.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: globals.c,v 1.16 1994/02/07 02:18:57 proven Exp $";
+#endif
+
+#include <pthread.h>
+
+/*
+ * Initial thread, running thread, and top of link list
+ * of all threads.
+ */
+struct pthread *pthread_run;
+struct pthread *pthread_initial;
+struct pthread *pthread_link_list;
+
+/*
+ * default thread attributes
+ */
+pthread_attr_t pthread_default_attr = { SCHED_RR, NULL, PTHREAD_STACK_DEFAULT };
+
+/*
+ * Queue for all threads elidgeable to run this scheduling round.
+ */
+struct pthread_queue pthread_current_queue = PTHREAD_QUEUE_INITIALIZER;
+
+/*
+ * File table information
+ */
+struct fd_table_entry *fd_table[64];
+
+
diff --git a/lib/libpthread/pthreads/malloc.c b/lib/libpthread/pthreads/malloc.c
new file mode 100644
index 00000000000..0c5937ddb12
--- /dev/null
+++ b/lib/libpthread/pthreads/malloc.c
@@ -0,0 +1,361 @@
+/* ==== malloc.c ============================================================
+ * Copyright (c) 1983 Regents of the University of California.
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Malloc functions.
+ * This is a very fast storage allocator. It allocates blocks of a small
+ * number of different sizes, and keeps free lists of each size. Blocks that
+ * don't exactly fit are passed up to the next larger size. In this
+ * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
+ * This is designed for use in a virtual memory environment.
+ *
+ * 0.00 82/02/21 Chris Kingsley kingsley@cit-20
+ *
+ * 1.00 93/11/06 proven
+ * -Modified BSD libc malloc to be threadsafe.
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: malloc.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: malloc.c,v 1.16 1994/02/07 02:19:00 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <string.h>
+#include <pthread/posix.h>
+
+/*
+ * The overhead on a block is at least 4 bytes. When free, this space
+ * contains a pointer to the next free block, and the bottom two bits must
+ * be zero. When in use, the first byte is set to MAGIC, and the second
+ * byte is the size index. The remaining bytes are for alignment.
+ * If range checking is enabled then a second word holds the size of the
+ * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
+ * The order of elements is critical: ov_magic must overlay the low order
+ * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
+ */
+union overhead {
+ union overhead *ov_next; /* when free */
+ struct {
+ u_char ovu_magic; /* magic number */
+ u_char ovu_index; /* bucket # */
+#ifdef RCHECK
+ u_short ovu_rmagic; /* range magic number */
+ u_int ovu_size; /* actual block size */
+#endif
+ } ovu;
+#define ov_magic ovu.ovu_magic
+#define ov_index ovu.ovu_index
+#define ov_rmagic ovu.ovu_rmagic
+#define ov_size ovu.ovu_size
+};
+
+#define MAGIC 0xef /* magic # on accounting info */
+#define RMAGIC 0x5555 /* magic # on range info */
+
+#ifdef RCHECK
+#define RSLOP sizeof (u_short)
+#else
+#define RSLOP 0
+#endif
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * smallest allocatable block is 8 bytes. The overhead information
+ * precedes the data area returned to the user.
+ */
+#define NBUCKETS 30
+static union overhead *nextf[NBUCKETS];
+extern char *sbrk();
+
+static int pagesz; /* page size */
+static int pagebucket; /* page size bucket */
+static semaphore malloc_lock = SEMAPHORE_CLEAR;
+
+#if defined(DEBUG) || defined(RCHECK)
+#define ASSERT(p) if (!(p)) botch("p")
+#include <stdio.h>
+static
+botch(s)
+ char *s;
+{
+ fprintf(stderr, "\r\nassertion botched: %s\r\n", s);
+ (void) fflush(stderr); /* just in case user buffered it */
+ abort();
+}
+#else
+#define ASSERT(p)
+#endif
+
+/* ==========================================================================
+ * morecore()
+ *
+ * Allocate more memory to the indicated bucket
+ */
+static inline void morecore(int bucket)
+{
+ register union overhead *op;
+ register int sz; /* size of desired block */
+ int amt; /* amount to allocate */
+ int nblks; /* how many blocks we get */
+
+ /*
+ * sbrk_size <= 0 only for big, FLUFFY, requests (about
+ * 2^30 bytes on a VAX, I think) or for a negative arg.
+ */
+ sz = 1 << (bucket + 3);
+#ifdef DEBUG
+ ASSERT(sz > 0);
+#else
+ if (sz <= 0)
+ return;
+#endif
+ if (sz < pagesz) {
+ amt = pagesz;
+ nblks = amt / sz;
+ } else {
+ amt = sz + pagesz;
+ nblks = 1;
+ }
+ op = (union overhead *)sbrk(amt);
+ /* no more room! */
+ if ((int)op == -1)
+ return;
+ /*
+ * Add new memory allocated to that on
+ * free list for this hash bucket.
+ */
+ nextf[bucket] = op;
+ while (--nblks > 0) {
+ op->ov_next = (union overhead *)((caddr_t)op + sz);
+ op = (union overhead *)((caddr_t)op + sz);
+ }
+}
+
+/* ==========================================================================
+ * malloc()
+ */
+void *malloc(size_t nbytes)
+{
+ union overhead *op;
+ unsigned int amt;
+ int bucket, n;
+ semaphore *lock;
+
+ lock = &malloc_lock;
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ /*
+ * First time malloc is called, setup page size and
+ * align break pointer so all data will be page aligned.
+ */
+ if (pagesz == 0) {
+ pagesz = n = getpagesize();
+ op = (union overhead *)sbrk(0);
+ n = n - sizeof (*op) - ((int)op & (n - 1));
+ if (n < 0)
+ n += pagesz;
+ if (n) {
+ if (sbrk(n) == (char *)-1)
+ return (NULL);
+ }
+ bucket = 0;
+ amt = 8;
+ while (pagesz > amt) {
+ amt <<= 1;
+ bucket++;
+ }
+ pagebucket = bucket;
+ }
+ /*
+ * Convert amount of memory requested into closest block size
+ * stored in hash buckets which satisfies request.
+ * Account for space used per block for accounting.
+ */
+ if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
+#ifndef RCHECK
+ amt = 8; /* size of first bucket */
+ bucket = 0;
+#else
+ amt = 16; /* size of first bucket */
+ bucket = 1;
+#endif
+ n = -(sizeof (*op) + RSLOP);
+ } else {
+ amt = pagesz;
+ bucket = pagebucket;
+ }
+ while (nbytes > amt + n) {
+ amt <<= 1;
+ if (amt == 0) {
+ SEMAPHORE_RESET(lock);
+ return (NULL);
+ }
+ bucket++;
+ }
+ /*
+ * If nothing in hash bucket right now,
+ * request more memory from the system.
+ */
+ if ((op = nextf[bucket]) == NULL) {
+ morecore(bucket);
+ if ((op = nextf[bucket]) == NULL) {
+ SEMAPHORE_RESET(lock);
+ return (NULL);
+ }
+ }
+ /* remove from linked list */
+ nextf[bucket] = op->ov_next;
+ op->ov_magic = MAGIC;
+ op->ov_index = bucket;
+#ifdef RCHECK
+ /*
+ * Record allocated size of block and
+ * bound space with magic numbers.
+ */
+ op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
+ op->ov_rmagic = RMAGIC;
+ *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+#endif
+ SEMAPHORE_RESET(lock);
+ return ((char *)(op + 1));
+}
+
+/* ==========================================================================
+ * free()
+ */
+void free(void *cp)
+{
+ union overhead *op;
+ semaphore *lock;
+ int size;
+
+ lock = &malloc_lock;
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ if (cp == NULL) {
+ SEMAPHORE_RESET(lock);
+ return;
+ }
+ op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
+#ifdef DEBUG
+ ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
+#else
+ if (op->ov_magic != MAGIC) {
+ SEMAPHORE_RESET(lock);
+ return; /* sanity */
+ }
+#endif
+#ifdef RCHECK
+ ASSERT(op->ov_rmagic == RMAGIC);
+ ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
+#endif
+ size = op->ov_index;
+ ASSERT(size < NBUCKETS);
+ op->ov_next = nextf[size]; /* also clobbers ov_magic */
+ nextf[size] = op;
+
+ SEMAPHORE_RESET(lock);
+}
+
+/* ==========================================================================
+ * realloc()
+ *
+ * Storage compaction is no longer supported, fix program and try again.
+ */
+void *realloc(void *cp, size_t nbytes)
+{
+ u_int onb;
+ int i;
+ semaphore *lock;
+ union overhead *op;
+ char *res;
+
+ if (cp == NULL)
+ return (malloc(nbytes));
+ op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
+
+ if (op->ov_magic == MAGIC) {
+ i = op->ov_index;
+ } else {
+ /*
+ * This will cause old programs using storage compaction feature of
+ * realloc to break in a pseudo resonable way that is easy to debug.
+ * Returning a malloced buffer without the copy may cause
+ * indeterministic behavior.
+ */
+ return(NULL);
+ }
+
+ lock = &malloc_lock;
+ while(SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+ onb = 1 << (i + 3);
+ if (onb < pagesz)
+ onb -= sizeof (*op) + RSLOP;
+ else
+ onb += pagesz - sizeof (*op) - RSLOP;
+
+ /* avoid the copy if same size block */
+ if (i) {
+ i = 1 << (i + 2);
+ if (i < pagesz)
+ i -= sizeof (*op) + RSLOP;
+ else
+ i += pagesz - sizeof (*op) - RSLOP;
+ }
+
+ if (nbytes <= onb && nbytes > i) {
+#ifdef RCHECK
+ op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
+ *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+#endif
+ SEMAPHORE_RESET(lock);
+ return(cp);
+ }
+ SEMAPHORE_RESET(lock);
+
+ if ((res = malloc(nbytes)) == NULL) {
+ free(cp);
+ return (NULL);
+ }
+
+ bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
+ free(cp);
+
+ return (res);
+}
+
diff --git a/lib/libpthread/pthreads/mutex.c b/lib/libpthread/pthreads/mutex.c
new file mode 100644
index 00000000000..a269284ae2f
--- /dev/null
+++ b/lib/libpthread/pthreads/mutex.c
@@ -0,0 +1,227 @@
+/* ==== mutex.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Mutex functions.
+ *
+ * 1.00 93/07/19 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: mutex.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: mutex.c,v 1.16 1994/02/07 02:19:03 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+/*
+ * Basic mutex functionality
+
+ * This is the basic lock order
+ * queue
+ * pthread
+ * global
+ *
+ * semaphore functionality is defined in machdep.h
+ */
+
+/* ==========================================================================
+ * pthread_mutex_init()
+ *
+ * In this implementation I don't need to allocate memory.
+ * ENOMEM, EAGAIN should never be returned. Arch that have
+ * weird constraints may need special coding.
+ */
+int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *mutex_attr)
+{
+ /* Only check if attr specifies some mutex type other than fast */
+ if ((mutex_attr) && (mutex_attr->m_type != MUTEX_TYPE_FAST)) {
+ if (mutex_attr->m_type >= MUTEX_TYPE_MAX) {
+ return(EINVAL);
+ }
+ if (mutex->m_flags & MUTEX_FLAGS_INITED) {
+ return(EBUSY);
+ }
+ mutex->m_type = mutex_attr->m_type;
+ } else {
+ mutex->m_type = MUTEX_TYPE_FAST;
+ }
+ /* Set all other paramaters */
+ pthread_queue_init(&mutex->m_queue);
+ mutex->m_flags |= MUTEX_FLAGS_INITED;
+ mutex->m_lock = SEMAPHORE_CLEAR;
+ mutex->m_owner = NULL;
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_mutex_destroy()
+ */
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ /* Only check if mutex is of type other than fast */
+ switch(mutex->m_type) {
+ case MUTEX_TYPE_FAST:
+ break;
+ case MUTEX_TYPE_STATIC_FAST:
+ default:
+ return(EINVAL);
+ break;
+ }
+
+ /* Cleanup mutex, others might want to use it. */
+ pthread_queue_init(&mutex->m_queue);
+ mutex->m_flags |= MUTEX_FLAGS_INITED;
+ mutex->m_lock = SEMAPHORE_CLEAR;
+ mutex->m_owner = NULL;
+ mutex->m_flags = 0;
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_mutex_trylock()
+ */
+int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+ semaphore *lock;
+ int rval;
+
+ lock = &(mutex->m_lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ switch (mutex->m_type) {
+ /*
+ * Fast mutexes do not check for any error conditions.
+ */
+ case MUTEX_TYPE_FAST:
+ case MUTEX_TYPE_STATIC_FAST:
+ if (!mutex->m_owner) {
+ mutex->m_owner = pthread_run;
+ rval = OK;
+ } else {
+ rval = EBUSY;
+ }
+ break;
+ default:
+ rval = EINVAL;
+ break;
+ }
+ SEMAPHORE_RESET(lock);
+ return(rval);
+}
+
+/* ==========================================================================
+ * pthread_mutex_lock()
+ */
+int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ semaphore *lock, *plock;
+ int rval;
+
+ lock = &(mutex->m_lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ switch (mutex->m_type) {
+ /*
+ * Fast mutexes do not check for any error conditions.
+ */
+ case MUTEX_TYPE_FAST:
+ case MUTEX_TYPE_STATIC_FAST:
+ if (mutex->m_owner) {
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ pthread_queue_enq(&mutex->m_queue, pthread_run);
+ SEMAPHORE_RESET(lock);
+
+ /* Reschedule will unlock pthread_run */
+ reschedule(PS_MUTEX_WAIT);
+ return(OK);
+ }
+ mutex->m_owner = pthread_run;
+ rval = OK;
+ break;
+ default:
+ rval = EINVAL;
+ break;
+ }
+ SEMAPHORE_RESET(lock);
+ return(rval);
+}
+
+/* ==========================================================================
+ * pthread_mutex_unlock()
+ */
+int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ struct pthread *pthread;
+ semaphore *lock, *plock;
+ int rval;
+
+ lock = &(mutex->m_lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ switch (mutex->m_type) {
+ /*
+ * Fast mutexes do not check for any error conditions.
+ */
+ case MUTEX_TYPE_FAST:
+ case MUTEX_TYPE_STATIC_FAST:
+ if (pthread = pthread_queue_get(&mutex->m_queue)) {
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ mutex->m_owner = pthread;
+
+ /* Reset pthread state */
+ pthread_queue_deq(&mutex->m_queue);
+ pthread->state = PS_RUNNING;
+ SEMAPHORE_RESET(plock);
+ } else {
+ mutex->m_owner = NULL;
+ }
+ rval = OK;
+ break;
+ default:
+ rval = EINVAL;
+ break;
+ }
+ SEMAPHORE_RESET(lock);
+ return(rval);
+}
diff --git a/lib/libpthread/pthreads/pthread.c b/lib/libpthread/pthreads/pthread.c
new file mode 100644
index 00000000000..b16a14d67cb
--- /dev/null
+++ b/lib/libpthread/pthreads/pthread.c
@@ -0,0 +1,204 @@
+/* ==== pthread.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Pthread functions.
+ *
+ * 1.00 93/07/26 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: pthread.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: pthread.c,v 1.16 1994/02/07 02:19:06 proven Exp $";
+#endif
+
+#include "pthread.h"
+#include <signal.h>
+#include <errno.h>
+
+/*
+ * These first functions really should not be called by the user.
+ */
+
+/* ==========================================================================
+ * pthread_init()
+ *
+ * This function should be called in crt0.o before main() is called.
+ * But on some systems It may not be possible to change crt0.o so currently
+ * I'm requiring this function to be called first thing after main.
+ * Actually I'm assuming it is, because I do no locking here.
+ */
+void pthread_init(void)
+{
+ struct machdep_pthread machdep_data = MACHDEP_PTHREAD_INIT;
+
+ /* Initialize the first thread */
+ if (pthread_initial = (pthread_t)malloc(sizeof(struct pthread))) {
+ memcpy(&(pthread_initial->machdep_data), &machdep_data, sizeof(machdep_data));
+ pthread_initial->state = PS_RUNNING;
+ pthread_initial->queue = NULL;
+ pthread_initial->next = NULL;
+ pthread_initial->pll = NULL;
+
+ pthread_initial->lock = SEMAPHORE_CLEAR;
+ pthread_initial->error = 0;
+
+ pthread_link_list = pthread_initial;
+ pthread_run = pthread_initial;
+
+ /* Initialize the signal handler. */
+ sig_init();
+
+ /* Initialize the fd table. */
+ fd_init();
+
+ return;
+ }
+ PANIC();
+}
+
+/* ==========================================================================
+ * pthread_yield()
+ */
+void pthread_yield()
+{
+ sig_handler_fake(SIGVTALRM);
+}
+
+/* ======================================================================= */
+/* ==========================================================================
+ * pthread_self()
+ */
+pthread_t pthread_self()
+{
+ return(pthread_run);
+}
+
+/* ==========================================================================
+ * pthread_equal()
+ */
+int pthread_equal(pthread_t t1, pthread_t t2)
+{
+ return(t1 == t2);
+}
+
+/* ==========================================================================
+ * pthread_exit()
+ */
+void pthread_exit(void *status)
+{
+ semaphore *lock, *plock;
+ pthread_t pthread;
+
+ lock = &pthread_run->lock;
+ if (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* Save return value */
+ pthread_run->ret = status;
+
+ /* First execute all cleanup handlers */
+
+
+ /*
+ * Are there any threads joined to this one,
+ * if so wake them and let them detach this thread.
+ */
+ if (pthread = pthread_queue_get(&(pthread_run->join_queue))) {
+ /* The current thread pthread_run can't be detached */
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+ (void)pthread_queue_deq(&(pthread_run->join_queue));
+ pthread->state = PS_RUNNING;
+
+ /* Thread will unlock itself in pthread_join() */
+ }
+
+ /* This thread will never run again */
+ reschedule(PS_DEAD);
+ PANIC();
+}
+
+/* ==========================================================================
+ * pthread_create()
+ *
+ * After the new thread structure is allocated and set up, it is added to
+ * pthread_run_next_queue, which requires a sig_prevent(),
+ * sig_check_and_resume()
+ */
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void * (*start_routine)(void *), void *arg)
+{
+ long nsec = 100000000;
+ void *stack;
+
+ if ((*thread) = (pthread_t)malloc(sizeof(struct pthread))) {
+
+ if (! attr) { attr = &pthread_default_attr; }
+
+ /* Get a stack, if necessary */
+ if ((stack = attr->stackaddr_attr) ||
+ (stack = (void *)malloc(attr->stacksize_attr))) {
+
+ machdep_pthread_create(&((*thread)->machdep_data),
+ start_routine, arg, 65536, stack, nsec);
+
+ memcpy(&(*thread)->attr, attr, sizeof(pthread_attr_t));
+
+ (*thread)->queue = NULL;
+ (*thread)->next = NULL;
+
+ (*thread)->lock = SEMAPHORE_CLEAR;
+ (*thread)->error = 0;
+
+ sig_prevent();
+
+ /* Add to the link list of all threads. */
+ (*thread)->pll = pthread_link_list;
+ pthread_link_list = (*thread);
+
+ (*thread)->state = PS_RUNNING;
+ sig_check_and_resume();
+
+ return(OK);
+ }
+ free((*thread));
+ }
+ return(ENOMEM);
+}
+
+/* ==========================================================================
+ * pthread_cancel()
+ *
+ * This routine will also require a sig_prevent/sig_check_and_resume()
+ */
diff --git a/lib/libpthread/pthreads/pthread_attr.c b/lib/libpthread/pthreads/pthread_attr.c
new file mode 100644
index 00000000000..87ebfced7a0
--- /dev/null
+++ b/lib/libpthread/pthreads/pthread_attr.c
@@ -0,0 +1,100 @@
+/* ==== pthread_attr.c =======================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Pthread attribute functions.
+ *
+ * 1.00 93/11/04 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: pthread_attr.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: pthread_attr.c,v 1.16 1994/02/07 02:19:14 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <errno.h>
+
+/* Currently we do no locking, should we just to be safe? CAP */
+/* ==========================================================================
+ * pthread_attr_init()
+ */
+int pthread_attr_init(pthread_attr_t *attr)
+{
+ memcpy(attr, &pthread_default_attr, sizeof(pthread_attr_t));
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_attr_destroy()
+ */
+int pthread_attr_destroy(pthread_attr_t *attr)
+{
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_attr_getstacksize()
+ */
+int pthread_attr_getstacksize(pthread_attr_t *attr, size_t * stacksize)
+{
+ *stacksize = attr->stacksize_attr;
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_attr_setstacksize()
+ */
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+ if (stacksize >= PTHREAD_STACK_MIN) {
+ attr->stacksize_attr = stacksize;
+ return(OK);
+ }
+ return(EINVAL);
+}
+
+/* ==========================================================================
+ * pthread_attr_getstackaddr()
+ */
+int pthread_attr_getstackaddr(pthread_attr_t *attr, void ** stackaddr)
+{
+ *stackaddr = attr->stackaddr_attr;
+ return(OK);
+}
+
+/* ==========================================================================
+ * pthread_attr_setstackaddr()
+ */
+int pthread_attr_setstackaddr(pthread_attr_t *attr, void * stackaddr)
+{
+ attr->stackaddr_attr = stackaddr;
+ return(OK);
+}
diff --git a/lib/libpthread/pthreads/pthread_detach.c b/lib/libpthread/pthreads/pthread_detach.c
new file mode 100644
index 00000000000..37ac35de292
--- /dev/null
+++ b/lib/libpthread/pthreads/pthread_detach.c
@@ -0,0 +1,90 @@
+/* ==== pthread_detach.c =======================================================
+ * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : pthread_join function.
+ *
+ * 1.00 94/01/15 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: pthread_detach.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: pthread_detach.c,v 1.16 1994/02/07 02:19:16 proven Exp $";
+#endif
+
+#include <pthread.h>
+
+/* ==========================================================================
+ * pthread_detach()
+ */
+int pthread_detach(pthread_t pthread)
+{
+ semaphore *plock;
+ int ret;
+
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* Check that thread isn't detached already */
+ if (!(pthread->flags & PF_DETACHED)) {
+
+ pthread->flags |= PF_DETACHED;
+
+ /* Wakeup first threads waiting on a join */
+ {
+ struct pthread * next_thread;
+ semaphore * next_lock;
+
+ if (next_thread = pthread_queue_get(&(pthread->join_queue))) {
+ next_lock = &(next_thread->lock);
+ while (SEMAPHORE_TEST_AND_SET(next_lock)) {
+ pthread_yield();
+ }
+ pthread_queue_deq(&(pthread->join_queue));
+ next_thread->state = PS_RUNNING;
+ /*
+ * Thread will wake up in pthread_join(), see the thread
+ * it was joined to already detached and unlock itself
+ * and pthread
+ */
+ } else {
+ SEMAPHORE_RESET(plock);
+ }
+ }
+ ret = OK;
+
+ } else {
+ SEMAPHORE_RESET(plock);
+ ret = ESRCH;
+ }
+ return(ret);
+}
diff --git a/lib/libpthread/pthreads/pthread_join.c b/lib/libpthread/pthreads/pthread_join.c
new file mode 100644
index 00000000000..b94ce3a70ea
--- /dev/null
+++ b/lib/libpthread/pthreads/pthread_join.c
@@ -0,0 +1,113 @@
+/* ==== pthread_join.c =======================================================
+ * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : pthread_join function.
+ *
+ * 1.00 94/01/15 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: pthread_join.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: pthread_join.c,v 1.16 1994/02/07 02:19:19 proven Exp $";
+#endif
+
+#include <pthread.h>
+
+/* ==========================================================================
+ * pthread_join()
+ */
+int pthread_join(pthread_t pthread, void **thread_return)
+{
+ semaphore *lock, *plock;
+ int ret;
+
+
+ plock = &(pthread->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* Check that thread isn't detached already */
+ if (pthread->flags & PF_DETACHED) {
+ SEMAPHORE_RESET(plock);
+ return(ESRCH);
+ }
+
+ lock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* If OK then queue current thread. */
+ pthread_queue(&(pthread->join_queue), pthread_run);
+
+ SEMAPHORE_RESET(plock);
+ reschedule(PS_JOIN);
+
+ /*
+ * At this point the thread is locked from the pthread_exit
+ * and so are we, so no extra locking is required, but be sure
+ * to unlock at least ourself.
+ */
+ if (!(pthread->flags & PF_DETACHED)) {
+ if (thread_return) {
+ *thread_return = pthread->ret;
+ }
+ pthread->flags |= PF_DETACHED;
+ ret = OK;
+ } else {
+ ret = ESRCH;
+ }
+
+ /* Cant do a cleanup until queue is cleared */
+ {
+ struct pthread * next_thread;
+ semaphore * next_lock;
+
+ if (next_thread = pthread_queue_get(&(pthread->join_queue))) {
+ next_lock = &(next_thread->lock);
+ while (SEMAPHORE_TEST_AND_SET(next_lock)) {
+ pthread_yield();
+ }
+ pthread_queue_deq(&(pthread->join_queue));
+ next_thread->state = PS_RUNNING;
+ /*
+ * Thread will wake up in pthread_join(), see the thread
+ * it was joined to already detached and unlock itself
+ */
+ } else {
+ SEMAPHORE_RESET(lock);
+ }
+ }
+
+ SEMAPHORE_RESET(plock);
+ return(ret);
+}
diff --git a/lib/libpthread/pthreads/pthread_once.c b/lib/libpthread/pthreads/pthread_once.c
new file mode 100644
index 00000000000..26a530971b0
--- /dev/null
+++ b/lib/libpthread/pthreads/pthread_once.c
@@ -0,0 +1,61 @@
+/* ==== pthread_once.c =======================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : pthread_once function.
+ *
+ * 1.00 93/12/12 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: pthread_once.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: pthread_once.c,v 1.4 1994/02/07 02:19:22 proven Exp $";
+#endif
+
+#include <pthread.h>
+
+/* ==========================================================================
+ * pthread_once()
+ */
+static pthread_mutex_t __pthread_once_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
+{
+ /* Check first for speed */
+ if (*once_control == PTHREAD_ONCE_INIT) {
+ pthread_mutex_lock(&__pthread_once_mutex);
+ if (*once_control == PTHREAD_ONCE_INIT) {
+ init_routine();
+ (*once_control)++;
+ }
+ pthread_mutex_unlock(&__pthread_once_mutex);
+ }
+ return(OK);
+}
diff --git a/lib/libpthread/pthreads/queue.c b/lib/libpthread/pthreads/queue.c
new file mode 100644
index 00000000000..dd662136c51
--- /dev/null
+++ b/lib/libpthread/pthreads/queue.c
@@ -0,0 +1,123 @@
+/* ==== queue.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Queue functions.
+ *
+ * 1.00 93/07/15 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: queue.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: queue.c,v 1.16 1994/02/07 02:19:24 proven Exp $";
+#endif
+
+#include <pthread.h>
+
+/*
+ * All routines in this file assume that the queue has been appropriatly
+ * locked.
+ */
+
+/* ==========================================================================
+ * pthread_queue_init()
+ */
+void pthread_queue_init(struct pthread_queue *queue)
+{
+ queue->q_next = NULL;
+ queue->q_last = NULL;
+ queue->q_data = NULL;
+}
+
+/* ==========================================================================
+ * pthread_queue_enq()
+ */
+void pthread_queue_enq(struct pthread_queue *queue, struct pthread *thread)
+{
+ if (queue->q_last) {
+ queue->q_last->next = thread;
+ } else {
+ queue->q_next = thread;
+ }
+ queue->q_last = thread;
+ thread->queue = queue;
+ thread->next = NULL;
+
+}
+
+/* ==========================================================================
+ * pthread_queue_get()
+ */
+struct pthread *pthread_queue_get(struct pthread_queue *queue)
+{
+ return(queue->q_next);
+}
+
+/* ==========================================================================
+ * pthread_queue_deq()
+ */
+struct pthread *pthread_queue_deq(struct pthread_queue *queue)
+{
+ struct pthread *thread = NULL;
+
+ if (queue->q_next) {
+ thread = queue->q_next;
+ if (!(queue->q_next = queue->q_next->next)) {
+ queue->q_last = NULL;
+ }
+ thread->queue = NULL;
+ thread->next = NULL;
+ }
+ return(thread);
+}
+
+/* ==========================================================================
+ * pthread_queue_remove()
+ */
+void pthread_queue_remove(struct pthread_queue *queue, struct pthread *thread)
+{
+ struct pthread **current = &(queue->q_next);
+ struct pthread *prev = NULL;
+
+ while (*current) {
+ if (*current == thread) {
+ if ((*current)->next) {
+ *current = (*current)->next;
+ } else {
+ queue->q_last = prev;
+ *current = NULL;
+ }
+ }
+ prev = *current;
+ current = &((*current)->next);
+ }
+ thread->queue = NULL;
+ thread->next = NULL;
+}
diff --git a/lib/libpthread/pthreads/signal.c b/lib/libpthread/pthreads/signal.c
new file mode 100644
index 00000000000..5bdbe6892d7
--- /dev/null
+++ b/lib/libpthread/pthreads/signal.c
@@ -0,0 +1,445 @@
+/* ==== signal.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Queue functions.
+ *
+ * 1.00 93/07/21 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: signal.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: signal.c,v 1.18 1994/02/07 02:19:28 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <signal.h>
+
+/*
+ * Time which select in fd_kern_wait() will sleep.
+ * If there are no threads to run we sleep for an hour or until
+ * we get an interrupt or an fd thats awakens. To make sure we
+ * don't miss an interrupt this variable gets reset too zero in
+ * sig_handler_real().
+ */
+struct timeval __fd_kern_wait_timeout = { 0, 0 };
+
+/*
+ * Global for user-kernel lock, and blocked signals
+ */
+static volatile sigset_t sig_to_tryagain;
+static volatile sigset_t sig_to_process;
+static volatile int kernel_lock = 0;
+static volatile int sig_count = 0;
+
+static void sig_handler(int signal);
+static void set_thread_timer();
+void sig_prevent(void);
+void sig_resume(void);
+
+/* ==========================================================================
+ * context_switch()
+ *
+ * This routine saves the current state of the running thread gets
+ * the next thread to run and restores it's state. To allow different
+ * processors to work with this routine, I allow the machdep_restore_state()
+ * to either return or have it return from machdep_save_state with a value
+ * other than 0, this is for implementations which use setjmp/longjmp.
+ */
+static void context_switch()
+{
+ struct pthread **current, *next, *last;
+ semaphore *lock;
+ int count;
+
+ /* save state of current thread */
+ if (machdep_save_state()) {
+ return;
+ }
+
+ last = pthread_run;
+ if (pthread_run = pthread_queue_deq(&pthread_current_queue)) {
+ /* restore state of new current thread */
+ machdep_restore_state();
+ return;
+ }
+
+ /* Poll all the kernel fds */
+ fd_kern_poll();
+
+context_switch_reschedule:;
+ /*
+ * Go through the reschedule list once, this is the only place
+ * that goes through the queue without using the queue routines.
+ *
+ * But first delete the current queue.
+ */
+ pthread_queue_init(&pthread_current_queue);
+ current = &(pthread_link_list);
+ count = 0;
+
+ while (*current) {
+ switch((*current)->state) {
+ case PS_RUNNING:
+ pthread_queue_enq(&pthread_current_queue, *current);
+ current = &((*current)->pll);
+ count++;
+ break;
+ case PS_DEAD:
+ /* Cleanup thread, unless we're using the stack */
+ if (((*current)->flags & PF_DETACHED) && (*current != last)) {
+ next = (*current)->pll;
+ lock = &((*current)->lock);
+ if (SEMAPHORE_TEST_AND_SET(lock)) {
+ /* Couldn't cleanup this time, try again later */
+ current = &((*current)->pll);
+ } else {
+ if (!((*current)->attr.stackaddr_attr)) {
+ free (machdep_pthread_cleanup(&((*current)->machdep_data)));
+ }
+ free (*current);
+ *current = next;
+ }
+ } else {
+ current = &((*current)->pll);
+ }
+ break;
+ default:
+ /* Should be on a different queue. Ignore. */
+ current = &((*current)->pll);
+ count++;
+ break;
+ }
+ }
+
+ /* Are there any threads to run */
+ if (pthread_run = pthread_queue_deq(&pthread_current_queue)) {
+ /* restore state of new current thread */
+ machdep_restore_state();
+ return;
+ }
+
+ /* Are there any threads at all */
+ if (count) {
+ /*
+ * Do a wait, timeout is set to a hour unless we get an interrupt
+ * before the select in wich case it polls and returns.
+ */
+ fd_kern_wait();
+
+ /* Check for interrupts, but ignore SIGVTALR */
+ sigdelset(&sig_to_process, SIGVTALRM);
+
+ if (sig_to_process) {
+ /* Process interrupts */
+ sig_handler(0);
+ }
+
+ goto context_switch_reschedule;
+
+ }
+ exit(0);
+}
+
+/* ==========================================================================
+ * sig_handler_pause()
+ *
+ * Wait until a signal is sent to the process.
+ */
+void sig_handler_pause()
+{
+ sigset_t sig_to_block, sig_to_pause;
+
+ sigfillset(&sig_to_block);
+ sigemptyset(&sig_to_pause);
+ sigprocmask(SIG_BLOCK, &sig_to_block, NULL);
+ if (!sig_to_process) {
+ sigsuspend(&sig_to_pause);
+ }
+ sigprocmask(SIG_UNBLOCK, &sig_to_block, NULL);
+}
+
+/* ==========================================================================
+ * context_switch_done()
+ *
+ * This routine does all the things that are necessary after a context_switch()
+ * calls the machdep_restore_state(). DO NOT put this in the context_switch()
+ * routine because sometimes the machdep_restore_state() doesn't return
+ * to context_switch() but instead ends up in machdep_thread_start() or
+ * some such routine, which will need to call this routine and
+ * sig_check_and_resume().
+ */
+void context_switch_done()
+{
+ sigdelset(&sig_to_process, SIGVTALRM);
+ set_thread_timer();
+}
+
+/* ==========================================================================
+ * set_thread_timer()
+ *
+ * Assums kernel is locked.
+ */
+static void set_thread_timer()
+{
+ static int last_sched_attr = SCHED_RR;
+
+ switch (pthread_run->attr.sched_attr) {
+ case SCHED_RR:
+ machdep_set_thread_timer(&(pthread_run->machdep_data));
+ break;
+ case SCHED_FIFO:
+ if (last_sched_attr != SCHED_FIFO) {
+ machdep_unset_thread_timer();
+ }
+ break;
+ case SCHED_IO:
+ if ((last_sched_attr != SCHED_IO) && (!sig_count)) {
+ machdep_set_thread_timer(&(pthread_run->machdep_data));
+ }
+ break;
+ default:
+ machdep_set_thread_timer(&(pthread_run->machdep_data));
+ break;
+ }
+ last_sched_attr = pthread_run->attr.sched_attr;
+}
+
+/* ==========================================================================
+ * sig_handler()
+ *
+ * Assumes the kernel is locked.
+ */
+static void sig_handler(int sig)
+{
+
+ /*
+ * First check for old signals, do one pass through and don't
+ * check any twice.
+ */
+ if (sig_to_tryagain) {
+ if (sigismember(&sig_to_tryagain, SIGALRM)) {
+ switch (sleep_wakeup()) {
+ case 1:
+ /* Do the default action, no threads were sleeping */
+ case OK:
+ /* Woke up a sleeping thread */
+ sigdelset(&sig_to_tryagain, SIGALRM);
+ break;
+ case NOTOK:
+ /* Couldn't get appropriate locks, try again later */
+ break;
+ }
+ } else {
+ PANIC();
+ }
+ }
+
+ /*
+ * NOW, process signal that just came in, plus any pending on the
+ * signal mask. All of these must be resolved.
+ */
+
+sig_handler_top:;
+
+ switch(sig) {
+ case 0:
+ break;
+ case SIGVTALRM:
+ if (sig_count) {
+ sigset_t sigall;
+
+ sig_count = 0;
+
+ /* Unblock all signals */
+ sigemptyset(&sigall);
+ sigprocmask(SIG_SETMASK, &sigall, NULL);
+ }
+ context_switch();
+ context_switch_done();
+ break;
+ case SIGALRM:
+ sigdelset(&sig_to_process, SIGALRM);
+ switch (sleep_wakeup()) {
+ case 1:
+ /* Do the default action, no threads were sleeping */
+ case OK:
+ /* Woke up a sleeping thread */
+ break;
+ case NOTOK:
+ /* Couldn't get appropriate locks, try again later */
+ sigaddset(&sig_to_tryagain, SIGALRM);
+ break;
+ }
+ break;
+ default:
+ PANIC();
+ }
+
+ /* Determine if there are any other signals */
+ if (sig_to_process) {
+ for (sig = 1; sig <= SIGMAX; sig++) {
+ if (sigismember(&sig_to_process, sig)) {
+
+ /* goto sig_handler_top */
+ goto sig_handler_top;
+ }
+ }
+ }
+}
+
+/* ==========================================================================
+ * sig_handler_real()
+ *
+ * On a multi-processor this would need to use the test and set instruction
+ * otherwise the following will work.
+ */
+void sig_handler_real(int sig)
+{
+ if (kernel_lock) {
+ __fd_kern_wait_timeout.tv_sec = 0;
+ sigaddset(&sig_to_process, sig);
+ return;
+ }
+ sig_prevent();
+ sig_count++;
+ sig_handler(sig);
+ sig_resume();
+}
+
+/* ==========================================================================
+ * sig_handler_fake()
+ */
+void sig_handler_fake(int sig)
+{
+ if (kernel_lock) {
+ /* Currently this should be impossible */
+ PANIC();
+ }
+ sig_prevent();
+ sig_handler(sig);
+ sig_resume();
+}
+
+/* ==========================================================================
+ * reschedule()
+ *
+ * This routine assumes that the caller is the current pthread, pthread_run
+ * and that it has a lock on itself and that it wants to reschedule itself.
+ */
+void reschedule(enum pthread_state state)
+{
+ semaphore *plock;
+
+ if (kernel_lock) {
+ /* Currently this should be impossible */
+ PANIC();
+ }
+ sig_prevent();
+ pthread_run->state = state;
+ SEMAPHORE_RESET((plock = &(pthread_run->lock)));
+ sig_handler(SIGVTALRM);
+ sig_resume();
+}
+
+/* ==========================================================================
+ * sig_prevent()
+ */
+void sig_prevent(void)
+{
+ kernel_lock++;
+}
+
+/* ==========================================================================
+ * sig_resume()
+ */
+void sig_resume()
+{
+ kernel_lock--;
+}
+
+/* ==========================================================================
+ * sig_check_and_resume()
+ */
+void sig_check_and_resume()
+{
+ /* Some routine name that is yet to be determined. */
+
+ /* Only bother if we are truely unlocking the kernel */
+ while (!(--kernel_lock)) {
+
+ /* Assume sigset_t is not a struct or union */
+ if (sig_to_process) {
+ kernel_lock++;
+ sig_handler(0);
+ } else {
+ break;
+ }
+ }
+}
+
+/* ==========================================================================
+ * sig_init()
+ *
+ * SIGVTALRM (NOT POSIX) needed for thread timeslice timeouts.
+ * Since it's not POSIX I will replace it with a
+ * virtual timer for threads.
+ * SIGALRM (IS POSIX) so some special handling will be
+ * necessary to fake SIGALRM signals
+ */
+void sig_init(void)
+{
+ int sig_to_init[] = { SIGVTALRM, SIGALRM, 0 };
+
+#if defined(SA_RESTART)
+ struct sigaction act;
+#endif
+
+ int i;
+
+#if defined(SA_RESTART)
+ act.sa_handler = sig_handler_real;
+ sigemptyset(&(act.sa_mask));
+ act.sa_flags = SA_RESTART;
+#endif
+
+ /* Initialize only the necessary signals */
+ for (i = 0; sig_to_init[i]; i++) {
+
+#if defined(SA_RESTART)
+ if (sigaction(sig_to_init[i], &act, NULL)) {
+#else
+ if (signal(sig_to_init[i], sig_handler_real)) {
+#endif
+ PANIC();
+ }
+ }
+}
+
diff --git a/lib/libpthread/pthreads/sleep.c b/lib/libpthread/pthreads/sleep.c
new file mode 100644
index 00000000000..1b76f26391f
--- /dev/null
+++ b/lib/libpthread/pthreads/sleep.c
@@ -0,0 +1,256 @@
+/* ==== sleep.c ============================================================
+ * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano.
+ * 4. The name of Chris Provenzano may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Description : Condition cariable functions.
+ *
+ * 1.00 93/12/28 proven
+ * -Started coding this file.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: sleep.c,v 1.1 1995/10/18 08:43:05 deraadt Exp $ $provenid: sleep.c,v 1.18 1994/02/07 02:19:31 proven Exp $";
+#endif
+
+#include <pthread.h>
+#include <unistd.h>
+
+struct pthread * pthread_sleep = NULL;
+semaphore sleep_semaphore = SEMAPHORE_CLEAR;
+
+
+#include <sys/time.h>
+#include <stdio.h>
+
+/* ==========================================================================
+ * machdep_start_timer()
+ */
+int machdep_start_timer(struct itimerval *start_time_val)
+{
+ setitimer(ITIMER_REAL, start_time_val, NULL);
+ return(OK);
+}
+
+/* ==========================================================================
+ * machdep_stop_timer()
+ */
+struct itimerval stop_time_val = { { 0, 0 }, { 0, 0 } };
+int machdep_stop_timer(struct itimerval * current)
+{
+ setitimer(ITIMER_REAL, &stop_time_val, current);
+ return(OK);
+}
+
+/* ==========================================================================
+ * machdep_sub_timer()
+ *
+ * formula is: new -= current;
+ */
+static inline void machdep_sub_timer(struct itimerval * new,
+ struct itimerval * current)
+{
+ new->it_value.tv_usec -= current->it_value.tv_usec;
+ if (new->it_value.tv_usec < 0) {
+ new->it_value.tv_usec += 1000000;
+ new->it_value.tv_sec--;
+ }
+ new->it_value.tv_sec -= current->it_value.tv_sec;
+}
+
+
+/* ==========================================================================
+ * sleep_basic_wakeup()
+ *
+ * The real work of sleep_wakeup is done here.
+ */
+static inline int sleep_basic_wakeup()
+{
+ struct pthread *pthread_sleep_next;
+ struct itimerval current_time;
+ semaphore *plock;
+
+ machdep_stop_timer(&current_time);
+ do {
+ plock = &(pthread_sleep->lock);
+ if (SEMAPHORE_TEST_AND_SET(plock)) {
+ return(NOTOK);
+ }
+
+ /* return remaining time */
+ pthread_sleep->time_sec = current_time.it_value.tv_sec;
+ pthread_sleep->time_usec = current_time.it_value.tv_usec;
+
+ if (pthread_sleep_next = pthread_sleep->sll) {
+ pthread_sleep_next->time_usec += current_time.it_value.tv_usec;
+ current_time.it_value.tv_usec = pthread_sleep_next->time_usec;
+ pthread_sleep_next->time_sec += current_time.it_value.tv_sec;
+ current_time.it_value.tv_sec = pthread_sleep_next->time_sec;
+ }
+
+ /* Clean up removed thread and start it runnng again. */
+ pthread_sleep->state = PS_RUNNING;
+ pthread_sleep->sll = NULL;
+ SEMAPHORE_RESET(plock);
+
+ /* Set top of queue to next queue item */
+ pthread_sleep = pthread_sleep_next;
+
+ if (current_time.it_value.tv_sec || current_time.it_value.tv_usec) {
+ machdep_start_timer(&current_time);
+ break;
+ }
+
+ } while(pthread_sleep);
+ return(OK);
+}
+
+/* ==========================================================================
+ * sleep_wakeup()
+ *
+ * This routine is called by the interrupt handler. It cannot call
+ * pthread_yield() thenrfore it returns NOTOK to inform the handler
+ * that it will have to be called at a later time.
+ */
+int sleep_wakeup()
+{
+ semaphore *lock, *plock;
+ int ret;
+
+ /* Lock sleep queue */
+ lock = &(sleep_semaphore);
+ if (SEMAPHORE_TEST_AND_SET(lock)) {
+ return(NOTOK);
+ }
+
+ if (pthread_sleep) {
+ ret = sleep_basic_wakeup();
+ } else {
+ ret = NOTOK;
+ }
+
+ SEMAPHORE_RESET(lock);
+ return(ret);
+}
+
+/* ==========================================================================
+ * sleep()
+ */
+unsigned int sleep(unsigned int seconds)
+{
+ struct pthread *pthread_sleep_current, *pthread_sleep_prev;
+ struct itimerval current_time, new_time;
+ semaphore *lock, *plock;
+
+ if (seconds) {
+ /* Lock current thread */
+ plock = &(pthread_run->lock);
+ while (SEMAPHORE_TEST_AND_SET(plock)) {
+ pthread_yield();
+ }
+
+ /* Set new_time timer value */
+ new_time.it_value.tv_usec = 0;
+ new_time.it_value.tv_sec = seconds;
+ new_time.it_interval.tv_usec = 0;
+ new_time.it_interval.tv_sec = 0;
+
+ /* Lock sleep queue */
+ lock = &(sleep_semaphore);
+ while (SEMAPHORE_TEST_AND_SET(lock)) {
+ pthread_yield();
+ }
+
+ /* any threads? */
+ if (pthread_sleep_current = pthread_sleep) {
+
+ machdep_stop_timer(&current_time);
+
+ /* Is remaining time left <= new thread time */
+ if (current_time.it_value.tv_sec <= new_time.it_value.tv_sec) {
+ machdep_sub_timer(&new_time, &current_time);
+ machdep_start_timer(&current_time);
+
+ while (pthread_sleep_current->sll) {
+ pthread_sleep_prev = pthread_sleep_current;
+ pthread_sleep_current = pthread_sleep_current->sll;
+ current_time.it_value.tv_sec = pthread_sleep_current->time_sec;
+
+ if ((current_time.it_value.tv_sec > new_time.it_value.tv_sec) ||
+ ((current_time.it_value.tv_sec == new_time.it_value.tv_sec) &&
+ (current_time.it_value.tv_usec > new_time.it_value.tv_usec))) {
+ pthread_run->time_usec = new_time.it_value.tv_usec;
+ pthread_run->time_sec = new_time.it_value.tv_sec;
+ machdep_sub_timer(&current_time, &new_time);
+ pthread_run->sll = pthread_sleep_current;
+ pthread_sleep_prev->sll = pthread_run;
+
+ /* Unlock sleep mutex */
+ SEMAPHORE_RESET(lock);
+
+ /* Reschedule thread */
+ reschedule(PS_SLEEP_WAIT);
+
+ return(pthread_run->time_sec);
+ }
+ machdep_sub_timer(&new_time, &current_time);
+
+ }
+
+ /* No more threads in queue, attach pthread_run to end of list */
+ pthread_sleep_current->sll = pthread_run;
+ pthread_run->sll = NULL;
+
+ } else {
+ /* Start timer and enqueue thread */
+ machdep_start_timer(&new_time);
+ machdep_sub_timer(&current_time, &new_time);
+ pthread_run->sll = pthread_sleep_current;
+ pthread_sleep = pthread_run;
+ }
+ } else {
+ /* Start timer and enqueue thread */
+ machdep_start_timer(&new_time);
+ pthread_sleep = pthread_run;
+ pthread_run->sll = NULL;
+ }
+
+ pthread_run->time_usec = new_time.it_value.tv_usec;
+ pthread_run->time_sec = new_time.it_value.tv_sec;
+
+ /* Unlock sleep mutex */
+ SEMAPHORE_RESET(lock);
+
+ /* Reschedule thread */
+ reschedule(PS_SLEEP_WAIT);
+
+ }
+ return(pthread_run->time_sec);
+}
+
diff --git a/lib/libpthread/stdio/Makefile.inc b/lib/libpthread/stdio/Makefile.inc
new file mode 100644
index 00000000000..ff13440c8d0
--- /dev/null
+++ b/lib/libpthread/stdio/Makefile.inc
@@ -0,0 +1,18 @@
+# from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91
+# $Id: Makefile.inc,v 1.1 1995/10/18 08:43:05 deraadt Exp $
+
+# Thread safe stdio sources
+.PATH: ${.CURDIR}/stdio
+
+SRCS+= clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
+ fgetline.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \
+ fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
+ fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
+ getc.c getchar.c gets.c getw.c makebuf.c perror.c printf.c putc.c \
+ putchar.c puts.c putw.c refill.c remove.c rewind.c rget.c scanf.c \
+ setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c sscanf.c \
+ stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vfprintf.c \
+ vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
+ wsetup.c putc_unlocked.c putchar_unlocked.c getc_unlocked.c \
+ getchar_unlocked.c strerror.c wbuf.c
+
diff --git a/lib/libpthread/stdio/README b/lib/libpthread/stdio/README
new file mode 100644
index 00000000000..017f61f1b46
--- /dev/null
+++ b/lib/libpthread/stdio/README
@@ -0,0 +1,40 @@
+This is a threadsafe stdio based on the BSD stdio written by Chris Torek.
+
+INCLUDE FILES AND PORTING
+To continue to make this package portable, some basic rules on includes
+files must be followed.
+
+pthread.h should be included first (if it is to be included).
+stdio.h should be included.
+
+INTERNAL LOCKING
+1. All functions that can be called by the user must have __flockfile at the
+ begining and a __funlockfile at the end. __Flockfile is a counting mutex,
+ The thread that owns the lock can call __flockfile as many times as
+ it wants, but must call an equal number of __funlockfile before the
+ lock will be released.
+2. All functions starting with __ shouldn't need addtional locking.
+3. Anything that writes the variable __sglue should lock __sfp_mutex,
+ check __sfp_state, and do a condion wait if it is set.
+4. Anything that checks fp->_flag for valididity should also lock
+ __sfp_mutex.
+5. Anything that reads the variable __sglue should lock __sfp_mutex, increment
+ __sfp_state, and then unlock the mutex. At function return it should
+ lock the mutex again decrement __sfp_state and check if zero. If so
+ do a cond_signal, and unlock the mutex.
+6. The functions fopen, fdopen, and freopen are the only functions that
+ will change a fp->_file
+7. fdopen and fopen both allocate the next fp by locking __sfp_mutex
+ checking fp->_flags and then setting it if free.
+8. freopen tries to preserve fp->_file. It sets __sfp_mutex, then it
+ tries to lock fp->_file and close it.
+9. __sinit is done with a pthread_once routine.
+
+Copyright (c) 1993 Chris Provenzano. All rights reserved.
+
+This product includes software developed by the Univeristy of California,
+Berkeley and its contributors.
+
+
+Things to do.
+Fix printf so it uses the ininf function.
diff --git a/lib/libpthread/stdio/clrerr.c b/lib/libpthread/stdio/clrerr.c
new file mode 100644
index 00000000000..5989b6484b9
--- /dev/null
+++ b/lib/libpthread/stdio/clrerr.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clrerr.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: clrerr.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+void clearerr(FILE *fp)
+{
+ flockfile(fp);
+ fp->_flags &= ~(__SERR|__SEOF);
+ funlockfile(fp);
+}
diff --git a/lib/libpthread/stdio/fclose.c b/lib/libpthread/stdio/fclose.c
new file mode 100644
index 00000000000..538e0db8a35
--- /dev/null
+++ b/lib/libpthread/stdio/fclose.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fclose.c 5.2 (Berkeley) 2/1/91";*/
+static char *rcsid = "$Id: fclose.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/* Do not reset the fd */
+fclose(fp)
+ register FILE *fp;
+{
+ register int r;
+
+ if (fp->_flags) {
+ flockfile(fp);
+ r = fp->_flags & __SWR ? __sflush(fp) : 0;
+ if (__sclose(fp) < 0)
+ r = EOF;
+ if (fp->_flags & __SMBF)
+ free((char *)fp->_bf._base);
+ if (HASUB(fp))
+ FREEUB(fp);
+ if (HASLB(fp))
+ FREELB(fp);
+ fp->_flags = 0; /* release this FILE for reuse, DO THIS LAST */
+ funlockfile(fp);
+ return(r);
+ }
+ errno = EBADF;
+ return(EOF);
+}
diff --git a/lib/libpthread/stdio/fdopen.c b/lib/libpthread/stdio/fdopen.c
new file mode 100644
index 00000000000..8d860bbeac2
--- /dev/null
+++ b/lib/libpthread/stdio/fdopen.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fdopen.c 5.6 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: fdopen.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+extern pthread_mutex_t __sfp_mutex;
+extern pthread_cond_t __sfp_cond;
+extern int __sfp_state;
+
+FILE *fdopen(int fd, const char *mode)
+{
+ register FILE *fp;
+ int flags, oflags, fdflags, tmp;
+
+ if ((flags = __sflags(mode, &oflags)) == 0)
+ return (NULL);
+
+ /* Make sure the mode the user wants is a subset of the actual mode. */
+ if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
+ return (NULL);
+ tmp = fdflags & O_ACCMODE;
+ if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ pthread_once(&__sdidinit, __sinit);
+ pthread_mutex_lock(&__sfp_mutex);
+ while (__sfp_state) {
+ pthread_cond_wait(&__sfp_cond, &__sfp_mutex);
+ }
+
+ if (fp = __sfp()) {
+ fp->_flags = flags;
+
+ /*
+ * If opened for appending, but underlying descriptor does not have
+ * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
+ * end before each write.
+ */
+ if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
+ fp->_flags |= __SAPP;
+ fp->_file = fd;
+
+ }
+ pthread_mutex_unlock(&__sfp_mutex);
+ return (fp);
+}
diff --git a/lib/libpthread/stdio/feof.c b/lib/libpthread/stdio/feof.c
new file mode 100644
index 00000000000..53e09f5ea50
--- /dev/null
+++ b/lib/libpthread/stdio/feof.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)feof.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: feof.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro feof.
+ */
+#undef feof
+
+feof(fp)
+ FILE *fp;
+{
+ return (__sfeof(fp));
+}
diff --git a/lib/libpthread/stdio/ferror.c b/lib/libpthread/stdio/ferror.c
new file mode 100644
index 00000000000..7e12f1d6a87
--- /dev/null
+++ b/lib/libpthread/stdio/ferror.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)ferror.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: ferror.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro ferror.
+ */
+#undef ferror
+
+ferror(fp)
+ FILE *fp;
+{
+ return (__sferror(fp));
+}
diff --git a/lib/libpthread/stdio/fflush.c b/lib/libpthread/stdio/fflush.c
new file mode 100644
index 00000000000..5e9f72c05ed
--- /dev/null
+++ b/lib/libpthread/stdio/fflush.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fflush.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fflush.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include "local.h"
+
+/* Flush a single file, or (if fp is NULL) all files. */
+fflush(fp)
+ register FILE *fp;
+{
+ int retval;
+
+ if (fp == NULL)
+ return (__swalk_sflush);
+ flockfile(fp);
+
+ if ((fp->_flags & (__SWR | __SRW)) == 0) {
+ errno = EBADF;
+ retval = EOF;
+ } else {
+ retval = __sflush(fp);
+ }
+ funlockfile(fp);
+ return(retval);
+}
+
+__sflush(fp)
+ register FILE *fp;
+{
+ register unsigned char *p;
+ register int n, t;
+
+ t = fp->_flags;
+ if ((t & __SWR) == 0)
+ return (0);
+
+ if ((p = fp->_bf._base) == NULL)
+ return (0);
+
+ n = fp->_p - p; /* write this much */
+
+ /*
+ * Set these immediately to avoid problems with longjmp and to allow
+ * exchange buffering (via setvbuf) in user write function.
+ */
+ fp->_p = p;
+ fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+
+ for (; n > 0; n -= t, p += t) {
+ t = __swrite(fp, (char *)p, n);
+ if (t <= 0) {
+ fp->_flags |= __SERR;
+ return (EOF);
+ }
+ }
+ return (0);
+}
diff --git a/lib/libpthread/stdio/fgetc.c b/lib/libpthread/stdio/fgetc.c
new file mode 100644
index 00000000000..382aac0602f
--- /dev/null
+++ b/lib/libpthread/stdio/fgetc.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fgetc.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fgetc.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+fgetc(fp)
+ FILE *fp;
+{
+ flockfile(fp);
+ return (__sgetc(fp));
+ funlockfile(fp);
+}
diff --git a/lib/libpthread/stdio/fgetline.c b/lib/libpthread/stdio/fgetline.c
new file mode 100644
index 00000000000..320b306e745
--- /dev/null
+++ b/lib/libpthread/stdio/fgetline.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fgetline.c 5.2 (Berkeley) 5/4/91";*/
+static char *rcsid = "$Id: fgetline.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+
+/*
+ * Expand the line buffer. Return -1 on error.
+ * The `new size' does not account for a terminating '\0',
+ * so we add 1 here.
+ */
+__slbexpand(fp, newsize)
+ FILE *fp;
+ size_t newsize;
+{
+ void *p;
+
+ if (fp->_lb._size >= ++newsize)
+ return (0);
+ if ((p = realloc(fp->_lb._base, newsize)) == NULL)
+ return (-1);
+ fp->_lb._base = p;
+ fp->_lb._size = newsize;
+ return (0);
+}
+
+/*
+ * Get an input line. The returned pointer often (but not always)
+ * points into a stdio buffer. Fgetline smashes the newline (if any)
+ * in the stdio buffer; callers must not use it on streams that
+ * have `magic' setvbuf() games happening.
+ */
+char *
+fgetline(fp, lenp)
+ register FILE *fp;
+ size_t *lenp;
+{
+ register unsigned char *p;
+ register size_t len;
+ size_t off;
+
+ flockfile(fp);
+
+ /* make sure there is input */
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (lenp != NULL)
+ *lenp = 0;
+ funlockfile(fp);
+ return (NULL);
+ }
+
+ /* look for a newline in the input */
+ if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
+ register char *ret;
+
+ /*
+ * Found one. Flag buffer as modified to keep
+ * fseek from `optimising' a backward seek, since
+ * the newline is about to be trashed. (We should
+ * be able to get away with doing this only if
+ * p is not pointing into an ungetc buffer, since
+ * fseek discards ungetc data, but this is the
+ * usual case anyway.)
+ */
+ ret = (char *)fp->_p;
+ len = p - fp->_p;
+ fp->_flags |= __SMOD;
+ *p = 0;
+ fp->_r -= len + 1;
+ fp->_p = p + 1;
+ if (lenp != NULL)
+ *lenp = len;
+ funlockfile(fp);
+ return (ret);
+ }
+
+ /*
+ * We have to copy the current buffered data to the line buffer.
+ *
+ * OPTIMISTIC is length that we (optimistically)
+ * expect will accomodate the `rest' of the string,
+ * on each trip through the loop below.
+ */
+#define OPTIMISTIC 80
+
+ for (len = fp->_r, off = 0;; len += fp->_r) {
+ register size_t diff;
+
+ /*
+ * Make sure there is room for more bytes.
+ * Copy data from file buffer to line buffer,
+ * refill file and look for newline. The
+ * loop stops only when we find a newline.
+ */
+ if (__slbexpand(fp, len + OPTIMISTIC))
+ goto error;
+ (void) bcopy((void *)fp->_p, (void *)(fp->_lb._base + off),
+ len - off);
+ off = len;
+ if (__srefill(fp))
+ break; /* EOF or error: return partial line */
+ if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
+ continue;
+
+ /* got it: finish up the line (like code above) */
+ fp->_flags |= __SMOD; /* soon */
+ diff = p - fp->_p;
+ len += diff;
+ if (__slbexpand(fp, len))
+ goto error;
+ (void) bcopy((void *)fp->_p, (void *)(fp->_lb._base + off), diff);
+ fp->_r -= diff + 1;
+ fp->_p = p + 1;
+ break;
+ }
+ if (lenp != NULL)
+ *lenp = len;
+ fp->_lb._base[len] = 0;
+
+ funlockfile(fp);
+ return ((char *)fp->_lb._base);
+
+error:
+ if (lenp != NULL)
+ *lenp = 0; /* ??? */
+ funlockfile(fp);
+ return (NULL); /* ??? */
+}
diff --git a/lib/libpthread/stdio/fgetpos.c b/lib/libpthread/stdio/fgetpos.c
new file mode 100644
index 00000000000..752db946cd8
--- /dev/null
+++ b/lib/libpthread/stdio/fgetpos.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fgetpos.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fgetpos.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/* Don't bother locking, ftell does it */
+fgetpos(fp, pos)
+ FILE *fp;
+ fpos_t *pos;
+{
+ return ((*pos = ftell(fp)) == (fpos_t)-1);
+}
diff --git a/lib/libpthread/stdio/fgets.c b/lib/libpthread/stdio/fgets.c
new file mode 100644
index 00000000000..7c00b6bdae8
--- /dev/null
+++ b/lib/libpthread/stdio/fgets.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fgets.c 5.4 (Berkeley) 5/4/91";*/
+static char *rcsid = "$Id: fgets.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * Read at most n-1 characters from the given file.
+ * Stop when a newline has been read, or the count runs out.
+ * Return first argument, or NULL if no characters were read.
+ */
+char *
+fgets(buf, n, fp)
+ char *buf;
+ register size_t n;
+ register FILE *fp;
+{
+ register size_t len;
+ register char *s;
+ register unsigned char *p, *t;
+
+ if (n < 2) /* sanity check */
+ return (NULL);
+
+ flockfile(fp);
+ s = buf;
+ n--; /* leave space for NUL */
+ do {
+ /*
+ * If the buffer is empty, refill it.
+ */
+ if ((len = fp->_r) <= 0) {
+ if (__srefill(fp)) {
+ /* EOF/error: stop with partial or no line */
+ if (s == buf)
+ buf = NULL;
+ break;
+ }
+ len = fp->_r;
+ }
+ p = fp->_p;
+
+ /*
+ * Scan through at most n bytes of the current buffer,
+ * looking for '\n'. If found, copy up to and including
+ * newline, and stop. Otherwise, copy entire chunk
+ * and loop.
+ */
+ if (len > n)
+ len = n;
+ t = memchr((void *)p, '\n', len);
+ if (t != NULL) {
+ len = ++t - p;
+ fp->_r -= len;
+ fp->_p = t;
+ (void) bcopy((void *)p, (void *)s, len);
+ s += len;
+ break;
+ }
+ fp->_r -= len;
+ fp->_p += len;
+ (void) bcopy((void *)p, (void *)s, len);
+ s += len;
+ } while ((n -= len) != 0);
+
+ *s = 0;
+ funlockfile(fp);
+ return (buf);
+}
diff --git a/lib/libpthread/stdio/fileno.c b/lib/libpthread/stdio/fileno.c
new file mode 100644
index 00000000000..e4f08c105d8
--- /dev/null
+++ b/lib/libpthread/stdio/fileno.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fileno.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fileno.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro fileno.
+ */
+#undef fileno
+
+fileno(fp)
+ FILE *fp;
+{
+ return (__sfileno(fp));
+}
diff --git a/lib/libpthread/stdio/findfp.c b/lib/libpthread/stdio/findfp.c
new file mode 100644
index 00000000000..dc1045bc3ff
--- /dev/null
+++ b/lib/libpthread/stdio/findfp.c
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)findfp.c 5.10 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: findfp.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <posix.h>
+#include "local.h"
+#include "glue.h"
+
+
+#define NSTATIC 20 /* stdin + stdout + stderr + the usual */
+#define NDYNAMIC 10 /* add ten more whenever necessary */
+
+#define std(flags, file) \
+ {0,0,0,flags,file,{0},0 }
+/* p r w flags file _bf z */
+
+static FILE usual[NSTATIC - 3]; /* the usual */
+static struct glue uglue = { 0, NSTATIC - 3, usual };
+
+FILE __sF[3] = {
+ std(__SRD, 0), /* stdin */
+ std(__SWR, 1), /* stdout */
+ std(__SWR|__SNBF, 2) /* stderr */
+};
+struct glue __sglue = { &uglue, 3, __sF };
+
+pthread_mutex_t __sfp_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t __sfp_cond = PTHREAD_COND_INITIALIZER;
+pthread_once_t __sdidinit = PTHREAD_ONCE_INIT;
+/*
+ * __sfp_state = 0, when free, > 0 when in _fwalk
+ * This allows multiple readers in _fwalk, but only one writer __sfp,
+ * or freopen() at a time.
+ */
+int __sfp_state = 0;
+
+static struct glue *moreglue(register int n)
+{
+ register struct glue *g;
+ register FILE *p;
+ static FILE empty;
+
+ g = (struct glue *)malloc(sizeof(*g) + n * sizeof(FILE));
+ if (g == NULL)
+ return (NULL);
+ p = (FILE *)(g + 1);
+ g->next = NULL;
+ g->niobs = n;
+ g->iobs = p;
+ while (--n >= 0)
+ *p++ = empty;
+ return (g);
+}
+
+/*
+ * Find a free FILE for fopen et al.
+ */
+FILE *__sfp()
+{
+ register FILE *fp;
+ register int n;
+ register struct glue *g;
+
+ for (g = &__sglue;; g = g->next) {
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
+ if (fp->_flags == 0) {
+ fp->_flags = 1; /* reserve this slot; caller sets real flags */
+ fp->_p = NULL; /* no current pointer */
+ fp->_w = 0; /* nothing to read or write */
+ fp->_r = 0;
+ fp->_bf._base = NULL; /* no buffer */
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0; /* not line buffered */
+ fp->_file = -1; /* no file */
+ fp->_ub._base = NULL; /* no ungetc buffer */
+ fp->_ub._size = 0;
+ fp->_lb._base = NULL; /* no line buffer */
+ fp->_lb._size = 0;
+ goto __sfp_done;
+ }
+ if (g->next == NULL && (g->next = moreglue(NDYNAMIC)) == NULL) {
+ fp = NULL;
+ break;
+ }
+ }
+__sfp_done:;
+ return (fp);
+}
+
+/*
+ * exit() calls _cleanup() through *__cleanup, set whenever we
+ * open or buffer a file. This chicanery is done so that programs
+ * that do not use stdio need not link it all in.
+ *
+ * The name `_cleanup' is, alas, fairly well known outside stdio.
+ */
+void _cleanup()
+{
+ (void) __swalk_sflush;
+}
+
+/*
+ * __sinit() is called whenever stdio's internal variables must be set up.
+ */
+void __sinit()
+{
+ /* make sure we clean up on exit */
+ __cleanup = _cleanup;
+ __sdidinit = 1;
+}
diff --git a/lib/libpthread/stdio/flags.c b/lib/libpthread/stdio/flags.c
new file mode 100644
index 00000000000..7a0bfa71ab9
--- /dev/null
+++ b/lib/libpthread/stdio/flags.c
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)flags.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: flags.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <errno.h>
+
+/*
+ * Return the (stdio) flags for a given mode. Store the flags
+ * to be passed to an open() syscall through *optr.
+ * Return 0 on error.
+ */
+__sflags(mode, optr)
+ register char *mode;
+ int *optr;
+{
+ register int ret, m, o;
+
+ switch (*mode++) {
+
+ case 'r': /* open for reading */
+ ret = __SRD;
+ m = O_RDONLY;
+ o = 0;
+ break;
+
+ case 'w': /* open for writing */
+ ret = __SWR;
+ m = O_WRONLY;
+ o = O_CREAT | O_TRUNC;
+ break;
+
+ case 'a': /* open for appending */
+ ret = __SWR;
+ m = O_WRONLY;
+ o = O_CREAT | O_APPEND;
+ break;
+
+ default: /* illegal mode */
+ errno = EINVAL;
+ return (0);
+ }
+
+ /* [rwa]\+ or [rwa]b\+ means read and write */
+ if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
+ ret = __SRW;
+ m = O_RDWR;
+ }
+ *optr = m | o;
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/floatio.h b/lib/libpthread/stdio/floatio.h
new file mode 100644
index 00000000000..a5bfd1f59e4
--- /dev/null
+++ b/lib/libpthread/stdio/floatio.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)floatio.h 5.1 (Berkeley) 1/20/91
+ * $Id: floatio.h,v 1.1 1995/10/18 08:43:06 deraadt Exp $
+ */
+
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
diff --git a/lib/libpthread/stdio/fopen.c b/lib/libpthread/stdio/fopen.c
new file mode 100644
index 00000000000..f12842e3bc5
--- /dev/null
+++ b/lib/libpthread/stdio/fopen.c
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fopen.c 5.5 (Berkeley) 2/5/91";*/
+static char *rcsid = "$Id: fopen.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+extern pthread_mutex_t __sfp_mutex;
+extern pthread_cond_t __sfp_cond;
+extern int __sfp_state;
+
+FILE *fopen(const char *file, const char *mode)
+{
+ register FILE *fp;
+ register int f;
+ int flags, oflags;
+
+ if ((flags = __sflags(mode, &oflags)) == 0)
+ return (NULL);
+ if ((f = open(file, oflags, 0666)) < 0) {
+ return (NULL);
+ }
+
+ pthread_once(&__sdidinit, __sinit);
+ pthread_mutex_lock(&__sfp_mutex);
+ while (__sfp_state) {
+ pthread_cond_wait(&__sfp_cond, &__sfp_mutex);
+ }
+
+ if (fp = __sfp()) {
+ fp->_file = f;
+ fp->_flags = flags;
+
+ /*
+ * When opening in append mode, even though we use O_APPEND,
+ * we need to seek to the end so that ftell() gets the right
+ * answer. If the user then alters the seek pointer, or
+ * the file extends, this will fail, but there is not much
+ * we can do about this. (We could set __SAPP and check in
+ * fseek and ftell.)
+ */
+ if (oflags & O_APPEND)
+ (void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
+ }
+ pthread_mutex_unlock(&__sfp_mutex);
+ return (fp);
+}
diff --git a/lib/libpthread/stdio/fprintf.c b/lib/libpthread/stdio/fprintf.c
new file mode 100644
index 00000000000..18f202e4a65
--- /dev/null
+++ b/lib/libpthread/stdio/fprintf.c
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fprintf.c 5.6 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fprintf.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+fprintf(FILE *fp, const char *fmt, ...)
+#else
+fprintf(fp, fmt, va_alist)
+ FILE *fp;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vfprintf(fp, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/fpurge.c b/lib/libpthread/stdio/fpurge.c
new file mode 100644
index 00000000000..65788204920
--- /dev/null
+++ b/lib/libpthread/stdio/fpurge.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fpurge.c 5.2 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: fpurge.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * fpurge: like fflush, but without writing anything: leave the
+ * given FILE's buffer empty.
+ */
+int
+fpurge(fp)
+ register FILE *fp;
+{
+ int ret;
+
+ flockfile(fp);
+ if (fp->_flags) {
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+ ret = 0;
+ } else {
+ errno = EBADF;
+ ret = EOF;
+ }
+ funlockfile(fp);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/fputc.c b/lib/libpthread/stdio/fputc.c
new file mode 100644
index 00000000000..b1febc14515
--- /dev/null
+++ b/lib/libpthread/stdio/fputc.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fputc.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fputc.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+fputc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ int ret;
+ flockfile(fp);
+ ret = __sputc(c, fp);
+ funlockfile(fp);
+ return(ret);
+}
diff --git a/lib/libpthread/stdio/fputs.c b/lib/libpthread/stdio/fputs.c
new file mode 100644
index 00000000000..320477ca416
--- /dev/null
+++ b/lib/libpthread/stdio/fputs.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fputs.c 5.6 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: fputs.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+
+/*
+ * Write the given string to the given file.
+ */
+fputs(s, fp)
+ const char *s;
+ FILE *fp;
+{
+ struct __suio uio;
+ struct __siov iov;
+ int ret;
+
+ iov.iov_base = (void *)s;
+ iov.iov_len = uio.uio_resid = strlen(s);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ flockfile(fp);
+ ret = __sfvwrite(fp, &uio);
+ funlockfile(fp);
+ return(ret);
+}
diff --git a/lib/libpthread/stdio/fread.c b/lib/libpthread/stdio/fread.c
new file mode 100644
index 00000000000..3df1689f2f0
--- /dev/null
+++ b/lib/libpthread/stdio/fread.c
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fread.c 5.4 (Berkeley) 5/4/91";*/
+static char *rcsid = "$Id: fread.c,v 1.1 1995/10/18 08:43:06 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+
+size_t
+fread(buf, size, count, fp)
+ void *buf;
+ size_t size, count;
+ register FILE *fp;
+{
+ register size_t resid;
+ register char *p;
+ register int r;
+ size_t total;
+
+ if ((resid = count * size) == 0)
+ return (count);
+
+ flockfile(fp);
+ if (fp->_r < 0)
+ fp->_r = 0;
+ total = resid;
+ p = buf;
+ while (resid > (r = fp->_r)) {
+ (void) bcopy((void *)fp->_p, (void *)p, (size_t)r);
+ fp->_p += r;
+ /* fp->_r = 0 ... done in __srefill */
+ p += r;
+ resid -= r;
+ if (__srefill(fp)) {
+ /* no more input: return partial result */
+ count = (total - resid) / size;
+ goto done_fread;
+ }
+ }
+ (void) bcopy((void *)fp->_p, (void *)p, resid);
+ fp->_r -= resid;
+ fp->_p += resid;
+done_fread:;
+ funlockfile(fp);
+ return (count);
+}
diff --git a/lib/libpthread/stdio/freopen.c b/lib/libpthread/stdio/freopen.c
new file mode 100644
index 00000000000..c7ab61c061a
--- /dev/null
+++ b/lib/libpthread/stdio/freopen.c
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)freopen.c 5.6 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: freopen.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+extern pthread_mutex_t __sfp_mutex;
+extern pthread_cond_t __sfp_cond;
+extern int __sfp_state;
+
+/*
+ * Re-direct an existing, open (probably) file to some other file.
+ * ANSI is written such that the original file gets closed if at
+ * all possible, no matter what.
+ */
+FILE *
+freopen(file, mode, fp)
+ const char *file, *mode;
+ register FILE *fp;
+{
+ int f, flags, oflags;
+ FILE *ret;
+
+ if ((flags = __sflags(mode, &oflags)) == 0) {
+ (void) fclose(fp);
+ return (NULL);
+ }
+
+ pthread_once(&__sdidinit, __sinit);
+
+ /*
+ * There are actually programs that depend on being able to "freopen"
+ * descriptors that weren't originally open. Keep this from breaking.
+ * Remember whether the stream was open to begin with, and which file
+ * descriptor (if any) was associated with it. If it was attached to
+ * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
+ * should work. This is unnecessary if it was not a Unix file.
+ */
+ /* while lock __sfp_mutex, to block out fopen, and other freopen calls */
+ while (pthread_mutex_lock(&__sfp_mutex) == OK) {
+ if (ftrylockfile(fp) == OK) {
+ if (fp->_flags) {
+ /* flush the stream; ANSI doesn't require this. */
+ if (fp->_flags & __SWR)
+ (void) __sflush(fp);
+ __sclose(fp);
+ /*
+ * Finish closing fp. We cannot keep fp->_base:
+ * it may be the wrong size. This loses the effect
+ * of any setbuffer calls, but stdio has always done
+ * this before.
+ * NOTE: We do this even if __ftrylockfilr failed with
+ * an error to avoid memory leaks.
+ */
+ if (fp->_flags & __SMBF)
+ free((char *)fp->_bf._base);
+ fp->_w = 0;
+ fp->_r = 0;
+ fp->_p = NULL;
+ fp->_bf._base = NULL;
+ fp->_bf._size = 0;
+ fp->_lbfsize = 0;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_ub._size = 0;
+ if (HASLB(fp))
+ FREELB(fp);
+ fp->_lb._size = 0;
+ }
+ /* Get a new descriptor to refer to the new file. */
+ if ((f = open(file, oflags, 0666)) < OK)
+ ret = NULL;
+ /*
+ * If reopening something that was open before on a real file, try
+ * to maintain the descriptor. Various C library routines (perror)
+ * assume stderr is always fd STDERR_FILENO, even if being freopen'd.
+ */
+ /* Testing f == fp->_file may no longer be necessary */
+ if (fp->_file >= 0 && f != fp->_file) {
+ if (dup2(f, fp->_file) >= OK) {
+ (void)close(f);
+ f = fp->_file;
+ }
+ }
+ fp->_flags = flags;
+ fp->_file = f;
+ ret = fp;
+ break;
+ } else {
+ /* unlock __sfp_mutex, and try again later */
+ pthread_mutex_unlock(&__sfp_mutex);
+ pthread_yield();
+ continue;
+ }
+ pthread_mutex_unlock(&__sfp_mutex);
+ funlockfile(fp);
+ return(ret);
+ }
+ (void)fclose(fp);
+ return(NULL);
+}
diff --git a/lib/libpthread/stdio/fscanf.c b/lib/libpthread/stdio/fscanf.c
new file mode 100644
index 00000000000..54960c9c727
--- /dev/null
+++ b/lib/libpthread/stdio/fscanf.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fscanf.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: fscanf.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+fscanf(FILE *fp, char const *fmt, ...) {
+ int r;
+ va_list ap;
+
+ va_start(ap, fmt);
+#else
+fscanf(fp, fmt, va_alist)
+ FILE *fp;
+ char *fmt;
+ va_dcl
+{
+ int r;
+ va_list ap;
+
+ va_start(ap);
+#endif
+ flockfile(fp);
+ r = __svfscanf(fp, fmt, ap);
+ funlockfile(fp);
+ va_end(ap);
+ return(r);
+}
diff --git a/lib/libpthread/stdio/fseek.c b/lib/libpthread/stdio/fseek.c
new file mode 100644
index 00000000000..173d427ff43
--- /dev/null
+++ b/lib/libpthread/stdio/fseek.c
@@ -0,0 +1,246 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fseek.c 5.7 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: fseek.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "local.h"
+
+#define POS_ERR (-(fpos_t)1)
+
+/*
+ * Seek the given file to the given offset.
+ * `Whence' must be one of the three SEEK_* macros.
+ */
+fseek(fp, offset, whence)
+ register FILE *fp;
+ long offset;
+ int whence;
+{
+#if __STDC__
+ register fpos_t (*seekfn)(void *, fpos_t, int);
+#else
+ register fpos_t (*seekfn)();
+#endif
+ fpos_t target, curoff;
+ size_t n;
+ struct stat st;
+ int havepos;
+
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+ flockfile(fp);
+
+ /*
+ * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
+ * After this, whence is either SEEK_SET or SEEK_END.
+ */
+ switch (whence) {
+ case SEEK_CUR:
+ /*
+ * In order to seek relative to the current stream offset,
+ * we have to first find the current stream offset a la
+ * ftell (see ftell for details).
+ */
+ if (fp->_flags & __SOFF)
+ curoff = fp->_offset;
+ else {
+ curoff = __sseek(fp, (fpos_t)0, SEEK_CUR);
+ if (curoff == -1L)
+ funlockfile(fp);
+ return (EOF);
+ }
+ if (fp->_flags & __SRD) {
+ curoff -= fp->_r;
+ if (HASUB(fp))
+ curoff -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL)
+ curoff += fp->_p - fp->_bf._base;
+
+ offset += curoff;
+ whence = SEEK_SET;
+ havepos = 1;
+ break;
+
+ case SEEK_SET:
+ case SEEK_END:
+ curoff = 0; /* XXX just to keep gcc quiet */
+ havepos = 0;
+ break;
+
+ default:
+ errno = EINVAL;
+ funlockfile(fp);
+ return (EOF);
+ }
+
+ /*
+ * Can only optimise if:
+ * reading (and not reading-and-writing);
+ * not unbuffered; and
+ * this is a `regular' Unix file (and hence seekfn==__sseek).
+ * We must check __NBF first, because it is possible to have __NBF
+ * and __SOPT both set.
+ */
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+ if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
+ goto dumb;
+ if ((fp->_flags & __SOPT) == 0) {
+ if (fp->_file < 0 || fstat(fp->_file, &st) ||
+ (st.st_mode & S_IFMT) != S_IFREG) {
+ fp->_flags |= __SNPT;
+ goto dumb;
+ }
+ fp->_blksize = st.st_blksize;
+ fp->_flags |= __SOPT;
+ }
+
+ /*
+ * We are reading; we can try to optimise.
+ * Figure out where we are going and where we are now.
+ */
+ if (whence == SEEK_SET)
+ target = offset;
+ else {
+ if (fstat(fp->_file, &st))
+ goto dumb;
+ target = st.st_size + offset;
+ }
+
+ if (!havepos) {
+ if (fp->_flags & __SOFF)
+ curoff = fp->_offset;
+ else {
+ curoff = __sseek(fp, 0L, SEEK_CUR);
+ if (curoff == POS_ERR)
+ goto dumb;
+ }
+ curoff -= fp->_r;
+ if (HASUB(fp))
+ curoff -= fp->_ur;
+ }
+
+ /*
+ * Compute the number of bytes in the input buffer (pretending
+ * that any ungetc() input has been discarded). Adjust current
+ * offset backwards by this count so that it represents the
+ * file offset for the first byte in the current input buffer.
+ */
+ if (HASUB(fp)) {
+ n = fp->_up - fp->_bf._base;
+ curoff -= n;
+ n += fp->_ur;
+ } else {
+ n = fp->_p - fp->_bf._base;
+ curoff -= n;
+ n += fp->_r;
+ }
+
+ /*
+ * If the target offset is within the current buffer,
+ * simply adjust the pointers, clear EOF, undo ungetc(),
+ * and return. (If the buffer was modified, we have to
+ * skip this; see fgetline.c.)
+ */
+ if ((fp->_flags & __SMOD) == 0 &&
+ target >= curoff && target < curoff + n) {
+ register int o = target - curoff;
+
+ fp->_p = fp->_bf._base + o;
+ fp->_r = n - o;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~__SEOF;
+ funlockfile(fp);
+ return (0);
+ }
+
+ /*
+ * The place we want to get to is not within the current buffer,
+ * but we can still be kind to the kernel copyout mechanism.
+ * By aligning the file offset to a block boundary, we can let
+ * the kernel use the VM hardware to map pages instead of
+ * copying bytes laboriously. Using a block boundary also
+ * ensures that we only read one block, rather than two.
+ */
+ curoff = target & ~(fp->_blksize - 1);
+ if (__sseek(fp, 0L, SEEK_CUR) != POS_ERR) {
+ fp->_r = 0;
+ fp->_p = fp->_bf._base;
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~__SEOF;
+ n = target - curoff;
+ if (n) {
+ if (__srefill(fp) || fp->_r < n)
+ goto dumb;
+ fp->_p += n;
+ fp->_r -= n;
+ }
+ funlockfile(fp);
+ return (0);
+ }
+
+ /*
+ * We get here if we cannot optimise the seek ... just
+ * do it. Allow the seek function to change fp->_bf._base.
+ */
+dumb:
+ if (__sflush(fp) || __sseek(fp, offset, whence) == POS_ERR) {
+ funlockfile(fp);
+ return (EOF);
+ }
+ /* success: clear EOF indicator and discard ungetc() data */
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ /* fp->_w = 0; */ /* unnecessary (I think...) */
+ fp->_flags &= ~__SEOF;
+ funlockfile(fp);
+ return (0);
+}
diff --git a/lib/libpthread/stdio/fsetpos.c b/lib/libpthread/stdio/fsetpos.c
new file mode 100644
index 00000000000..69c9ddd0fcb
--- /dev/null
+++ b/lib/libpthread/stdio/fsetpos.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fsetpos.c 5.2 (Berkeley) 2/5/91";*/
+static char *rcsid = "$Id: fsetpos.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * fsetpos: like fseek.
+ * Don't bother locking, fseek does it.
+ */
+fsetpos(iop, pos)
+ FILE *iop;
+ const fpos_t *pos;
+{
+ return (fseek(iop, (long)*pos, SEEK_SET));
+}
diff --git a/lib/libpthread/stdio/ftell.c b/lib/libpthread/stdio/ftell.c
new file mode 100644
index 00000000000..2d5e5fa6eb1
--- /dev/null
+++ b/lib/libpthread/stdio/ftell.c
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)ftell.c 5.4 (Berkeley) 2/5/91";*/
+static char *rcsid = "$Id: ftell.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+/*
+ * ftell: return current offset.
+ */
+long
+ftell(fp)
+ register const FILE *fp;
+{
+ register fpos_t pos;
+
+ flockfile(fp);
+
+ /*
+ * Find offset of underlying I/O object, then
+ * adjust for buffered bytes.
+ */
+ if (fp->_flags & __SOFF)
+ pos = fp->_offset;
+ else {
+ pos = lseek(fp, (fpos_t)0, SEEK_CUR);
+ }
+
+ if (pos != -1L) {
+ if (fp->_flags & __SRD) {
+ /*
+ * Reading. Any unread characters (including
+ * those from ungetc) cause the position to be
+ * smaller than that in the underlying object.
+ */
+ pos -= fp->_r;
+ if (HASUB(fp))
+ pos -= fp->_ur;
+ } else if (fp->_flags & __SWR && fp->_p != NULL) {
+ /*
+ * Writing. Any buffered characters cause the
+ * position to be greater than that in the
+ * underlying object.
+ */
+ pos += fp->_p - fp->_bf._base;
+ }
+ }
+ funlockfile(fp);
+ return (pos);
+}
diff --git a/lib/libpthread/stdio/funopen.c b/lib/libpthread/stdio/funopen.c
new file mode 100644
index 00000000000..fd1689ada9e
--- /dev/null
+++ b/lib/libpthread/stdio/funopen.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)funopen.c 5.2 (Berkeley) 2/5/91";*/
+static char *rcsid = "$Id: funopen.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+FILE *
+funopen(cookie, readfn, writefn, seekfn, closefn)
+ const void *cookie;
+ int (*readfn)(), (*writefn)();
+#if __STDC__
+ fpos_t (*seekfn)(void *cookie, fpos_t off, int whence);
+#else
+ fpos_t (*seekfn)();
+#endif
+ int (*closefn)();
+{
+ struct fd_ops *fd_ops;
+ char *flags;
+ FILE *fp;
+ int fd;
+
+ if (readfn == NULL) {
+ if (writefn == NULL) { /* illegal */
+ errno = EINVAL;
+ return (NULL);
+ } else
+ flags = "w"; /* write only */
+ } else {
+ if (writefn == NULL)
+ flags = "r"; /* read only */
+ else
+ flags = "r+"; /* read-write */
+ }
+
+ if (fd_ops = (struct fd_ops*)malloc(sizeof(struct fd_ops))) {
+ if ((!(fd = fd_allocate())) < OK) {
+
+ /* Set functions */
+ fd_ops->seek = seekfn;
+ fd_ops->read = readfn;
+ fd_ops->write = writefn;
+ fd_ops->close = closefn;
+
+ /* Alloc space for funtion pointer table */
+ fd_table[fd]->type = FD_HALF_DUPLEX;
+ fd_table[fd]->ops = fd_ops;
+
+ /* Save the cookie, it's important */
+ fd_table[fd]->fd.ptr = cookie;
+
+ if (fp = fdopen(fd, flags))
+ return(fp);
+
+ fd_free(fd);
+ }
+ free(fd_ops);
+ }
+ return(NULL);
+}
diff --git a/lib/libpthread/stdio/fvwrite.c b/lib/libpthread/stdio/fvwrite.c
new file mode 100644
index 00000000000..c4646099fde
--- /dev/null
+++ b/lib/libpthread/stdio/fvwrite.c
@@ -0,0 +1,188 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fvwrite.c 5.3 (Berkeley) 5/4/91";*/
+static char *rcsid = "$Id: fvwrite.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <string.h>
+#include <stdio.h>
+#include "local.h"
+#include "fvwrite.h"
+
+/*
+ * Write some memory regions. Return zero on success, EOF on error.
+ *
+ * This routine is large and unsightly, but most of the ugliness due
+ * to the three different kinds of output buffering is handled here.
+ */
+__sfvwrite(fp, uio)
+ register FILE *fp;
+ register struct __suio *uio;
+{
+ register size_t len;
+ register char *p;
+ register struct __siov *iov;
+ register int w, s;
+ char *nl;
+ int nlknown, nldist;
+
+ if ((len = uio->uio_resid) == 0)
+ return (0);
+ /* make sure we can write */
+ if (cantwrite(fp))
+ return (EOF);
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define COPY(n) (void) bcopy((void *)p, (void *)fp->_p, (size_t)(n));
+
+ iov = uio->uio_iov;
+ p = iov->iov_base;
+ len = iov->iov_len;
+ iov++;
+#define GETIOV(extra_work) \
+ while (len == 0) { \
+ extra_work; \
+ p = iov->iov_base; \
+ len = iov->iov_len; \
+ iov++; \
+ }
+ if (fp->_flags & __SNBF) {
+ /*
+ * Unbuffered: write up to BUFSIZ bytes at a time.
+ */
+ do {
+ GETIOV(;);
+ w = __swrite(fp, p, MIN(len, BUFSIZ));
+ if (w <= 0)
+ goto err;
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ } else if ((fp->_flags & __SLBF) == 0) {
+ /*
+ * Fully buffered: fill partially full buffer, if any,
+ * and then flush. If there is no partial buffer, write
+ * one _bf._size byte chunk directly (without copying).
+ *
+ * String output is a special case: write as many bytes
+ * as fit, but pretend we wrote everything. This makes
+ * snprintf() return the number of bytes needed, rather
+ * than the number used, and avoids its write function
+ * (so that the write function can be invalid).
+ */
+ do {
+ GETIOV(;);
+ w = fp->_w;
+ if (fp->_flags & __SSTR) {
+ if (len < w)
+ w = len;
+ COPY(w); /* copy MIN(fp->_w,len), */
+ fp->_w -= w;
+ fp->_p += w;
+ w = len; /* but pretend copied all */
+ } else if (fp->_p > fp->_bf._base && len > w) {
+ /* fill and flush */
+ COPY(w);
+ /* fp->_w -= w; */ /* unneeded */
+ fp->_p += w;
+ if (fflush(fp))
+ goto err;
+ } else if (len >= (w = fp->_bf._size)) {
+ if ((w = __swrite(fp, p, w)) <= 0)
+ goto err;
+ } else {
+ /* fill and done */
+ w = len;
+ COPY(w);
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ } else {
+ /*
+ * Line buffered: like fully buffered, but we
+ * must check for newlines. Compute the distance
+ * to the first newline (including the newline),
+ * or `infinity' if there is none, then pretend
+ * that the amount to write is MIN(len,nldist).
+ */
+ nlknown = 0;
+ nldist = 0; /* XXX just to keep gcc happy */
+ do {
+ GETIOV(nlknown = 0);
+ if (!nlknown) {
+ nl = memchr((void *)p, '\n', len);
+ nldist = nl ? nl + 1 - p : len + 1;
+ nlknown = 1;
+ }
+ s = MIN(len, nldist);
+ w = fp->_w + fp->_bf._size;
+ if (fp->_p > fp->_bf._base && s > w) {
+ COPY(w);
+ /* fp->_w -= w; */
+ fp->_p += w;
+ if (fflush(fp))
+ goto err;
+ } else if (s >= (w = fp->_bf._size)) {
+ if ((w = __swrite(fp, p, w)) <= 0)
+ goto err;
+ } else {
+ w = s;
+ COPY(w);
+ fp->_w -= w;
+ fp->_p += w;
+ }
+ if ((nldist -= w) == 0) {
+ /* copied the newline: flush and forget */
+ if (fflush(fp))
+ goto err;
+ nlknown = 0;
+ }
+ p += w;
+ len -= w;
+ } while ((uio->uio_resid -= w) != 0);
+ }
+ return (0);
+
+err:
+ fp->_flags |= __SERR;
+ return (EOF);
+}
diff --git a/lib/libpthread/stdio/fvwrite.h b/lib/libpthread/stdio/fvwrite.h
new file mode 100644
index 00000000000..8977a2bf49e
--- /dev/null
+++ b/lib/libpthread/stdio/fvwrite.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)fvwrite.h 5.1 (Berkeley) 1/20/91
+ * $Id: fvwrite.h,v 1.1 1995/10/18 08:43:07 deraadt Exp $
+ */
+
+/*
+ * I/O descriptors for __sfvwrite().
+ */
+struct __siov {
+ void *iov_base;
+ size_t iov_len;
+};
+
+struct __suio {
+ struct __siov *uio_iov;
+ int uio_iovcnt;
+ int uio_resid;
+};
+
+extern int __sfvwrite __P(( FILE *, struct __suio *));
diff --git a/lib/libpthread/stdio/fwalk.c b/lib/libpthread/stdio/fwalk.c
new file mode 100644
index 00000000000..b4a81f083ba
--- /dev/null
+++ b/lib/libpthread/stdio/fwalk.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fwalk.c 5.2 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: fwalk.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include "local.h"
+#include "glue.h"
+
+extern pthread_mutex_t __sfp_mutex;
+extern pthread_cond_t __sfp_cond;
+extern int __sfp_state;
+
+/*
+ * fwalk now can only be used for flushing the buffers.
+ * This is all it was originally used for.
+ * The function has also become much more complicated.
+ * The first time through we flush everything we can.
+ * If this fails to flush everything because we couldn't get a lock
+ * we wait on the locksfor the second pass. Why this works ...
+ *
+ * This function must allow for multiple threads to flush everything.
+ * This function cannot flush buffers locked by another thread.
+ * So we flush everything we can the first pass. This includes all
+ * buffers locked by this thread, and wait on buffers that are locked.
+ * Eventually other threads willl unlock there buffers or flush them themselves
+ * at which point this thread will notice that it's empty or be able to
+ * flush the buffer. This is fine so long as no other thread tries to flush
+ * all buffers. Here is the possible deadlock condition, but since this thread
+ * has flushed all buffers it can, there are NO buffers locked by this thread
+ * that need flushing so any other thread flushing won't block waiting on this
+ * thread thereby eliminating the deadlock condition.
+ */
+
+int __swalk_sflush()
+{
+ register FILE *fp, *savefp;
+ register int n, ret, saven;
+ register struct glue *g, *saveg;
+
+ /* Only allow other threads to read __sglue */
+ pthread_mutex_lock(&__sfp_mutex);
+ __sfp_state++;
+ pthread_mutex_unlock(&__sfp_mutex);
+
+ ret = 0;
+ saven = 0;
+ saveg = NULL;
+ savefp = NULL;
+ for (g = &__sglue; g != NULL; g = g->next) {
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
+ if (fp->_flags != 0) {
+ /* Is there anything to flush? */
+ if (fp->_bf._base && (fp->_bf._base - fp->_p)) {
+ if (ftrylockfile(fp)) { /* Can we flush it */
+ if (!saven) { /* No, save first fp we can't flush */
+ saven;
+ saveg = g;
+ savefp = fp;
+ continue;
+ }
+ ret |= __sflush(fp);
+ }
+ }
+ }
+ }
+ }
+ if (savefp) {
+ for (g = saveg; g != NULL; g = g->next) {
+ for (fp = savefp, n = saven + 1; --n >= 0; fp++) {
+ if (fp->_flags != 0) {
+ /* Anything to flush */
+ while (fp->_bf._base && (fp->_bf._base - fp->_p)) {
+ if (ftrylockfile(fp)) { /* Can we flush it */
+ pthread_yield();
+ continue;
+ }
+ ret |= __sflush(fp);
+ }
+ }
+ }
+ }
+ }
+
+ /* If no other readers wakeup a thread waiting to do __sfp */
+ pthread_mutex_lock(&__sfp_mutex);
+ if (! (--__sfp_state)) {
+ pthread_cond_signal(&__sfp_cond);
+ }
+ pthread_mutex_unlock(&__sfp_mutex);
+ return (ret);
+}
+
diff --git a/lib/libpthread/stdio/fwrite.c b/lib/libpthread/stdio/fwrite.c
new file mode 100644
index 00000000000..35576013f62
--- /dev/null
+++ b/lib/libpthread/stdio/fwrite.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)fwrite.c 5.5 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: fwrite.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include "local.h"
+#include "fvwrite.h"
+
+/*
+ * Write `count' objects (each size `size') from memory to the given file.
+ * Return the number of whole objects written.
+ */
+size_t
+fwrite(buf, size, count, fp)
+ const void *buf;
+ size_t size, count;
+ FILE *fp;
+{
+ struct __suio uio;
+ struct __siov iov;
+ size_t n;
+
+ iov.iov_base = (void *)buf;
+ uio.uio_resid = iov.iov_len = n = count * size;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+
+ flockfile(fp);
+
+ /*
+ * The usual case is success (__sfvwrite returns 0);
+ * skip the divide if this happens, since divides are
+ * generally slow and since this occurs whenever size==0.
+ */
+ if (__sfvwrite(fp, &uio) == 0)
+ count = (n - uio.uio_resid) / size;
+ funlockfile(fp);
+ return(count);
+}
diff --git a/lib/libpthread/stdio/getc.c b/lib/libpthread/stdio/getc.c
new file mode 100644
index 00000000000..2b487ce63c7
--- /dev/null
+++ b/lib/libpthread/stdio/getc.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: getc.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro getc.
+ */
+#undef getc
+
+getc(fp)
+ register FILE *fp;
+{
+ int ret;
+ flockfile(fp);
+ ret = __sgetc(fp);
+ funlockfile(fp);
+ return(ret);
+}
diff --git a/lib/libpthread/stdio/getc_unlocked.c b/lib/libpthread/stdio/getc_unlocked.c
new file mode 100644
index 00000000000..c60046cf34c
--- /dev/null
+++ b/lib/libpthread/stdio/getc_unlocked.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getc.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: getc_unlocked.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro getc.
+ */
+#undef getc_unlocked
+
+getc_unlocked(fp)
+ register FILE *fp;
+{
+ return (__sgetc(fp));
+}
diff --git a/lib/libpthread/stdio/getchar.c b/lib/libpthread/stdio/getchar.c
new file mode 100644
index 00000000000..1e2d6ac92a9
--- /dev/null
+++ b/lib/libpthread/stdio/getchar.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: getchar.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * A subroutine version of the macro getchar.
+ */
+#include <pthread.h>
+#include <stdio.h>
+
+#undef getchar
+
+getchar()
+{
+ int ret;
+ flockfile(stdin);
+ ret = getc(stdin);
+ funlockfile(stdin);
+ return(ret);
+}
diff --git a/lib/libpthread/stdio/getchar_unlocked.c b/lib/libpthread/stdio/getchar_unlocked.c
new file mode 100644
index 00000000000..f2eefcb29e3
--- /dev/null
+++ b/lib/libpthread/stdio/getchar_unlocked.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getchar.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: getchar_unlocked.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * A subroutine version of the macro getchar.
+ */
+#include <pthread.h>
+#include <stdio.h>
+
+#undef getchar_unlocked
+
+getchar_unlocked()
+{
+ return (getc(stdin));
+}
diff --git a/lib/libpthread/stdio/gets.c b/lib/libpthread/stdio/gets.c
new file mode 100644
index 00000000000..9cc4916e7a1
--- /dev/null
+++ b/lib/libpthread/stdio/gets.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)gets.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: gets.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+
+char *
+gets(buf)
+ char *buf;
+{
+ register int c;
+ register char *s;
+ static int warned;
+ static char w[] =
+ "warning: this program uses gets(), which is unsafe.\r\n";
+
+ if (!warned) {
+ (void) write(STDERR_FILENO, w, sizeof(w) - 1);
+ warned = 1;
+ }
+ for (s = buf; (c = getchar()) != '\n';)
+ if (c == EOF)
+ if (s == buf)
+ return (NULL);
+ else
+ break;
+ else
+ *s++ = c;
+ *s = 0;
+ return (buf);
+}
diff --git a/lib/libpthread/stdio/getw.c b/lib/libpthread/stdio/getw.c
new file mode 100644
index 00000000000..ef6472a0940
--- /dev/null
+++ b/lib/libpthread/stdio/getw.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getw.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: getw.c,v 1.1 1995/10/18 08:43:07 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+getw(fp)
+ FILE *fp;
+{
+ int x;
+
+ return (fread((void *)&x, sizeof(x), 1, fp) == 1 ? x : EOF);
+}
diff --git a/lib/libpthread/stdio/glue.h b/lib/libpthread/stdio/glue.h
new file mode 100644
index 00000000000..3467dd66b2f
--- /dev/null
+++ b/lib/libpthread/stdio/glue.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)glue.h 5.1 (Berkeley) 1/20/91
+ * $Id: glue.h,v 1.1 1995/10/18 08:43:07 deraadt Exp $
+ */
+
+/*
+ * The first few FILEs are statically allocated; others are dynamically
+ * allocated and linked in via this glue structure.
+ */
+struct glue {
+ struct glue *next;
+ int niobs;
+ FILE *iobs;
+} __sglue;
diff --git a/lib/libpthread/stdio/local.h b/lib/libpthread/stdio/local.h
new file mode 100644
index 00000000000..248bb3d5e31
--- /dev/null
+++ b/lib/libpthread/stdio/local.h
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)local.h 5.3 (Berkeley) 5/6/93
+ * $Id: local.h,v 1.1 1995/10/18 08:43:07 deraadt Exp $
+ */
+
+/*
+ * Information local to this implementation of stdio,
+ * in particular, macros and private variables.
+ */
+
+FILE *__sfp __P((void));
+int __sflush __P((FILE *));
+int __srefill __P((FILE *));
+int __swrite __P((FILE *, const char *, int));
+int __sread __P((FILE *, char *, int));
+fpos_t __sseek __P((FILE *, fpos_t, int));
+int __sclose __P((FILE *));
+void __sinit __P((void));
+void _cleanup __P((void));
+void (*__cleanup) __P((void));
+void __smakebuf __P((FILE *));
+int __swhatbuf __P((FILE *, size_t *, int *));
+int __swalk_sflush __P(());
+int __swsetup __P((FILE *));
+int __sflags __P((const char *, int *));
+
+extern int __sdidinit;
+
+/*
+ * Return true iff the given FILE cannot be written now.
+ */
+#define cantwrite(fp) \
+ ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
+ __swsetup(fp))
+
+/*
+ * Test whether the given stdio file has an active ungetc buffer;
+ * release such a buffer, without restoring ordinary unread data.
+ */
+#define HASUB(fp) ((fp)->_ub._base != NULL)
+#define FREEUB(fp) { \
+ if ((fp)->_ub._base != (fp)->_ubuf) \
+ free((char *)(fp)->_ub._base); \
+ (fp)->_ub._base = NULL; \
+}
+
+/*
+ * test for an fgetline() buffer.
+ */
+#define HASLB(fp) ((fp)->_lb._base != NULL)
+#define FREELB(fp) { \
+ free((char *)(fp)->_lb._base); \
+ (fp)->_lb._base = NULL; \
+}
diff --git a/lib/libpthread/stdio/makebuf.c b/lib/libpthread/stdio/makebuf.c
new file mode 100644
index 00000000000..e7b615437d8
--- /dev/null
+++ b/lib/libpthread/stdio/makebuf.c
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)makebuf.c 5.3 (Berkeley) 5/6/93";*/
+static char *rcsid = "$Id: makebuf.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * Allocate a file buffer, or switch to unbuffered I/O.
+ * Per the ANSI C standard, ALL tty devices default to line buffered.
+ *
+ * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
+ * optimisation) right after the fstat() that finds the buffer size.
+ */
+void
+__smakebuf(fp)
+ register FILE *fp;
+{
+ register void *p;
+ register int flags;
+ size_t size;
+ int couldbetty;
+
+ if (fp->_flags & __SNBF) {
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ return;
+ }
+ flags = __swhatbuf(fp, &size, &couldbetty);
+ if ((p = malloc(size)) == NULL) {
+ fp->_flags |= __SNBF;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ return;
+ }
+ __cleanup = _cleanup;
+ flags |= __SMBF;
+ fp->_bf._base = fp->_p = p;
+ fp->_bf._size = size;
+ if (couldbetty && isatty(fp->_file))
+ flags |= __SLBF;
+ fp->_flags |= flags;
+}
+
+/*
+ * Internal routine to determine `proper' buffering for a file.
+ */
+int
+__swhatbuf(fp, bufsize, couldbetty)
+ register FILE *fp;
+ size_t *bufsize;
+ int *couldbetty;
+{
+ struct stat st;
+
+ if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
+ *couldbetty = 0;
+ *bufsize = BUFSIZ;
+ return (__SNPT);
+ }
+
+ /* could be a tty iff it is a character device */
+ *couldbetty = (st.st_mode & S_IFMT) == S_IFCHR;
+ if (st.st_blksize <= 0) {
+ *bufsize = BUFSIZ;
+ return (__SNPT);
+ }
+
+ /*
+ * Optimise fseek() only if it is a regular file. (The test for
+ * __sseek is mainly paranoia.) It is safe to set _blksize
+ * unconditionally; it will only be used if __SOPT is also set.
+ */
+ *bufsize = st.st_blksize;
+ fp->_blksize = st.st_blksize;
+ return ((st.st_mode & S_IFMT) == S_IFREG ? __SOPT : __SNPT);
+}
diff --git a/lib/libpthread/stdio/mktemp.c b/lib/libpthread/stdio/mktemp.c
new file mode 100644
index 00000000000..4f41c63ff48
--- /dev/null
+++ b/lib/libpthread/stdio/mktemp.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)mktemp.c 5.10 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: mktemp.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+
+static int _gettemp();
+
+mkstemp(path)
+ char *path;
+{
+ int fd;
+
+ return (_gettemp(path, &fd) ? fd : -1);
+}
+
+char *
+mktemp(path)
+ char *path;
+{
+ return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
+}
+
+static
+_gettemp(path, doopen)
+ char *path;
+ register int *doopen;
+{
+ extern int errno;
+ register char *start, *trv;
+ struct stat sbuf;
+ u_int pid;
+
+ pid = getpid();
+ for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
+ while (*--trv == 'X') {
+ *trv = (pid % 10) + '0';
+ pid /= 10;
+ }
+
+ /*
+ * check the target directory; if you have six X's and it
+ * doesn't exist this runs for a *very* long time.
+ */
+ for (start = trv + 1;; --trv) {
+ if (trv <= path)
+ break;
+ if (*trv == '/') {
+ *trv = '\0';
+ if (stat(path, &sbuf))
+ return(0);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return(0);
+ }
+ *trv = '/';
+ break;
+ }
+ }
+
+ for (;;) {
+ if (doopen) {
+ if ((*doopen =
+ open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
+ return(1);
+ if (errno != EEXIST)
+ return(0);
+ }
+ else if (stat(path, &sbuf))
+ return(errno == ENOENT ? 1 : 0);
+
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (!*trv)
+ return(0);
+ if (*trv == 'z')
+ *trv++ = 'a';
+ else {
+ if (isdigit(*trv))
+ *trv = 'a';
+ else
+ ++*trv;
+ break;
+ }
+ }
+ }
+ /*NOTREACHED*/
+}
diff --git a/lib/libpthread/stdio/perror.c b/lib/libpthread/stdio/perror.c
new file mode 100644
index 00000000000..c4cb0154da2
--- /dev/null
+++ b/lib/libpthread/stdio/perror.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)perror.c 5.11 (Berkeley) 2/24/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+void
+perror(s)
+ const char *s;
+{
+ register struct iovec *v;
+ struct iovec iov[4];
+
+ v = iov;
+ if (s && *s) {
+ v->iov_base = (char *)s;
+ v->iov_len = strlen(s);
+ v++;
+ v->iov_base = ": ";
+ v->iov_len = 2;
+ v++;
+ }
+ v->iov_base = strerror(errno);
+ v->iov_len = strlen(v->iov_base);
+ v++;
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ (void)writev(STDERR_FILENO, iov, (v - iov) + 1);
+}
diff --git a/lib/libpthread/stdio/printf.c b/lib/libpthread/stdio/printf.c
new file mode 100644
index 00000000000..4b546565d08
--- /dev/null
+++ b/lib/libpthread/stdio/printf.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)printf.c 5.6 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: printf.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+printf(char const *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/putc.c b/lib/libpthread/stdio/putc.c
new file mode 100644
index 00000000000..f98ace370ad
--- /dev/null
+++ b/lib/libpthread/stdio/putc.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: putc.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro putc.
+ */
+#undef putc
+
+putc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ int ret;
+ flockfile(fp);
+ ret = __sputc(c, fp);
+ funlockfile(fp);
+ return(ret);
+}
diff --git a/lib/libpthread/stdio/putc_unlocked.c b/lib/libpthread/stdio/putc_unlocked.c
new file mode 100644
index 00000000000..3f3a6a9a14c
--- /dev/null
+++ b/lib/libpthread/stdio/putc_unlocked.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)putc.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: putc_unlocked.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro putc.
+ */
+#undef putc_unlocked
+
+putc_unlocked(c, fp)
+ int c;
+ register FILE *fp;
+{
+ return (__sputc(c, fp));
+}
diff --git a/lib/libpthread/stdio/putchar.c b/lib/libpthread/stdio/putchar.c
new file mode 100644
index 00000000000..d02c06beb33
--- /dev/null
+++ b/lib/libpthread/stdio/putchar.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: putchar.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+#undef putchar
+
+/*
+ * A subroutine version of the macro putchar
+ */
+putchar(c)
+ int c;
+{
+ register FILE *so = stdout;
+ int ret;
+
+ flockfile(so);
+ ret = __sputc(c, so);
+ funlockfile(so);
+ return(ret);
+}
diff --git a/lib/libpthread/stdio/putchar_unlocked.c b/lib/libpthread/stdio/putchar_unlocked.c
new file mode 100644
index 00000000000..c79dc7ed489
--- /dev/null
+++ b/lib/libpthread/stdio/putchar_unlocked.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)putchar.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: putchar_unlocked.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+
+#undef putchar_unlocked
+/*
+ * A subroutine version of the macro putchar
+ */
+putchar_unlocked(c)
+ int c;
+{
+ register FILE *so = stdout;
+
+ return (__sputc(c, so));
+}
diff --git a/lib/libpthread/stdio/puts.c b/lib/libpthread/stdio/puts.c
new file mode 100644
index 00000000000..bb7357b1cb4
--- /dev/null
+++ b/lib/libpthread/stdio/puts.c
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)puts.c 5.6 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: puts.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+
+/*
+ * Write the given string to stdout, appending a newline.
+ */
+puts(s)
+ char const *s;
+{
+ size_t c = strlen(s);
+ struct __suio uio;
+ struct __siov iov[2];
+ int r;
+
+ iov[0].iov_base = (void *)s;
+ iov[0].iov_len = c;
+ iov[1].iov_base = "\n";
+ iov[1].iov_len = 1;
+ uio.uio_resid = c + 1;
+ uio.uio_iov = &iov[0];
+ uio.uio_iovcnt = 2;
+
+ flockfile(stdout);
+ r = (__sfvwrite(stdout, &uio) ? EOF : '\n');
+ funlockfile(stdout);
+ return(r);
+}
diff --git a/lib/libpthread/stdio/putw.c b/lib/libpthread/stdio/putw.c
new file mode 100644
index 00000000000..0bb28601d4d
--- /dev/null
+++ b/lib/libpthread/stdio/putw.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)putw.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: putw.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include "fvwrite.h"
+
+putw(w, fp)
+ int w;
+ FILE *fp;
+{
+ struct __suio uio;
+ struct __siov iov;
+ int r;
+
+ iov.iov_base = &w;
+ iov.iov_len = uio.uio_resid = sizeof(w);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+
+ flockfile(fp);
+ r = (__sfvwrite(fp, &uio));
+ funlockfile(fp);
+ return(r);
+}
diff --git a/lib/libpthread/stdio/refill.c b/lib/libpthread/stdio/refill.c
new file mode 100644
index 00000000000..8485159ad6c
--- /dev/null
+++ b/lib/libpthread/stdio/refill.c
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)refill.c 5.3 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: refill.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+#include "glue.h"
+
+extern pthread_mutex_t __sfp_mutex;
+extern pthread_cond_t __sfp_cond;
+extern struct glue __sglue;
+extern int __sfp_state;
+
+/* This function is very similar to __swalk_sflush */
+static void __swalk_lflush()
+{
+ register FILE *fp, *savefp;
+ register int n, saven;
+ register struct glue *g, *saveg;
+
+ /* Only allow other threads to read __sglue */
+ pthread_mutex_lock(&__sfp_mutex);
+ __sfp_state++;
+ pthread_mutex_unlock(&__sfp_mutex);
+
+ saven = 0;
+ saveg = NULL;
+ savefp = NULL;
+ for (g = &__sglue; g != NULL; g = g->next) {
+ for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
+ if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) {
+ /* Is there anything to flush? */
+ if (fp->_bf._base && (fp->_bf._base - fp->_p)) {
+ if (ftrylockfile(fp)) { /* Can we flush it */
+ if (!saven) { /* No, save first fp we can't flush */
+ saven;
+ saveg = g;
+ savefp = fp;
+ continue;
+ }
+ (void) __sflush(fp);
+ }
+ }
+ }
+ }
+ }
+ if (savefp) {
+ for (g = saveg; g != NULL; g = g->next) {
+ for (fp = savefp, n = saven + 1; --n >= 0; fp++) {
+ if ((fp->_flags & (__SLBF|__SWR)) == __SLBF|__SWR) {
+ /* Anything to flush */
+ while (fp->_bf._base && (fp->_bf._base - fp->_p)) {
+ if (ftrylockfile(fp)) { /* Can we flush it */
+ pthread_yield();
+ continue;
+ }
+ (void) __sflush(fp);
+ }
+ }
+ }
+ }
+ }
+
+ /* If no other readers wakeup a thread waiting to do __sfp */
+ pthread_mutex_lock(&__sfp_mutex);
+ if (! (--__sfp_state)) {
+ pthread_cond_signal(&__sfp_cond);
+ }
+ pthread_mutex_unlock(&__sfp_mutex);
+}
+
+/*
+ * Refill a stdio buffer.
+ * Return EOF on eof or error, 0 otherwise.
+ */
+__srefill(fp)
+ register FILE *fp;
+{
+
+ /* make sure stdio is set up */
+ pthread_once(&__sdidinit, __sinit);
+
+ fp->_r = 0; /* largely a convenience for callers */
+
+ /* SysV does not make this test; take it out for compatibility */
+ if (fp->_flags & __SEOF)
+ return (EOF);
+
+ /* if not already reading, have to be reading and writing */
+ if ((fp->_flags & __SRD) == 0) {
+ if ((fp->_flags & __SRW) == 0) {
+ errno = EBADF;
+ return (EOF);
+ }
+ /* switch to reading */
+ if (fp->_flags & __SWR) {
+ if (__sflush(fp))
+ return (EOF);
+ fp->_flags &= ~__SWR;
+ fp->_w = 0;
+ fp->_lbfsize = 0;
+ }
+ fp->_flags |= __SRD;
+ } else {
+ /*
+ * We were reading. If there is an ungetc buffer,
+ * we must have been reading from that. Drop it,
+ * restoring the previous buffer (if any). If there
+ * is anything in that buffer, return.
+ */
+ if (HASUB(fp)) {
+ FREEUB(fp);
+ if ((fp->_r = fp->_ur) != 0) {
+ fp->_p = fp->_up;
+ return (0);
+ }
+ }
+ }
+
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+
+ /*
+ * Before reading from a line buffered or unbuffered file,
+ * flush all line buffered output files, per the ANSI C
+ * standard.
+ */
+ if (fp->_flags & (__SLBF|__SNBF))
+ __swalk_lflush();
+ fp->_p = fp->_bf._base;
+ fp->_r = __sread(fp, (char *)fp->_p, fp->_bf._size);
+ fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
+ if (fp->_r <= 0) {
+ if (fp->_r == 0)
+ fp->_flags |= __SEOF;
+ else {
+ fp->_r = 0;
+ fp->_flags |= __SERR;
+ }
+ return (EOF);
+ }
+ return (0);
+}
diff --git a/lib/libpthread/stdio/remove.c b/lib/libpthread/stdio/remove.c
new file mode 100644
index 00000000000..3a09735f298
--- /dev/null
+++ b/lib/libpthread/stdio/remove.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)remove.c 5.3 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: remove.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+
+remove(file)
+ const char *file;
+{
+ return (unlink(file));
+}
diff --git a/lib/libpthread/stdio/rewind.c b/lib/libpthread/stdio/rewind.c
new file mode 100644
index 00000000000..b5d1a9d8e67
--- /dev/null
+++ b/lib/libpthread/stdio/rewind.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rewind.c 5.6 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: rewind.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+
+void
+rewind(fp)
+ register FILE *fp;
+{
+ flockfile(fp);
+ (void) fseek(fp, 0L, SEEK_SET);
+ fp->_flags &= ~(__SERR|__SEOF); /* clearerr */
+ funlockfile(fp);
+ errno = 0; /* not required, but seems reasonable */
+}
diff --git a/lib/libpthread/stdio/rget.c b/lib/libpthread/stdio/rget.c
new file mode 100644
index 00000000000..f43747cda99
--- /dev/null
+++ b/lib/libpthread/stdio/rget.c
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rget.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: rget.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * Handle getc() when the buffer ran out:
+ * Refill, then return the first character
+ * in the newly-filled buffer.
+ */
+__srget(fp)
+ register FILE *fp;
+{
+ if (__srefill(fp) == 0) {
+ fp->_r--;
+ return (*fp->_p++);
+ }
+ return (EOF);
+}
diff --git a/lib/libpthread/stdio/scanf.c b/lib/libpthread/stdio/scanf.c
new file mode 100644
index 00000000000..7feb1f529f0
--- /dev/null
+++ b/lib/libpthread/stdio/scanf.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)scanf.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: scanf.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+scanf(char const *fmt, ...)
+#else
+scanf(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ flockfile(stdin);
+ ret = __svfscanf(stdin, fmt, ap);
+ flockfile(stdin);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/setbuf.c b/lib/libpthread/stdio/setbuf.c
new file mode 100644
index 00000000000..94ae5d66d75
--- /dev/null
+++ b/lib/libpthread/stdio/setbuf.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)setbuf.c 5.3 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: setbuf.c,v 1.1 1995/10/18 08:43:08 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+
+void
+setbuf(fp, buf)
+ FILE *fp;
+ char *buf;
+{
+ (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
diff --git a/lib/libpthread/stdio/setbuffer.c b/lib/libpthread/stdio/setbuffer.c
new file mode 100644
index 00000000000..e390674110b
--- /dev/null
+++ b/lib/libpthread/stdio/setbuffer.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)setbuffer.c 5.5 (Berkeley) 3/18/91";*/
+static char *rcsid = "$Id: setbuffer.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+void
+setbuffer(fp, buf, size)
+ register FILE *fp;
+ char *buf;
+ int size;
+{
+
+ (void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
+}
+
+/*
+ * set line buffering
+ */
+setlinebuf(fp)
+ FILE *fp;
+{
+
+ (void) setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0);
+ return (0); /* ??? */
+}
diff --git a/lib/libpthread/stdio/setvbuf.c b/lib/libpthread/stdio/setvbuf.c
new file mode 100644
index 00000000000..f0a195a5dcf
--- /dev/null
+++ b/lib/libpthread/stdio/setvbuf.c
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)setvbuf.c 5.5 (Berkeley) 5/6/93";*/
+static char *rcsid = "$Id: setvbuf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * Set one of the three kinds of buffering, optionally including
+ * a buffer.
+ */
+setvbuf(fp, buf, mode, size)
+ register FILE *fp;
+ char *buf;
+ register int mode;
+ register size_t size;
+{
+ register int ret, flags;
+ size_t iosize;
+ int ttyflag;
+
+ /*
+ * Verify arguments. The `int' limit on `size' is due to this
+ * particular implementation. Note, buf and size are ignored
+ * when setting _IONBF.
+ */
+ if (mode != _IONBF)
+ if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
+ return (EOF);
+
+ flockfile(fp);
+ /*
+ * Write current buffer, if any. Discard unread input, cancel
+ * line buffering, and free old buffer if malloc()ed.
+ */
+ ret = 0;
+ (void)__sflush(fp);
+ fp->_r = fp->_lbfsize = 0;
+ flags = fp->_flags;
+ if (flags & __SMBF)
+ free((void *)fp->_bf._base);
+ flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT);
+
+ /* If setting unbuffered mode, skip all the hard work. */
+ if (mode == _IONBF)
+ goto nbf;
+
+ /*
+ * Find optimal I/O size for seek optimization. This also returns
+ * a `tty flag' to suggest that we check isatty(fd), but we do not
+ * care since our caller told us how to buffer.
+ */
+ flags |= __swhatbuf(fp, &iosize, &ttyflag);
+ if (size == 0) {
+ buf = NULL; /* force local allocation */
+ size = iosize;
+ }
+
+ /* Allocate buffer if needed. */
+ if (buf == NULL) {
+ if ((buf = malloc(size)) == NULL) {
+ /*
+ * Unable to honor user's request. We will return
+ * failure, but try again with file system size.
+ */
+ ret = EOF;
+ if (size != iosize) {
+ size = iosize;
+ buf = malloc(size);
+ }
+ }
+ if (buf == NULL) {
+ /* No luck; switch to unbuffered I/O. */
+nbf:
+ fp->_flags = flags | __SNBF;
+ fp->_w = 0;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ funlockfile(fp);
+ return (ret);
+ }
+ flags |= __SMBF;
+ }
+
+ /*
+ * Kill any seek optimization if the buffer is not the
+ * right size.
+ *
+ * SHOULD WE ALLOW MULTIPLES HERE (i.e., ok iff (size % iosize) == 0)?
+ */
+ if (size != iosize)
+ flags |= __SNPT;
+
+ /*
+ * Fix up the FILE fields, and set __cleanup for output flush on
+ * exit (since we are buffered in some way). If in r/w mode, go
+ * to the intermediate state, so that everyone has to call
+ * __srefill or __swsetup on the first operation -- it is more
+ * trouble than it is worth to set things up correctly here.
+ */
+ if (mode == _IOLBF)
+ flags |= __SLBF;
+ if (flags & __SRW)
+ flags &= ~(__SRD | __SWR);
+ fp->_w = 0;
+ fp->_flags = flags;
+ fp->_bf._base = fp->_p = (unsigned char *)buf;
+ fp->_bf._size = size;
+ fp->_lbfsize = 0;
+ __cleanup = _cleanup;
+
+ funlockfile(fp);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/snprintf.c b/lib/libpthread/stdio/snprintf.c
new file mode 100644
index 00000000000..8aed707d401
--- /dev/null
+++ b/lib/libpthread/stdio/snprintf.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)snprintf.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: snprintf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+snprintf(char *str, size_t n, char const *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ if ((int)n < 1)
+ return (EOF);
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n - 1;
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = 0;
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/sprintf.c b/lib/libpthread/stdio/sprintf.c
new file mode 100644
index 00000000000..cc57310cddc
--- /dev/null
+++ b/lib/libpthread/stdio/sprintf.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)sprintf.c 5.7 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: sprintf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <limits.h>
+#include "local.h"
+
+#if __STDC__
+sprintf(char *str, char const *fmt, ...)
+#else
+sprintf(str, fmt, va_alist)
+ char *str;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = INT_MAX;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vfprintf(&f, fmt, ap);
+ va_end(ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/sscanf.c b/lib/libpthread/stdio/sscanf.c
new file mode 100644
index 00000000000..959f8b67c37
--- /dev/null
+++ b/lib/libpthread/stdio/sscanf.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)sscanf.c 5.1 (Berkeley) 1/20/91";*/
+static char *rcsid = "$Id: sscanf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "local.h"
+
+#if __STDC__
+sscanf(const char *str, char const *fmt, ...)
+#else
+sscanf(str, fmt, va_alist)
+ const char *str;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ f._flags = __SRD;
+ f._file = -1;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._r = strlen(str);
+ f._ub._base = NULL;
+ f._lb._base = NULL;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = __svfscanf(&f, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/stdio.c b/lib/libpthread/stdio/stdio.c
new file mode 100644
index 00000000000..d485da20fbb
--- /dev/null
+++ b/lib/libpthread/stdio/stdio.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)stdio.c 5.3 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: stdio.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "local.h"
+
+/*
+ * Small standard I/O/seek/close functions.
+ * These maintain the `known seek offset' for seek optimisation.
+ */
+int __sread(FILE *fp, char *buf, int n)
+{
+ register int ret;
+
+ /* if the read succeeded, update the current offset */
+ if ((ret = fd_table[fp->_file]->ops->read(fd_table[fp->_file]->fd,
+ fd_table[fp->_file]->flags, buf, n)) >= 0) {
+ fp->_offset += ret;
+ } else {
+ fp->_flags &= ~__SOFF; /* paranoia */
+ }
+ return (ret);
+}
+
+int __swrite(FILE *fp, const char *buf, int n)
+{
+ if (fp->_flags & __SAPP)
+ (void) lseek(fp->_file, (off_t)0, SEEK_END);
+ fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */
+ return(fd_table[fp->_file]->ops->write(fd_table[fp->_file]->fd,
+ fd_table[fp->_file]->flags, buf, n));
+}
+
+fpos_t __sseek(FILE *fp, fpos_t offset, int whence)
+{
+ register off_t ret;
+
+ ret = lseek(fp->_file, (off_t)offset, whence);
+ if (ret == -1L)
+ fp->_flags &= ~__SOFF;
+ else {
+ fp->_flags |= __SOFF;
+ fp->_offset = ret;
+ }
+ return (ret);
+}
+
+int __sclose(FILE *fp)
+{
+ return (close(fp->_file));
+}
diff --git a/lib/libpthread/stdio/strerror.c b/lib/libpthread/stdio/strerror.c
new file mode 100644
index 00000000000..5aea7e7a4fc
--- /dev/null
+++ b/lib/libpthread/stdio/strerror.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strerror.c 5.6 (Berkeley) 5/4/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+
+char *
+strerror(num)
+ int num;
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+#define UPREFIX "Unknown error: "
+ static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
+ register unsigned int errnum;
+ register char *p, *t;
+ char tmp[40];
+
+ errnum = num; /* convert to unsigned */
+ if (errnum < sys_nerr)
+ return(sys_errlist[errnum]);
+
+ /* Do this by hand, so we don't include stdio(3). */
+ t = tmp;
+ do {
+ *t++ = "0123456789"[errnum % 10];
+ } while (errnum /= 10);
+ for (p = ebuf + sizeof(UPREFIX) - 1;;) {
+ *p++ = *--t;
+ if (t <= tmp)
+ break;
+ }
+ return(ebuf);
+}
diff --git a/lib/libpthread/stdio/tempnam.c b/lib/libpthread/stdio/tempnam.c
new file mode 100644
index 00000000000..95ecfeb3a5a
--- /dev/null
+++ b/lib/libpthread/stdio/tempnam.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)tempnam.c 5.1 (Berkeley) 2/22/91";*/
+static char *rcsid = "$Id: tempnam.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <paths.h>
+
+char *
+tempnam(dir, pfx)
+ const char *dir, *pfx;
+{
+ int sverrno;
+ char *f, *name;
+
+ if (!(name = malloc(MAXPATHLEN)))
+ return(NULL);
+
+ if (!pfx)
+ pfx = "tmp.";
+
+ if (f = getenv("TMPDIR")) {
+ (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
+ *(f + strlen(f) - 1) == '/'? "": "/", pfx);
+ if (f = mktemp(name))
+ return(f);
+ }
+
+ if (f = (char *)dir) {
+ (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
+ *(f + strlen(f) - 1) == '/'? "": "/", pfx);
+ if (f = mktemp(name))
+ return(f);
+ }
+
+ f = P_tmpdir;
+ (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
+ if (f = mktemp(name))
+ return(f);
+
+ f = _PATH_TMP;
+ (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
+ if (f = mktemp(name))
+ return(f);
+
+ sverrno = errno;
+ free(name);
+ errno = sverrno;
+ return(NULL);
+}
diff --git a/lib/libpthread/stdio/tmpfile.c b/lib/libpthread/stdio/tmpfile.c
new file mode 100644
index 00000000000..1e0fcfe60ce
--- /dev/null
+++ b/lib/libpthread/stdio/tmpfile.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)tmpfile.c 5.4 (Berkeley) 5/27/91";*/
+static char *rcsid = "$Id: tmpfile.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <paths.h>
+
+FILE *
+tmpfile()
+{
+ sigset_t set, oset;
+ FILE *fp;
+ int fd, sverrno;
+#define TRAILER "tmp.XXXXXX"
+ char buf[sizeof(_PATH_TMP) + sizeof(TRAILER)];
+
+ bcopy(_PATH_TMP, buf, sizeof(_PATH_TMP) - 1);
+ bcopy(TRAILER, buf + sizeof(_PATH_TMP) - 1, sizeof(TRAILER));
+
+ sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
+
+ fd = mkstemp(buf);
+ if (fd != -1)
+ (void)unlink(buf);
+
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ if (fd == -1)
+ return (NULL);
+
+ if (!(fp = fdopen(fd, "w+"))) {
+ sverrno = errno;
+ (void)close(fd);
+ errno = sverrno;
+ return (NULL);
+ }
+ return (fp);
+}
diff --git a/lib/libpthread/stdio/tmpnam.c b/lib/libpthread/stdio/tmpnam.c
new file mode 100644
index 00000000000..c5001e29c6f
--- /dev/null
+++ b/lib/libpthread/stdio/tmpnam.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)tmpnam.c 5.3 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: tmpnam.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+
+char *
+tmpnam(s)
+ char *s;
+{
+ static char buf[L_tmpnam];
+
+ if (s == NULL)
+ s = buf;
+ (void)snprintf(s, L_tmpnam, "%stmp.XXXXXX", P_tmpdir);
+ return(mktemp(s));
+}
diff --git a/lib/libpthread/stdio/ungetc.c b/lib/libpthread/stdio/ungetc.c
new file mode 100644
index 00000000000..6366050da70
--- /dev/null
+++ b/lib/libpthread/stdio/ungetc.c
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)ungetc.c 5.6 (Berkeley) 5/4/91";*/
+static char *rcsid = "$Id: ungetc.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+
+/*
+ * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
+ * the buffer moves, so that it points the same distance from the end,
+ * and move the bytes in the buffer around as necessary so that they
+ * are all at the end (stack-style).
+ */
+static
+__submore(fp)
+ register FILE *fp;
+{
+ register int i;
+ register unsigned char *p;
+
+ if (fp->_ub._base == fp->_ubuf) {
+ /*
+ * Get a new buffer (rather than expanding the old one).
+ */
+ if ((p = malloc((size_t)BUFSIZ)) == NULL)
+ return (EOF);
+ fp->_ub._base = p;
+ fp->_ub._size = BUFSIZ;
+ p += BUFSIZ - sizeof(fp->_ubuf);
+ for (i = sizeof(fp->_ubuf); --i >= 0;)
+ p[i] = fp->_ubuf[i];
+ fp->_p = p;
+ return (0);
+ }
+ i = fp->_ub._size;
+ p = realloc(fp->_ub._base, i << 1);
+ if (p == NULL)
+ return (EOF);
+ (void) bcopy((void *)p, (void *)(p + i), (size_t)i);
+ fp->_p = p + i;
+ fp->_ub._base = p;
+ fp->_ub._size = i << 1;
+ return (0);
+}
+
+ungetc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ if (c == EOF)
+ return (EOF);
+ pthread_once(&__sdidinit, __sinit);
+
+ flockfile(fp);
+ if ((fp->_flags & __SRD) == 0) {
+ /*
+ * Not already reading: no good unless reading-and-writing.
+ * Otherwise, flush any current write stuff.
+ */
+ if ((fp->_flags & __SRW) == 0)
+ c = EOF;
+ goto ungetc_end;
+ if (fp->_flags & __SWR) {
+ if (__sflush(fp))
+ c = EOF;
+ goto ungetc_end;
+ fp->_flags &= ~__SWR;
+ fp->_w = 0;
+ fp->_lbfsize = 0;
+ }
+ fp->_flags |= __SRD;
+ }
+ c = (unsigned char)c;
+
+ /*
+ * If we are in the middle of ungetc'ing, just continue.
+ * This may require expanding the current ungetc buffer.
+ */
+ if (HASUB(fp)) {
+ if (fp->_r >= fp->_ub._size && __submore(fp))
+ return (EOF);
+ *--fp->_p = c;
+ fp->_r++;
+ goto ungetc_end;
+ }
+
+ /*
+ * If we can handle this by simply backing up, do so,
+ * but never replace the original character.
+ * (This makes sscanf() work when scanning `const' data.)
+ */
+ if (fp->_bf._base != NULL && fp->_p > fp->_bf._base &&
+ fp->_p[-1] == c) {
+ fp->_p--;
+ fp->_r++;
+ goto ungetc_end;
+ }
+
+ /*
+ * Create an ungetc buffer.
+ * Initially, we will use the `reserve' buffer.
+ */
+ fp->_ur = fp->_r;
+ fp->_up = fp->_p;
+ fp->_ub._base = fp->_ubuf;
+ fp->_ub._size = sizeof(fp->_ubuf);
+ fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
+ fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
+ fp->_r = 1;
+
+ungetc_end:;
+ funlockfile(fp);
+ return (c);
+}
diff --git a/lib/libpthread/stdio/vfprintf.c b/lib/libpthread/stdio/vfprintf.c
new file mode 100644
index 00000000000..c246e417980
--- /dev/null
+++ b/lib/libpthread/stdio/vfprintf.c
@@ -0,0 +1,774 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/
+static char *rcsid = "$Id: vfprintf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Actual printf innards.
+ *
+ * This code is large and complicated...
+ */
+
+#include <pthread.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "local.h"
+#include "fvwrite.h"
+
+/* Define FLOATING_POINT to get floating point. */
+#define FLOATING_POINT
+
+/*
+ * Flush out all the vectors defined by the given uio,
+ * then reset it so that it can be reused.
+ */
+static int
+__sprint(fp, uio)
+ register FILE* fp;
+ register struct __suio *uio;
+{
+ register int err;
+
+ if (uio->uio_resid == 0) {
+ uio->uio_iovcnt = 0;
+ return (0);
+ }
+ err = __sfvwrite(fp, uio);
+ uio->uio_resid = 0;
+ uio->uio_iovcnt = 0;
+ return (err);
+}
+
+/*
+ * Helper function for `fprintf to unbuffered unix file': creates a
+ * temporary buffer. We only work on write-only files; this avoids
+ * worries about ungetc buffers and so forth.
+ */
+static int
+__sbprintf(fp, fmt, ap)
+ FILE *fp;
+ const char *fmt;
+ va_list ap;
+{
+ unsigned char buf[BUFSIZ];
+ FILE fake;
+ int ret;
+
+ /* copy the important variables */
+ fake._flags = fp->_flags & ~__SNBF;
+ fake._file = fp->_file;
+
+ /* set up the buffer */
+ fake._bf._base = fake._p = buf;
+ fake._bf._size = fake._w = sizeof(buf);
+ fake._lbfsize = 0; /* not actually used, but Just In Case */
+
+ /* do the work, then copy any error status */
+ ret = vfprintf(&fake, fmt, ap);
+ if (ret >= 0 && fflush(&fake))
+ ret = EOF;
+ if (fake._flags & __SERR)
+ fp->_flags |= __SERR;
+ return (ret);
+}
+
+
+#ifdef FLOATING_POINT
+#include <locale.h>
+#include <math.h>
+#include "floatio.h"
+
+#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
+#define DEFPREC 6
+
+static char *cvt __P((double, int, int, char *, int *, int, int *));
+static int exponent __P((char *, int, int));
+
+#else /* no FLOATING_POINT */
+
+#define BUF 40
+
+#endif /* FLOATING_POINT */
+
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define to_char(n) ((n) + '0')
+
+/*
+ * Flags used during conversion.
+ */
+#define ALT 0x001 /* alternate form */
+#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
+#define LADJUST 0x004 /* left adjustment */
+#define LONGDBL 0x008 /* long double; unimplemented */
+#define LONGINT 0x010 /* long integer */
+#define QUADINT 0x020 /* quad integer */
+#define SHORTINT 0x040 /* short integer */
+#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
+#define FPT 0x100 /* Floating point number */
+int
+vfprintf(fp, fmt0, ap)
+ FILE *fp;
+ const char *fmt0;
+ va_list ap;
+{
+ register char *fmt; /* format string */
+ register int ch; /* character from fmt */
+ register int n; /* handy integer (short term usage) */
+ register char *cp; /* handy char pointer (short term usage) */
+ register struct __siov *iovp;/* for PRINT macro */
+ register int flags; /* flags as above */
+ int ret; /* return value accumulator */
+ int width; /* width from format (%8d), or 0 */
+ int prec; /* precision from format (%.3d), or -1 */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+#ifdef FLOATING_POINT
+ char softsign; /* temporary negative sign for floats */
+ double _double; /* double precision arguments %[eEfgG] */
+ int expt; /* integer value of exponent */
+ int expsize; /* character count for expstr */
+ int ndig; /* actual number of digits returned by cvt */
+ char expstr[7]; /* buffer for exponent string */
+#endif
+
+#ifdef __GNUC__ /* gcc has builtin quad type (long long) SOS */
+#define quad_t long long
+#define u_quad_t unsigned long long
+#endif
+
+ u_quad_t _uquad; /* integer arguments %[diouxX] */
+ enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ int fieldsz; /* field size expanded by sign, etc */
+ int realsz; /* field size expanded by dprec */
+ int size; /* size of converted field or string */
+ char *xdigs; /* digits for [xX] conversion */
+#define NIOV 8
+ struct __suio uio; /* output information: summary */
+ struct __siov iov[NIOV];/* ... and individual io vectors */
+ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
+ char ox[2]; /* space for 0x hex-prefix */
+
+ /*
+ * Choose PADSIZE to trade efficiency vs. size. If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define PADSIZE 16 /* pad chunk size */
+ static char blanks[PADSIZE] =
+ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+ static char zeroes[PADSIZE] =
+ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+ /*
+ * BEWARE, these `goto error' on error, and PAD uses `n'.
+ */
+#define PRINT(ptr, len) { \
+ iovp->iov_base = (ptr); \
+ iovp->iov_len = (len); \
+ uio.uio_resid += (len); \
+ iovp++; \
+ if (++uio.uio_iovcnt >= NIOV) { \
+ if (__sprint(fp, &uio)) \
+ goto error; \
+ iovp = iov; \
+ } \
+}
+#define PAD(howmany, with) { \
+ if ((n = (howmany)) > 0) { \
+ while (n > PADSIZE) { \
+ PRINT(with, PADSIZE); \
+ n -= PADSIZE; \
+ } \
+ PRINT(with, n); \
+ } \
+}
+#define FLUSH() { \
+ if (uio.uio_resid && __sprint(fp, &uio)) \
+ goto error; \
+ uio.uio_iovcnt = 0; \
+ iovp = iov; \
+}
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ (flags&QUADINT ? va_arg(ap, quad_t) : \
+ flags&LONGINT ? va_arg(ap, long) : \
+ flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+ (long)va_arg(ap, int))
+#define UARG() \
+ (flags&QUADINT ? va_arg(ap, u_quad_t) : \
+ flags&LONGINT ? va_arg(ap, u_long) : \
+ flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
+ (u_long)va_arg(ap, u_int))
+
+ flockfile(fp);
+
+ /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
+ if (cantwrite(fp))
+ return (EOF);
+
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0) {
+ ret = (__sbprintf(fp, fmt0, ap));
+ funlockfile(fp);
+ return(ret);
+ }
+
+ fmt = (char *)fmt0;
+ uio.uio_iov = iovp = iov;
+ uio.uio_resid = 0;
+ uio.uio_iovcnt = 0;
+ ret = 0;
+
+ /*
+ * Scan the format for conversions (`%' character).
+ */
+ for (;;) {
+ for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
+ /* void */;
+ if ((n = fmt - cp) != 0) {
+ PRINT(cp, n);
+ ret += n;
+ }
+ if (ch == '\0')
+ goto done;
+ fmt++; /* skip over '%' */
+
+ flags = 0;
+ dprec = 0;
+ width = 0;
+ prec = -1;
+ sign = '\0';
+
+rflag: ch = *fmt++;
+reswitch: switch (ch) {
+ case ' ':
+ /*
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (!sign)
+ sign = ' ';
+ goto rflag;
+ case '#':
+ flags |= ALT;
+ goto rflag;
+ case '*':
+ /*
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ if ((width = va_arg(ap, int)) >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ n = va_arg(ap, int);
+ prec = n < 0 ? -1 : n;
+ goto rflag;
+ }
+ n = 0;
+ while (is_digit(ch)) {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ }
+ prec = n < 0 ? -1 : n;
+ goto reswitch;
+ case '0':
+ /*
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ flags |= ZEROPAD;
+ goto rflag;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = 0;
+ do {
+ n = 10 * n + to_digit(ch);
+ ch = *fmt++;
+ } while (is_digit(ch));
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= QUADINT;
+ goto rflag;
+ case 'c':
+ *(cp = buf) = va_arg(ap, int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ _uquad = SARG();
+ if ((quad_t)_uquad < 0) {
+ _uquad = -_uquad;
+ sign = '-';
+ }
+ base = DEC;
+ goto number;
+#ifdef FLOATING_POINT
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ if (prec == -1) {
+ prec = DEFPREC;
+ } else if ((ch == 'g' || ch == 'G') && prec == 0) {
+ prec = 1;
+ }
+
+ if (flags & LONGDBL) {
+ _double = (double) va_arg(ap, long double);
+ } else {
+ _double = va_arg(ap, double);
+ }
+
+ /* do this before tricky precision changes */
+ /* if (isinf(_double)) {
+ if (_double < 0)
+ sign = '-';
+ cp = "Inf";
+ size = 3;
+ break;
+ } */
+/* if (isnan(_double)) {
+ cp = "NaN";
+ size = 3;
+ break;
+ } */
+
+ flags |= FPT;
+ cp = cvt(_double, prec, flags, &softsign,
+ &expt, ch, &ndig);
+ if (ch == 'g' || ch == 'G') {
+ if (expt <= -4 || expt > prec)
+ ch = (ch == 'g') ? 'e' : 'E';
+ else
+ ch = 'g';
+ }
+ if (ch <= 'e') { /* 'e' or 'E' fmt */
+ --expt;
+ expsize = exponent(expstr, expt, ch);
+ size = expsize + ndig;
+ if (ndig > 1 || flags & ALT)
+ ++size;
+ } else if (ch == 'f') { /* f fmt */
+ if (expt > 0) {
+ size = expt;
+ if (prec || flags & ALT)
+ size += prec + 1;
+ } else /* "0.X" */
+ size = prec + 2;
+ } else if (expt >= ndig) { /* fixed g fmt */
+ size = expt;
+ if (flags & ALT)
+ ++size;
+ } else
+ size = ndig + (expt > 0 ?
+ 1 : 2 - expt);
+
+ if (softsign)
+ sign = '-';
+ break;
+#endif /* FLOATING_POINT */
+ case 'n':
+ if (flags & QUADINT)
+ *va_arg(ap, quad_t *) = ret;
+ else if (flags & LONGINT)
+ *va_arg(ap, long *) = ret;
+ else if (flags & SHORTINT)
+ *va_arg(ap, short *) = ret;
+ else
+ *va_arg(ap, int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ _uquad = UARG();
+ base = OCT;
+ goto nosign;
+ case 'p':
+ /*
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ /* NOSTRICT */
+ _uquad = (u_quad_t)va_arg(ap, void *);
+ base = HEX;
+ xdigs = "0123456789abcdef";
+ flags |= HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = va_arg(ap, char *)) == NULL)
+ cp = "(null)";
+ if (prec >= 0) {
+ /*
+ * can't use strlen; can only look for the
+ * NUL in the first `prec' characters, and
+ * strlen() will go further.
+ */
+ char *p = memchr(cp, 0, prec);
+
+ if (p != NULL) {
+ size = p - cp;
+ if (size > prec)
+ size = prec;
+ } else
+ size = prec;
+ } else
+ size = strlen(cp);
+ sign = '\0';
+ break;
+ case 'U':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'u':
+ _uquad = UARG();
+ base = DEC;
+ goto nosign;
+ case 'X':
+ xdigs = "0123456789ABCDEF";
+ goto hex;
+ case 'x':
+ xdigs = "0123456789abcdef";
+hex: _uquad = UARG();
+ base = HEX;
+ /* leading 0x/X only if non-zero */
+ if (flags & ALT && _uquad != 0)
+ flags |= HEXPREFIX;
+
+ /* unsigned conversions */
+nosign: sign = '\0';
+ /*
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+number: if ((dprec = prec) >= 0)
+ flags &= ~ZEROPAD;
+
+ /*
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ */
+ cp = buf + BUF;
+ if (_uquad != 0 || prec != 0) {
+ /*
+ * Unsigned mod is hard, and unsigned mod
+ * by a constant is easier than that by
+ * a variable; hence this switch.
+ */
+ switch (base) {
+ case OCT:
+ do {
+ *--cp = to_char(_uquad & 7);
+ _uquad >>= 3;
+ } while (_uquad);
+ /* handle octal leading 0 */
+ if (flags & ALT && *cp != '0')
+ *--cp = '0';
+ break;
+
+ case DEC:
+ /* many numbers are 1 digit */
+ while (_uquad >= 10) {
+ *--cp = to_char(_uquad % 10);
+ _uquad /= 10;
+ }
+ *--cp = to_char(_uquad);
+ break;
+
+ case HEX:
+ do {
+ *--cp = xdigs[_uquad & 15];
+ _uquad >>= 4;
+ } while (_uquad);
+ break;
+
+ default:
+ cp = "bug in vfprintf: bad base";
+ size = strlen(cp);
+ goto skipsize;
+ }
+ }
+ size = buf + BUF - cp;
+ skipsize:
+ break;
+ default: /* "%?" prints ?, unless ? is NUL */
+ if (ch == '\0')
+ goto done;
+ /* pretend it was %c with argument ch */
+ cp = buf;
+ *cp = ch;
+ size = 1;
+ sign = '\0';
+ break;
+ }
+
+ /*
+ * All reasonable formats wind up here. At this point, `cp'
+ * points to a string which (if not flags&LADJUST) should be
+ * padded out to `width' places. If flags&ZEROPAD, it should
+ * first be prefixed by any sign or other prefix; otherwise,
+ * it should be blank padded before the prefix is emitted.
+ * After any left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print the
+ * string proper, then emit zeroes required by any leftover
+ * floating precision; finally, if LADJUST, pad with blanks.
+ *
+ * Compute actual size, so we know how much to pad.
+ * fieldsz excludes decimal prec; realsz includes it.
+ */
+ fieldsz = size;
+ if (sign)
+ fieldsz++;
+ else if (flags & HEXPREFIX)
+ fieldsz += 2;
+ realsz = dprec > fieldsz ? dprec : fieldsz;
+
+ /* right-adjusting blank padding */
+ if ((flags & (LADJUST|ZEROPAD)) == 0)
+ PAD(width - realsz, blanks);
+
+ /* prefix */
+ if (sign) {
+ PRINT(&sign, 1);
+ } else if (flags & HEXPREFIX) {
+ ox[0] = '0';
+ ox[1] = ch;
+ PRINT(ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+ PAD(width - realsz, zeroes);
+
+ /* leading zeroes from decimal precision */
+ PAD(dprec - fieldsz, zeroes);
+
+ /* the string or number proper */
+#ifdef FLOATING_POINT
+ if ((flags & FPT) == 0) {
+ PRINT(cp, size);
+ } else { /* glue together f_p fragments */
+ if (ch >= 'f') { /* 'f' or 'g' */
+ if (_double == 0) {
+ /* kludge for __dtoa irregularity */
+ if (expt >= ndig && (flags & ALT) == 0) {
+ PRINT("0", 1);
+ } else {
+ PRINT("0.", 2);
+ PAD(ndig - 1, zeroes);
+ }
+ } else if (expt <= 0) {
+ PRINT("0.", 2);
+ PAD(-expt, zeroes);
+ PRINT(cp, ndig);
+ } else if (expt >= ndig) {
+ PRINT(cp, ndig);
+ PAD(expt - ndig, zeroes);
+ if (flags & ALT)
+ PRINT(".", 1);
+ } else {
+ PRINT(cp, expt);
+ cp += expt;
+ PRINT(".", 1);
+ PRINT(cp, ndig-expt);
+ }
+ } else { /* 'e' or 'E' */
+ if (ndig > 1 || flags & ALT) {
+ ox[0] = *cp++;
+ ox[1] = '.';
+ PRINT(ox, 2);
+ if (_double || flags & ALT == 0) {
+ PRINT(cp, ndig-1);
+ } else /* 0.[0..] */
+ /* __dtoa irregularity */
+ PAD(ndig - 1, zeroes);
+ } else /* XeYYY */
+ PRINT(cp, 1);
+ PRINT(expstr, expsize);
+ }
+ }
+#else
+ PRINT(cp, size);
+#endif
+ /* left-adjusting padding (always blank) */
+ if (flags & LADJUST)
+ PAD(width - realsz, blanks);
+
+ /* finally, adjust ret */
+ ret += width > realsz ? width : realsz;
+
+ FLUSH(); /* copy out the I/O vectors */
+ }
+done:
+ FLUSH();
+error:
+ if (__sferror(fp))
+ ret = EOF;
+ funlockfile(fp);
+ return (ret);
+}
+
+#ifdef FLOATING_POINT
+
+extern char *__dtoa __P((double, int, int, int *, int *, char **));
+
+static char *
+cvt(value, ndigits, flags, sign, decpt, ch, length)
+ double value;
+ int ndigits, flags, *decpt, ch, *length;
+ char *sign;
+{
+ int mode, dsgn;
+ char *digits, *bp, *rve;
+
+ if (ch == 'f') {
+ mode = 3; /* ndigits after the decimal point */
+ } else {
+ /* To obtain ndigits after the decimal point for the 'e'
+ * and 'E' formats, round to ndigits + 1 significant
+ * figures.
+ */
+ if (ch == 'e' || ch == 'E') {
+ ndigits++;
+ }
+ mode = 2; /* ndigits significant digits */
+ }
+
+ if (value < 0) {
+ value = -value;
+ *sign = '-';
+ } else
+ *sign = '\000';
+ digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
+ if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
+ bp = digits + ndigits;
+ if (ch == 'f') {
+ if (*digits == '0' && value)
+ *decpt = -ndigits + 1;
+ bp += *decpt;
+ }
+ if (value == 0) /* kludge for __dtoa irregularity */
+ rve = bp;
+ while (rve < bp)
+ *rve++ = '0';
+ }
+ *length = rve - digits;
+ return (digits);
+}
+
+static int
+exponent(p0, exp, fmtch)
+ char *p0;
+ int exp, fmtch;
+{
+ register char *p, *t;
+ char expbuf[MAXEXP];
+
+ p = p0;
+ *p++ = fmtch;
+ if (exp < 0) {
+ exp = -exp;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXP;
+ if (exp > 9) {
+ do {
+ *--t = to_char(exp % 10);
+ } while ((exp /= 10) > 9);
+ *--t = to_char(exp);
+ for (; t < expbuf + MAXEXP; *p++ = *t++);
+ }
+ else {
+ *p++ = '0';
+ *p++ = to_char(exp);
+ }
+ return (p - p0);
+}
+#endif /* FLOATING_POINT */
diff --git a/lib/libpthread/stdio/vfscanf.c b/lib/libpthread/stdio/vfscanf.c
new file mode 100644
index 00000000000..121c35404fa
--- /dev/null
+++ b/lib/libpthread/stdio/vfscanf.c
@@ -0,0 +1,749 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vfscanf.c 5.7 (Berkeley) 12/14/92";*/
+static char *rcsid = "$Id: vfscanf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "local.h"
+
+#define FLOATING_POINT
+
+#include "floatio.h"
+#define BUF 513 /* Maximum length of numeric string. */
+
+/*
+ * Flags used during conversion.
+ */
+#define LONG 0x01 /* l: long or double */
+#define LONGDBL 0x02 /* L: long double; unimplemented */
+#define SHORT 0x04 /* h: short */
+#define SUPPRESS 0x08 /* suppress assignment */
+#define POINTER 0x10 /* weird %p pointer (`fake hex') */
+#define NOSKIP 0x20 /* do not skip blanks */
+
+/*
+ * The following are used in numeric conversions only:
+ * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
+ * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
+ */
+#define SIGNOK 0x40 /* +/- is (still) legal */
+#define NDIGITS 0x80 /* no digits detected */
+
+#define DPTOK 0x100 /* (float) decimal point is still legal */
+#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
+
+#define PFXOK 0x100 /* 0x prefix is (still) legal */
+#define NZDIGITS 0x200 /* no zero digits detected */
+
+/*
+ * Conversion types.
+ */
+#define CT_CHAR 0 /* %c conversion */
+#define CT_CCL 1 /* %[...] conversion */
+#define CT_STRING 2 /* %s conversion */
+#define CT_INT 3 /* integer, i.e., strtol or strtoul */
+#define CT_FLOAT 4 /* floating, i.e., strtod */
+
+#define u_char unsigned char
+#define u_long unsigned long
+
+static u_char *__sccl();
+
+/*
+ * vfscanf
+ */
+__svfscanf(fp, fmt0, ap)
+ register FILE *fp;
+ char const *fmt0;
+ va_list ap;
+{
+ register u_char *fmt = (u_char *)fmt0;
+ register int c; /* character from format, or conversion */
+ register size_t width; /* field width, or 0 */
+ register char *p; /* points into all kinds of strings */
+ register int n; /* handy integer */
+ register int flags; /* flags as defined above */
+ register char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to strtol/strtoul */
+ u_long (*ccfn)(); /* conversion function (strtol/strtoul) */
+ char ccltab[256]; /* character class table for %[...] */
+ char buf[BUF]; /* buffer for numeric conversions */
+
+ /* `basefix' is used to avoid `if' tests in the integer scanner */
+ static short basefix[17] =
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ nassigned = 0;
+ nread = 0;
+ base = 0; /* XXX just to keep gcc happy */
+ ccfn = NULL; /* XXX just to keep gcc happy */
+ for (;;) {
+ c = *fmt++;
+ if (c == 0)
+ return (nassigned);
+ if (isspace(c)) {
+ for (;;) {
+ if (fp->_r <= 0 && __srefill(fp))
+ return (nassigned);
+ if (!isspace(*fp->_p))
+ break;
+ nread++, fp->_r--, fp->_p++;
+ }
+ continue;
+ }
+ if (c != '%')
+ goto literal;
+ width = 0;
+ flags = 0;
+ /*
+ * switch on the format. continue if done;
+ * break once format type is derived.
+ */
+again: c = *fmt++;
+ switch (c) {
+ case '%':
+literal:
+ if (fp->_r <= 0 && __srefill(fp))
+ goto input_failure;
+ if (*fp->_p != c)
+ goto match_failure;
+ fp->_r--, fp->_p++;
+ nread++;
+ continue;
+
+ case '*':
+ flags |= SUPPRESS;
+ goto again;
+ case 'l':
+ flags |= LONG;
+ goto again;
+ case 'L':
+ flags |= LONGDBL;
+ goto again;
+ case 'h':
+ flags |= SHORT;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ width = width * 10 + c - '0';
+ goto again;
+
+ /*
+ * Conversions.
+ * Those marked `compat' are for 4.[123]BSD compatibility.
+ *
+ * (According to ANSI, E and X formats are supposed
+ * to the same as e and x. Sorry about that.)
+ */
+ case 'D': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'd':
+ c = CT_INT;
+ ccfn = (u_long (*)())strtol;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ ccfn = (u_long (*)())strtol;
+ base = 0;
+ break;
+
+ case 'O': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'o':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 10;
+ break;
+
+ case 'X': /* compat XXX */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 16;
+ break;
+
+#ifdef FLOATING_POINT
+ case 'E': /* compat XXX */
+ case 'F': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'e': case 'f': case 'g':
+ c = CT_FLOAT;
+ break;
+#endif
+
+ case 's':
+ c = CT_STRING;
+ break;
+
+ case '[':
+ fmt = __sccl(ccltab, fmt);
+ flags |= NOSKIP;
+ c = CT_CCL;
+ break;
+
+ case 'c':
+ flags |= NOSKIP;
+ c = CT_CHAR;
+ break;
+
+ case 'p': /* pointer format is like hex */
+ flags |= POINTER | PFXOK;
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 16;
+ break;
+
+ case 'n':
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORT)
+ *va_arg(ap, short *) = nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = nread;
+ else
+ *va_arg(ap, int *) = nread;
+ continue;
+
+ /*
+ * Disgusting backwards compatibility hacks. XXX
+ */
+ case '\0': /* compat */
+ return (EOF);
+
+ default: /* compat */
+ if (isupper(c))
+ flags |= LONG;
+ c = CT_INT;
+ ccfn = (u_long (*)())strtol;
+ base = 10;
+ break;
+ }
+
+ /*
+ * We have a conversion that requires input.
+ */
+ if (fp->_r <= 0 && __srefill(fp))
+ goto input_failure;
+
+ /*
+ * Consume leading white space, except for formats
+ * that suppress this.
+ */
+ if ((flags & NOSKIP) == 0) {
+ while (isspace(*fp->_p)) {
+ nread++;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ goto input_failure;
+ }
+ /*
+ * Note that there is at least one character in
+ * the buffer, so conversions that do not set NOSKIP
+ * ca no longer result in an input failure.
+ */
+ }
+
+ /*
+ * Do the conversion.
+ */
+ switch (c) {
+
+ case CT_CHAR:
+ /* scan arbitrary characters (sets NOSKIP) */
+ if (width == 0)
+ width = 1;
+ if (flags & SUPPRESS) {
+ size_t sum = 0;
+ for (;;) {
+ if ((n = fp->_r) < width) {
+ sum += n;
+ width -= n;
+ fp->_p += n;
+ if (__srefill(fp)) {
+ if (sum == 0)
+ goto input_failure;
+ break;
+ }
+ } else {
+ sum += width;
+ fp->_r -= width;
+ fp->_p += width;
+ break;
+ }
+ }
+ nread += sum;
+ } else {
+ size_t r = fread((void *)va_arg(ap, char *), 1,
+ width, fp);
+
+ if (r == 0)
+ goto input_failure;
+ nread += r;
+ nassigned++;
+ }
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = ~0; /* `infinity' */
+ /* take only those things in the class */
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (ccltab[*fp->_p]) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (n == 0)
+ goto input_failure;
+ break;
+ }
+ }
+ if (n == 0)
+ goto match_failure;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (ccltab[*fp->_p]) {
+ fp->_r--;
+ *p++ = *fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp)) {
+ if (p == p0)
+ goto input_failure;
+ break;
+ }
+ }
+ n = p - p0;
+ if (n == 0)
+ goto match_failure;
+ *p = 0;
+ nassigned++;
+ }
+ nread += n;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = ~0;
+ if (flags & SUPPRESS) {
+ n = 0;
+ while (!isspace(*fp->_p)) {
+ n++, fp->_r--, fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ nread += n;
+ } else {
+ p0 = p = va_arg(ap, char *);
+ while (!isspace(*fp->_p)) {
+ fp->_r--;
+ *p++ = *fp->_p++;
+ if (--width == 0)
+ break;
+ if (fp->_r <= 0 && __srefill(fp))
+ break;
+ }
+ *p = 0;
+ nread += p - p0;
+ nassigned++;
+ }
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by strtol/strtoul */
+#ifdef hardway
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+#else
+ /* size_t is unsigned, hence this optimisation */
+ if (--width > sizeof(buf) - 2)
+ width = sizeof(buf) - 2;
+ width++;
+#endif
+ flags |= SIGNOK | NDIGITS | NZDIGITS;
+ for (p = buf; width; width--) {
+ c = *fp->_p;
+ /*
+ * Switch on the character; `goto ok'
+ * if we accept it as a part of number.
+ */
+ switch (c) {
+
+ /*
+ * The digit 0 is always legal, but is
+ * special. For %i conversions, if no
+ * digits (zero or nonzero) have been
+ * scanned (only signs), we will have
+ * base==0. In that case, we should set
+ * it to 8 and enable 0x prefixing.
+ * Also, if we have not scanned zero digits
+ * before this, do not turn off prefixing
+ * (someone else will turn it off if we
+ * have scanned any nonzero digits).
+ */
+ case '0':
+ if (base == 0) {
+ base = 8;
+ flags |= PFXOK;
+ }
+ if (flags & NZDIGITS)
+ flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
+ else
+ flags &= ~(SIGNOK|PFXOK|NDIGITS);
+ goto ok;
+
+ /* 1 through 7 always legal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ base = basefix[base];
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* digits 8 and 9 ok iff decimal or hex */
+ case '8': case '9':
+ base = basefix[base];
+ if (base <= 8)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* letters ok iff hex */
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ /* no need to fix base here */
+ if (base <= 10)
+ break; /* not legal here */
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ goto ok;
+
+ /* sign ok only as first character */
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto ok;
+ }
+ break;
+
+ /* x ok iff flag still set & 2nd char */
+ case 'x': case 'X':
+ if (flags & PFXOK && p == buf + 1) {
+ base = 16; /* if %i */
+ flags &= ~PFXOK;
+ goto ok;
+ }
+ break;
+ }
+
+ /*
+ * If we got here, c is not a legal character
+ * for a number. Stop accumulating digits.
+ */
+ break;
+ ok:
+ /*
+ * c is legal: store it and look at the next.
+ */
+ *p++ = c;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ break; /* EOF */
+ }
+ /*
+ * If we had only a sign, it is no good; push
+ * back the sign. If the number ends in `x',
+ * it was [sign] '0' 'x', so push back the x
+ * and treat it as [sign] '0'.
+ */
+ if (flags & NDIGITS) {
+ if (p > buf)
+ (void) ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ c = ((u_char *)p)[-1];
+ if (c == 'x' || c == 'X') {
+ --p;
+ (void) ungetc(c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ u_long res;
+
+ *p = 0;
+ res = (*ccfn)(buf, (char **)NULL, base);
+ if (flags & POINTER)
+ *va_arg(ap, void **) = (void *)res;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = res;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = res;
+ else
+ *va_arg(ap, int *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+
+#ifdef FLOATING_POINT
+ case CT_FLOAT:
+ /* scan a floating point number as if by strtod */
+#ifdef hardway
+ if (width == 0 || width > sizeof(buf) - 1)
+ width = sizeof(buf) - 1;
+#else
+ /* size_t is unsigned, hence this optimisation */
+ if (--width > sizeof(buf) - 2)
+ width = sizeof(buf) - 2;
+ width++;
+#endif
+ flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
+ for (p = buf; width; width--) {
+ c = *fp->_p;
+ /*
+ * This code mimicks the integer conversion
+ * code, but is much simpler.
+ */
+ switch (c) {
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ flags &= ~(SIGNOK | NDIGITS);
+ goto fok;
+
+ case '+': case '-':
+ if (flags & SIGNOK) {
+ flags &= ~SIGNOK;
+ goto fok;
+ }
+ break;
+ case '.':
+ if (flags & DPTOK) {
+ flags &= ~(SIGNOK | DPTOK);
+ goto fok;
+ }
+ break;
+ case 'e': case 'E':
+ /* no exponent without some digits */
+ if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
+ flags =
+ (flags & ~(EXPOK|DPTOK)) |
+ SIGNOK | NDIGITS;
+ goto fok;
+ }
+ break;
+ }
+ break;
+ fok:
+ *p++ = c;
+ if (--fp->_r > 0)
+ fp->_p++;
+ else if (__srefill(fp))
+ break; /* EOF */
+ }
+ /*
+ * If no digits, might be missing exponent digits
+ * (just give back the exponent) or might be missing
+ * regular digits, but had sign and/or decimal point.
+ */
+ if (flags & NDIGITS) {
+ if (flags & EXPOK) {
+ /* no digits at all */
+ while (p > buf)
+ ungetc(*(u_char *)--p, fp);
+ goto match_failure;
+ }
+ /* just a bad exponent (e and maybe sign) */
+ c = *(u_char *)--p;
+ if (c != 'e' && c != 'E') {
+ (void) ungetc(c, fp);/* sign */
+ c = *(u_char *)--p;
+ }
+ (void) ungetc(c, fp);
+ }
+ if ((flags & SUPPRESS) == 0) {
+ double res;
+
+ *p = 0;
+ res = strtod(buf, (char **) NULL);
+ if (flags & LONG)
+ *va_arg(ap, double *) = res;
+ else
+ *va_arg(ap, float *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+#endif /* FLOATING_POINT */
+ }
+ }
+input_failure:
+ return (nassigned ? nassigned : -1);
+match_failure:
+ return (nassigned);
+}
+
+/*
+ * Fill in the given table from the scanset at the given format
+ * (just after `['). Return a pointer to the character past the
+ * closing `]'. The table has a 1 wherever characters should be
+ * considered part of the scanset.
+ */
+static u_char *
+__sccl(tab, fmt)
+ register char *tab;
+ register u_char *fmt;
+{
+ register int c, n, v;
+
+ /* first `clear' the whole table */
+ c = *fmt++; /* first char hat => negated scanset */
+ if (c == '^') {
+ v = 1; /* default => accept */
+ c = *fmt++; /* get new first char */
+ } else
+ v = 0; /* default => reject */
+ /* should probably use memset here */
+ for (n = 0; n < 256; n++)
+ tab[n] = v;
+ if (c == 0)
+ return (fmt - 1);/* format ended before closing ] */
+
+ /*
+ * Now set the entries corresponding to the actual scanset
+ * to the opposite of the above.
+ *
+ * The first character may be ']' (or '-') without being special;
+ * the last character may be '-'.
+ */
+ v = 1 - v;
+ for (;;) {
+ tab[c] = v; /* take character c */
+doswitch:
+ n = *fmt++; /* and examine the next */
+ switch (n) {
+
+ case 0: /* format ended too soon */
+ return (fmt - 1);
+
+ case '-':
+ /*
+ * A scanset of the form
+ * [01+-]
+ * is defined as `the digit 0, the digit 1,
+ * the character +, the character -', but
+ * the effect of a scanset such as
+ * [a-zA-Z0-9]
+ * is implementation defined. The V7 Unix
+ * scanf treats `a-z' as `the letters a through
+ * z', but treats `a-a' as `the letter a, the
+ * character -, and the letter a'.
+ *
+ * For compatibility, the `-' is not considerd
+ * to define a range if the character following
+ * it is either a close bracket (required by ANSI)
+ * or is not numerically greater than the character
+ * we just stored in the table (c).
+ */
+ n = *fmt;
+ if (n == ']' || n < c) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ do { /* fill in the range */
+ tab[++c] = v;
+ } while (c < n);
+#if 1 /* XXX another disgusting compatibility hack */
+ /*
+ * Alas, the V7 Unix scanf also treats formats
+ * such as [a-c-e] as `the letters a through e'.
+ * This too is permitted by the standard....
+ */
+ goto doswitch;
+#else
+ c = *fmt++;
+ if (c == 0)
+ return (fmt - 1);
+ if (c == ']')
+ return (fmt);
+#endif
+ break;
+
+ case ']': /* end of scanset */
+ return (fmt);
+
+ default: /* just another character */
+ c = n;
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libpthread/stdio/vprintf.c b/lib/libpthread/stdio/vprintf.c
new file mode 100644
index 00000000000..62655e0f438
--- /dev/null
+++ b/lib/libpthread/stdio/vprintf.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vprintf.c 5.6 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: vprintf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+vprintf(fmt, ap)
+ char const *fmt;
+ va_list ap;
+{
+ return (vfprintf(stdout, fmt, ap));
+}
diff --git a/lib/libpthread/stdio/vscanf.c b/lib/libpthread/stdio/vscanf.c
new file mode 100644
index 00000000000..c4c95901b47
--- /dev/null
+++ b/lib/libpthread/stdio/vscanf.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vscanf.c 5.1 (Berkeley) 4/15/91";*/
+static char *rcsid = "$Id: vscanf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+vscanf(fmt, ap)
+ const char *fmt;
+ va_list ap;
+{
+ int r;
+ flockfile(stdin);
+ r = __svfscanf(stdin, fmt, ap);
+ funlockfile(stdin);
+ return(r);
+}
diff --git a/lib/libpthread/stdio/vsnprintf.c b/lib/libpthread/stdio/vsnprintf.c
new file mode 100644
index 00000000000..672c86b2331
--- /dev/null
+++ b/lib/libpthread/stdio/vsnprintf.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vsnprintf.c 5.2 (Berkeley) 2/5/91";*/
+static char *rcsid = "$Id: vsnprintf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ const char *fmt;
+ va_list ap;
+{
+ int ret;
+ FILE f;
+
+ if ((int)n < 1)
+ return (EOF);
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n - 1;
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/vsprintf.c b/lib/libpthread/stdio/vsprintf.c
new file mode 100644
index 00000000000..d97f8b4723a
--- /dev/null
+++ b/lib/libpthread/stdio/vsprintf.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vsprintf.c 5.5 (Berkeley) 2/5/91";*/
+static char *rcsid = "$Id: vsprintf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <limits.h>
+
+vsprintf(str, fmt, ap)
+ char *str;
+ const char *fmt;
+ va_list ap;
+{
+ int ret;
+ FILE f;
+
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = INT_MAX;
+ ret = vfprintf(&f, fmt, ap);
+ *f._p = 0;
+ return (ret);
+}
diff --git a/lib/libpthread/stdio/vsscanf.c b/lib/libpthread/stdio/vsscanf.c
new file mode 100644
index 00000000000..a639a787a7c
--- /dev/null
+++ b/lib/libpthread/stdio/vsscanf.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Donn Seeley at UUNET Technologies, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)vsscanf.c 5.1 (Berkeley) 4/15/91";*/
+static char *rcsid = "$Id: vsscanf.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+
+vsscanf(str, fmt, ap)
+ const char *str;
+ const char *fmt;
+ va_list ap;
+{
+ int ret;
+ FILE f;
+
+ f._flags = __SRD;
+ f._file = -1; /* This will do the right thing */
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._r = strlen(str);
+ f._ub._base = NULL;
+ f._lb._base = NULL;
+ return (__svfscanf(&f, fmt, ap));
+}
diff --git a/lib/libpthread/stdio/wbuf.c b/lib/libpthread/stdio/wbuf.c
new file mode 100644
index 00000000000..63d8f9e3648
--- /dev/null
+++ b/lib/libpthread/stdio/wbuf.c
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)wbuf.c 5.6 (Berkeley) 1/20/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+
+/*
+ * Write the given character into the (probably full) buffer for
+ * the given file. Flush the buffer out if it is or becomes full,
+ * or if c=='\n' and the file is line buffered.
+ */
+__swbuf(c, fp)
+ register int c;
+ register FILE *fp;
+{
+ register int n;
+
+ /*
+ * In case we cannot write, or longjmp takes us out early,
+ * make sure _w is 0 (if fully- or un-buffered) or -_bf._size
+ * (if line buffered) so that we will get called again.
+ * If we did not do this, a sufficient number of putc()
+ * calls might wrap _w from negative to positive.
+ */
+ fp->_w = fp->_lbfsize;
+ if (cantwrite(fp))
+ return (EOF);
+ c = (unsigned char)c;
+
+ /*
+ * If it is completely full, flush it out. Then, in any case,
+ * stuff c into the buffer. If this causes the buffer to fill
+ * completely, or if c is '\n' and the file is line buffered,
+ * flush it (perhaps a second time). The second flush will always
+ * happen on unbuffered streams, where _bf._size==1; fflush()
+ * guarantees that putc() will always call wbuf() by setting _w
+ * to 0, so we need not do anything else.
+ */
+ n = fp->_p - fp->_bf._base;
+ if (n >= fp->_bf._size) {
+ if (fflush(fp))
+ return (EOF);
+ n = 0;
+ }
+ fp->_w--;
+ *fp->_p++ = c;
+ if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
+ if (fflush(fp))
+ return (EOF);
+ return (c);
+}
diff --git a/lib/libpthread/stdio/wsetup.c b/lib/libpthread/stdio/wsetup.c
new file mode 100644
index 00000000000..16941e113b2
--- /dev/null
+++ b/lib/libpthread/stdio/wsetup.c
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)wsetup.c 5.2 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: wsetup.c,v 1.1 1995/10/18 08:43:09 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * Various output routines call wsetup to be sure it is safe to write,
+ * because either _flags does not include __SWR, or _buf is NULL.
+ * _wsetup returns 0 if OK to write, nonzero otherwise.
+ */
+__swsetup(fp)
+ register FILE *fp;
+{
+ /* make sure stdio is set up */
+ if (!__sdidinit)
+ __sinit();
+
+ /*
+ * If we are not writing, we had better be reading and writing.
+ */
+ if ((fp->_flags & __SWR) == 0) {
+ if ((fp->_flags & __SRW) == 0)
+ return (EOF);
+ if (fp->_flags & __SRD) {
+ /* clobber any ungetc data */
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_flags &= ~(__SRD|__SEOF);
+ fp->_r = 0;
+ fp->_p = fp->_bf._base;
+ }
+ fp->_flags |= __SWR;
+ }
+
+ /*
+ * Make a buffer if necessary, then set _w.
+ */
+ if (fp->_bf._base == NULL)
+ __smakebuf(fp);
+ if (fp->_flags & __SLBF) {
+ /*
+ * It is line buffered, so make _lbfsize be -_bufsize
+ * for the putc() macro. We will change _lbfsize back
+ * to 0 whenever we turn off __SWR.
+ */
+ fp->_w = 0;
+ fp->_lbfsize = -fp->_bf._size;
+ } else
+ fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
+ return (0);
+}