Merge "Start moving to current FreeBSD stdio."
diff --git a/libc/Android.mk b/libc/Android.mk
index 74175ba..40191ee 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -15,58 +15,29 @@
 	unistd/system.c \
 	unistd/time.c \
 	stdio/asprintf.c \
-	stdio/clrerr.c \
-	stdio/fclose.c \
-	stdio/fdopen.c \
-	stdio/feof.c \
-	stdio/ferror.c \
 	stdio/fflush.c \
 	stdio/fgetc.c \
-	stdio/fgetln.c \
-	stdio/fgetpos.c \
-	stdio/fgets.c \
-	stdio/fileno.c \
 	stdio/findfp.c \
-	stdio/flags.c \
-	stdio/fopen.c \
 	stdio/fprintf.c \
-	stdio/fpurge.c \
 	stdio/fputc.c \
-	stdio/fputs.c \
 	stdio/fread.c \
 	stdio/freopen.c \
 	stdio/fscanf.c \
 	stdio/fseek.c \
-	stdio/fsetpos.c \
 	stdio/ftell.c \
-	stdio/funopen.c \
 	stdio/fvwrite.c \
-	stdio/fwalk.c \
-	stdio/fwrite.c \
-	stdio/getc.c \
-	stdio/getchar.c \
 	stdio/gets.c \
 	stdio/makebuf.c \
 	stdio/mktemp.c \
 	stdio/printf.c \
-	stdio/putc.c \
-	stdio/putchar.c \
-	stdio/puts.c \
-	stdio/putw.c \
 	stdio/refill.c \
-	stdio/remove.c \
 	stdio/rewind.c \
-	stdio/rget.c \
 	stdio/scanf.c \
-	stdio/setbuf.c \
-	stdio/setbuffer.c \
 	stdio/setvbuf.c \
 	stdio/snprintf.c\
 	stdio/sprintf.c \
 	stdio/sscanf.c \
 	stdio/stdio.c \
-	stdio/tempnam.c \
-	stdio/tmpnam.c \
 	stdio/ungetc.c \
 	stdio/vasprintf.c \
 	stdio/vfprintf.c \
@@ -77,7 +48,6 @@
 	stdio/vscanf.c \
 	stdio/vsscanf.c \
 	stdio/wbuf.c \
-	stdio/wsetup.c \
 	stdlib/atexit.c \
 	stdlib/ctype_.c \
 	stdlib/exit.c \
@@ -289,6 +259,36 @@
     bionic/wchar.cpp \
 
 libc_upstream_freebsd_src_files := \
+    upstream-freebsd/lib/libc/stdio/clrerr.c \
+    upstream-freebsd/lib/libc/stdio/fclose.c \
+    upstream-freebsd/lib/libc/stdio/fdopen.c \
+    upstream-freebsd/lib/libc/stdio/feof.c \
+    upstream-freebsd/lib/libc/stdio/ferror.c \
+    upstream-freebsd/lib/libc/stdio/fgetln.c \
+    upstream-freebsd/lib/libc/stdio/fgetpos.c \
+    upstream-freebsd/lib/libc/stdio/fgets.c \
+    upstream-freebsd/lib/libc/stdio/fileno.c \
+    upstream-freebsd/lib/libc/stdio/flags.c \
+    upstream-freebsd/lib/libc/stdio/fopen.c \
+    upstream-freebsd/lib/libc/stdio/fpurge.c \
+    upstream-freebsd/lib/libc/stdio/fputs.c \
+    upstream-freebsd/lib/libc/stdio/fsetpos.c \
+    upstream-freebsd/lib/libc/stdio/funopen.c \
+    upstream-freebsd/lib/libc/stdio/fwalk.c \
+    upstream-freebsd/lib/libc/stdio/fwrite.c \
+    upstream-freebsd/lib/libc/stdio/getc.c \
+    upstream-freebsd/lib/libc/stdio/getchar.c \
+    upstream-freebsd/lib/libc/stdio/putc.c \
+    upstream-freebsd/lib/libc/stdio/putchar.c \
+    upstream-freebsd/lib/libc/stdio/puts.c \
+    upstream-freebsd/lib/libc/stdio/putw.c \
+    upstream-freebsd/lib/libc/stdio/remove.c \
+    upstream-freebsd/lib/libc/stdio/rget.c \
+    upstream-freebsd/lib/libc/stdio/setbuf.c \
+    upstream-freebsd/lib/libc/stdio/setbuffer.c \
+    upstream-freebsd/lib/libc/stdio/tempnam.c \
+    upstream-freebsd/lib/libc/stdio/tmpnam.c \
+    upstream-freebsd/lib/libc/stdio/wsetup.c \
     upstream-freebsd/lib/libc/stdlib/realpath.c \
     upstream-freebsd/lib/libc/string/wcpcpy.c \
     upstream-freebsd/lib/libc/string/wcpncpy.c \
diff --git a/libc/stdio/fgetpos.c b/libc/stdio/fgetpos.c
deleted file mode 100644
index e6188e5..0000000
--- a/libc/stdio/fgetpos.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*	$OpenBSD: fgetpos.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- *	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. 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.
- */
-
-#include <stdio.h>
-
-/*
- * fgetpos: like ftello.
- */
-int
-fgetpos(FILE *fp, fpos_t *pos)
-{
-	return((*pos = ftello(fp)) == (fpos_t)-1);
-}
diff --git a/libc/upstream-freebsd/freebsd-compat.h b/libc/upstream-freebsd/freebsd-compat.h
index 08dec15..697ddcb 100644
--- a/libc/upstream-freebsd/freebsd-compat.h
+++ b/libc/upstream-freebsd/freebsd-compat.h
@@ -17,4 +17,12 @@
 #ifndef _BIONIC_FREEBSD_COMPAT_H_included
 #define _BIONIC_FREEBSD_COMPAT_H_included
 
+#define __USE_BSD
+
+#define _close close
+#define _fcntl fcntl
+#define _open open
+
+#define _sseek __sseek /* Needed as long as we have a mix of OpenBSD and FreeBSD stdio. */
+
 #endif
diff --git a/libc/stdio/clrerr.c b/libc/upstream-freebsd/lib/libc/stdio/clrerr.c
similarity index 78%
rename from libc/stdio/clrerr.c
rename to libc/upstream-freebsd/lib/libc/stdio/clrerr.c
index cb6c4df..1b318e6 100644
--- a/libc/stdio/clrerr.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/clrerr.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: clrerr.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,14 +30,32 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)clrerr.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
-#include "local.h"
-#undef	clearerr
+#include "un-namespace.h"
+#include "libc_private.h"
+
+#undef clearerr
+#undef clearerr_unlocked
 
 void
-clearerr(FILE *fp)
+clearerr(fp)
+	FILE *fp;
 {
 	FLOCKFILE(fp);
 	__sclearerr(fp);
 	FUNLOCKFILE(fp);
 }
+
+void
+clearerr_unlocked(FILE *fp)
+{
+
+	__sclearerr(fp);
+}
diff --git a/libc/stdio/fclose.c b/libc/upstream-freebsd/lib/libc/stdio/fclose.c
similarity index 73%
rename from libc/stdio/fclose.c
rename to libc/upstream-freebsd/lib/libc/stdio/fclose.c
index 8c3bac4..3957b6a 100644
--- a/libc/stdio/fclose.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fclose.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fclose.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,9 +30,19 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fclose.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "un-namespace.h"
+#include <spinlock.h>
+#include "libc_private.h"
 #include "local.h"
 
 int
@@ -46,7 +55,6 @@
 		return (EOF);
 	}
 	FLOCKFILE(fp);
-	WCIO_FREE(fp);
 	r = fp->_flags & __SWR ? __sflush(fp) : 0;
 	if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
 		r = EOF;
@@ -56,8 +64,22 @@
 		FREEUB(fp);
 	if (HASLB(fp))
 		FREELB(fp);
+	fp->_file = -1;
 	fp->_r = fp->_w = 0;	/* Mess up if reaccessed. */
+
+	/*
+	 * Lock the spinlock used to protect __sglue list walk in
+	 * __sfp().  The __sfp() uses fp->_flags == 0 test as an
+	 * indication of the unused FILE.
+	 *
+	 * Taking the lock prevents possible compiler or processor
+	 * reordering of the writes performed before the final _flags
+	 * cleanup, making sure that we are done with the FILE before
+	 * it is considered available.
+	 */
+	STDIO_THREAD_LOCK();
 	fp->_flags = 0;		/* Release this FILE for reuse. */
+	STDIO_THREAD_UNLOCK();
 	FUNLOCKFILE(fp);
 	return (r);
 }
diff --git a/libc/stdio/fdopen.c b/libc/upstream-freebsd/lib/libc/stdio/fdopen.c
similarity index 71%
rename from libc/stdio/fdopen.c
rename to libc/upstream-freebsd/lib/libc/stdio/fdopen.c
index 1df609c..8fc90a4 100644
--- a/libc/stdio/fdopen.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fdopen.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fdopen.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,24 +30,47 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fdopen.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <sys/types.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
+#include <limits.h>
+#include "un-namespace.h"
 #include "local.h"
 
 FILE *
-fdopen(int fd, const char *mode)
+fdopen(fd, mode)
+	int fd;
+	const char *mode;
 {
 	FILE *fp;
 	int flags, oflags, fdflags, tmp;
 
+	/*
+	 * File descriptors are a full int, but _file is only a short.
+	 * If we get a valid file descriptor that is greater than
+	 * SHRT_MAX, then the fd will get sign-extended into an
+	 * invalid file descriptor.  Handle this case by failing the
+	 * open.
+	 */
+	if (fd > SHRT_MAX) {
+		errno = EMFILE;
+		return (NULL);
+	}
+
 	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)
+	if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0)
 		return (NULL);
 	tmp = fdflags & O_ACCMODE;
 	if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
@@ -58,11 +80,17 @@
 
 	if ((fp = __sfp()) == NULL)
 		return (NULL);
+
+	if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
+		fp->_flags = 0;
+		return (NULL);
+	}
+
 	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.
+	 * O_APPEND bit set, assert __SAPP so that __swrite() caller
+	 * will _sseek() to the end before write.
 	 */
 	if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
 		fp->_flags |= __SAPP;
diff --git a/libc/stdio/feof.c b/libc/upstream-freebsd/lib/libc/stdio/feof.c
similarity index 79%
rename from libc/stdio/feof.c
rename to libc/upstream-freebsd/lib/libc/stdio/feof.c
index 0fa65b0..502f1e5 100644
--- a/libc/stdio/feof.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/feof.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: feof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,21 +30,34 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include "local.h"
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)feof.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro feof.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+
 #undef feof
+#undef feof_unlocked
 
 int
 feof(FILE *fp)
 {
-	int ret;
+	int	ret;
 
 	FLOCKFILE(fp);
-	ret = __sfeof(fp);
+	ret= __sfeof(fp);
 	FUNLOCKFILE(fp);
 	return (ret);
 }
+
+int
+feof_unlocked(FILE *fp)
+{
+
+	return (__sfeof(fp));
+}
diff --git a/libc/stdio/ferror.c b/libc/upstream-freebsd/lib/libc/stdio/ferror.c
similarity index 78%
rename from libc/stdio/ferror.c
rename to libc/upstream-freebsd/lib/libc/stdio/ferror.c
index 0d2cf01..d155ff0 100644
--- a/libc/stdio/ferror.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/ferror.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: ferror.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,15 +30,34 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ferror.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro ferror.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+
 #undef ferror
+#undef ferror_unlocked
 
 int
 ferror(FILE *fp)
 {
+	int	ret;
+
+	FLOCKFILE(fp);
+	ret = __sferror(fp);
+	FUNLOCKFILE(fp);
+	return (ret);
+}
+
+int
+ferror_unlocked(FILE *fp)
+{
+
 	return (__sferror(fp));
 }
diff --git a/libc/stdio/fgetln.c b/libc/upstream-freebsd/lib/libc/stdio/fgetln.c
similarity index 82%
rename from libc/stdio/fgetln.c
rename to libc/upstream-freebsd/lib/libc/stdio/fgetln.c
index 0947dd8..7cb2854 100644
--- a/libc/stdio/fgetln.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fgetln.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fgetln.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,9 +30,18 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgetln.c	8.2 (Berkeley) 1/2/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "un-namespace.h"
+#include "libc_private.h"
 #include "local.h"
 
 /*
@@ -43,7 +51,7 @@
  * so we add 1 here.
 #endif
  */
-static int
+int
 __slbexpand(FILE *fp, size_t newsize)
 {
 	void *p;
@@ -51,7 +59,7 @@
 #ifdef notdef
 	++newsize;
 #endif
-	if ((size_t)fp->_lb._size >= newsize)
+	if (fp->_lb._size >= newsize)
 		return (0);
 	if ((p = realloc(fp->_lb._base, newsize)) == NULL)
 		return (-1);
@@ -62,7 +70,7 @@
 
 /*
  * Get an input line.  The returned pointer often (but not always)
- * points into a stdio buffer.  Fgetline does not alter the text of
+ * points into a stdio buffer.  Fgetln does not alter the text of
  * the returned line (which is thus not a C string because it will
  * not necessarily end with '\0'), but does allow callers to modify
  * it if they wish.  Thus, we set __SMOD in case the caller does.
@@ -71,18 +79,22 @@
 fgetln(FILE *fp, size_t *lenp)
 {
 	unsigned char *p;
-	char *ret;
 	size_t len;
 	size_t off;
 
 	FLOCKFILE(fp);
-
+	ORIENT(fp, -1);
 	/* make sure there is input */
-	if (fp->_r <= 0 && __srefill(fp))
-		goto error;
+	if (fp->_r <= 0 && __srefill(fp)) {
+		*lenp = 0;
+		FUNLOCKFILE(fp);
+		return (NULL);
+	}
 
 	/* look for a newline in the input */
-	if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
+	if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) {
+		char *ret;
+
 		/*
 		 * Found one.  Flag buffer as modified to keep fseek from
 		 * `optimising' a backward seek, in case the user stomps on
@@ -103,7 +115,7 @@
 	 * As a bonus, though, we can leave off the __SMOD.
 	 *
 	 * OPTIMISTIC is length that we (optimistically) expect will
-	 * accommodate the `rest' of the string, on each trip through the
+	 * accomodate the `rest' of the string, on each trip through the
 	 * loop below.
 	 */
 #define OPTIMISTIC 80
@@ -123,7 +135,7 @@
 		off = len;
 		if (__srefill(fp))
 			break;	/* EOF or error: return partial line */
-		if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
+		if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
 			continue;
 
 		/* got it: finish up the line (like code above) */
@@ -139,12 +151,11 @@
 		break;
 	}
 	*lenp = len;
-	ret = (char *)fp->_lb._base;
 #ifdef notdef
-	ret[len] = '\0';
+	fp->_lb._base[len] = 0;
 #endif
 	FUNLOCKFILE(fp);
-	return (ret);
+	return ((char *)fp->_lb._base);
 
 error:
 	*lenp = 0;		/* ??? */
diff --git a/libc/stdio/remove.c b/libc/upstream-freebsd/lib/libc/stdio/fgetpos.c
similarity index 79%
copy from libc/stdio/remove.c
copy to libc/upstream-freebsd/lib/libc/stdio/fgetpos.c
index d09d76f..9053be8 100644
--- a/libc/stdio/remove.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fgetpos.c
@@ -1,5 +1,3 @@
-/*	$OpenBSD: remove.c,v 1.7 2005/08/08 08:05:36 espie Exp $	*/
-
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -15,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -32,18 +30,22 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgetpos.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
 
 int
-remove(const char *file)
+fgetpos(FILE * __restrict fp, fpos_t * __restrict pos)
 {
-	struct stat st;
-
-	if (lstat(file, &st) < 0)
+	/*
+	 * ftello is thread-safe; no need to lock fp.
+	 */
+	if ((*pos = ftello(fp)) == (fpos_t)-1)
 		return (-1);
-	if (S_ISDIR(st.st_mode))
-		return (rmdir(file));
-	return (unlink(file));
+	else
+		return (0);
 }
diff --git a/libc/stdio/fgets.c b/libc/upstream-freebsd/lib/libc/stdio/fgets.c
similarity index 85%
rename from libc/stdio/fgets.c
rename to libc/upstream-freebsd/lib/libc/stdio/fgets.c
index 311b7b2..a0cc724 100644
--- a/libc/stdio/fgets.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fgets.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fgets.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,18 +30,29 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgets.c	8.2 (Berkeley) 12/22/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <string.h>
+#include "un-namespace.h"
 #include "local.h"
+#include "libc_private.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.
- * Do not return NULL if n == 1.
  */
 char *
-fgets(char *buf, int n, FILE *fp)
+fgets(buf, n, fp)
+	char *buf;
+	int n;
+	FILE *fp;
 {
 	size_t len;
 	char *s;
@@ -52,24 +62,24 @@
 		return (NULL);
 
 	FLOCKFILE(fp);
-	_SET_ORIENTATION(fp, -1);
+	ORIENT(fp, -1);
 	s = buf;
 	n--;			/* leave space for NUL */
 	while (n != 0) {
 		/*
 		 * If the buffer is empty, refill it.
 		 */
-		if (fp->_r <= 0) {
+		if ((len = fp->_r) <= 0) {
 			if (__srefill(fp)) {
 				/* EOF/error: stop with partial or no line */
 				if (s == buf) {
 					FUNLOCKFILE(fp);
 					return (NULL);
-                                }
+				}
 				break;
 			}
+			len = fp->_r;
 		}
-		len = fp->_r;
 		p = fp->_p;
 
 		/*
@@ -78,7 +88,7 @@
 		 * newline, and stop.  Otherwise, copy entire chunk
 		 * and loop.
 		 */
-		if ((int)len > n)
+		if (len > n)
 			len = n;
 		t = memchr((void *)p, '\n', len);
 		if (t != NULL) {
@@ -86,7 +96,7 @@
 			fp->_r -= len;
 			fp->_p = t;
 			(void)memcpy((void *)s, (void *)p, len);
-			s[len] = '\0';
+			s[len] = 0;
 			FUNLOCKFILE(fp);
 			return (buf);
 		}
@@ -96,7 +106,7 @@
 		s += len;
 		n -= len;
 	}
-	*s = '\0';
+	*s = 0;
 	FUNLOCKFILE(fp);
 	return (buf);
 }
diff --git a/libc/stdio/fileno.c b/libc/upstream-freebsd/lib/libc/stdio/fileno.c
similarity index 78%
rename from libc/stdio/fileno.c
rename to libc/upstream-freebsd/lib/libc/stdio/fileno.c
index cbefdeb..1962bb7 100644
--- a/libc/stdio/fileno.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fileno.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fileno.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,21 +30,35 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include "local.h"
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fileno.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro fileno.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+
 #undef fileno
+#undef fileno_unlocked
 
 int
 fileno(FILE *fp)
 {
-	int ret;
+	int fd;
 
 	FLOCKFILE(fp);
-	ret = __sfileno(fp);
+	fd = __sfileno(fp);
 	FUNLOCKFILE(fp);
-	return (ret);
+
+	return (fd);
+}
+
+int
+fileno_unlocked(FILE *fp)
+{
+
+	return (__sfileno(fp));
 }
diff --git a/libc/stdio/flags.c b/libc/upstream-freebsd/lib/libc/stdio/flags.c
similarity index 73%
rename from libc/stdio/flags.c
rename to libc/upstream-freebsd/lib/libc/stdio/flags.c
index dde0447..e445fed 100644
--- a/libc/stdio/flags.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/flags.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: flags.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,19 +30,28 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)flags.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/types.h>
 #include <sys/file.h>
 #include <stdio.h>
 #include <errno.h>
-#include <fcntl.h>
+
+#include "local.h"
 
 /*
  * Return the (stdio) flags for a given mode.  Store the flags
- * to be passed to an open() syscall through *optr.
+ * to be passed to an _open() syscall through *optr.
  * Return 0 on error.
  */
 int
-__sflags(const char *mode, int *optr)
+__sflags(mode, optr)
+	const char *mode;
+	int *optr;
 {
 	int ret, m, o;
 
@@ -72,11 +80,35 @@
 		return (0);
 	}
 
-	/* [rwa]\+ or [rwa]b\+ means read and write */
-	if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
+	/* 'b' (binary) is ignored */
+	if (*mode == 'b')
+		mode++;
+
+	/* [rwa][b]\+ means read and write */
+	if (*mode == '+') {
+		mode++;
 		ret = __SRW;
 		m = O_RDWR;
 	}
+
+	/* 'b' (binary) can appear here, too -- and is ignored again */
+	if (*mode == 'b')
+		mode++;
+
+	/* 'x' means exclusive (fail if the file exists) */
+	if (*mode == 'x') {
+		mode++;
+		if (m == O_RDONLY) {
+			errno = EINVAL;
+			return (0);
+		}
+		o |= O_EXCL;
+	}
+
+	/* set close-on-exec */
+	if (*mode == 'e')
+		o |= O_CLOEXEC;
+
 	*optr = m | o;
 	return (ret);
 }
diff --git a/libc/stdio/fopen.c b/libc/upstream-freebsd/lib/libc/stdio/fopen.c
similarity index 73%
rename from libc/stdio/fopen.c
rename to libc/upstream-freebsd/lib/libc/stdio/fopen.c
index 6d2d882..6fe536a 100644
--- a/libc/stdio/fopen.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fopen.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fopen.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,18 +30,28 @@
  * SUCH DAMAGE.
  */
 
-#define __USE_BSD
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fopen.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
+#include <limits.h>
+#include "un-namespace.h"
+
 #include "local.h"
-#include <linux/stat.h>
 
 FILE *
-fopen(const char *file, const char *mode)
+fopen(file, mode)
+	const char * __restrict file;
+	const char * __restrict mode;
 {
 	FILE *fp;
 	int f;
@@ -52,10 +61,23 @@
 		return (NULL);
 	if ((fp = __sfp()) == NULL)
 		return (NULL);
-	if ((f = open(file, oflags, DEFFILEMODE)) < 0) {
+	if ((f = _open(file, oflags, DEFFILEMODE)) < 0) {
 		fp->_flags = 0;			/* release */
 		return (NULL);
 	}
+	/*
+	 * File descriptors are a full int, but _file is only a short.
+	 * If we get a valid file descriptor that is greater than
+	 * SHRT_MAX, then the fd will get sign-extended into an
+	 * invalid file descriptor.  Handle this case by failing the
+	 * open.
+	 */
+	if (f > SHRT_MAX) {
+		fp->_flags = 0;			/* release */
+		_close(f);
+		errno = EMFILE;
+		return (NULL);
+	}
 	fp->_file = f;
 	fp->_flags = flags;
 	fp->_cookie = fp;
@@ -63,7 +85,6 @@
 	fp->_write = __swrite;
 	fp->_seek = __sseek;
 	fp->_close = __sclose;
-
 	/*
 	 * When opening in append mode, even though we use O_APPEND,
 	 * we need to seek to the end so that ftell() gets the right
@@ -73,6 +94,6 @@
 	 * fseek and ftell.)
 	 */
 	if (oflags & O_APPEND)
-		(void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
+		(void)_sseek(fp, (fpos_t)0, SEEK_END);
 	return (fp);
 }
diff --git a/libc/stdio/fpurge.c b/libc/upstream-freebsd/lib/libc/stdio/fpurge.c
similarity index 77%
rename from libc/stdio/fpurge.c
rename to libc/upstream-freebsd/lib/libc/stdio/fpurge.c
index e04c4fe..148e490 100644
--- a/libc/stdio/fpurge.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fpurge.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fpurge.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,31 +30,41 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fpurge.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "un-namespace.h"
 #include "local.h"
+#include "libc_private.h"
 
 /*
  * fpurge: like fflush, but without writing anything: leave the
  * given FILE's buffer empty.
  */
 int
-fpurge(FILE *fp)
+fpurge(fp)
+	FILE *fp;
 {
+	int retval;
 	FLOCKFILE(fp);
 	if (!fp->_flags) {
-		FUNLOCKFILE(fp);
 		errno = EBADF;
-		return(EOF);
+		retval = EOF;
+	} else {
+		if (HASUB(fp))
+			FREEUB(fp);
+		fp->_p = fp->_bf._base;
+		fp->_r = 0;
+		fp->_w = fp->_flags & (__SLBF|__SNBF|__SRD) ? 0 : fp->_bf._size;
+		retval = 0;
 	}
-
-	if (HASUB(fp))
-		FREEUB(fp);
-	WCIO_FREE(fp);
-	fp->_p = fp->_bf._base;
-	fp->_r = 0;
-	fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
 	FUNLOCKFILE(fp);
-	return (0);
+	return (retval);
 }
diff --git a/libc/stdio/fputs.c b/libc/upstream-freebsd/lib/libc/stdio/fputs.c
similarity index 80%
rename from libc/stdio/fputs.c
rename to libc/upstream-freebsd/lib/libc/stdio/fputs.c
index c2462ba..eb20f9e 100644
--- a/libc/stdio/fputs.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fputs.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fputs.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,28 +30,39 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fputs.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <string.h>
-#include "local.h"
+#include "un-namespace.h"
 #include "fvwrite.h"
+#include "libc_private.h"
+#include "local.h"
 
 /*
  * Write the given string to the given file.
  */
 int
-fputs(const char *s, FILE *fp)
+fputs(s, fp)
+	const char * __restrict s;
+	FILE * __restrict fp;
 {
+	int retval;
 	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);
-	_SET_ORIENTATION(fp, -1);
-	ret = __sfvwrite(fp, &uio);
+	ORIENT(fp, -1);
+	retval = __sfvwrite(fp, &uio);
 	FUNLOCKFILE(fp);
-	return (ret);
+	return (retval);
 }
diff --git a/libc/stdio/fsetpos.c b/libc/upstream-freebsd/lib/libc/stdio/fsetpos.c
similarity index 82%
rename from libc/stdio/fsetpos.c
rename to libc/upstream-freebsd/lib/libc/stdio/fsetpos.c
index 9624fe5..f9a742e 100644
--- a/libc/stdio/fsetpos.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fsetpos.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fsetpos.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,13 +30,22 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fsetpos.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
 #include <stdio.h>
 
 /*
- * fsetpos: like fseeko.
+ * fsetpos: like fseek.
  */
 int
-fsetpos(FILE *iop, const fpos_t *pos)
+fsetpos(iop, pos)
+	FILE *iop;
+	const fpos_t *pos;
 {
 	return (fseeko(iop, (off_t)*pos, SEEK_SET));
 }
diff --git a/libc/stdio/funopen.c b/libc/upstream-freebsd/lib/libc/stdio/funopen.c
similarity index 83%
rename from libc/stdio/funopen.c
rename to libc/upstream-freebsd/lib/libc/stdio/funopen.c
index b85ee96..573589f 100644
--- a/libc/stdio/funopen.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/funopen.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: funopen.c,v 1.8 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,14 +30,23 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)funopen.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 #include <errno.h>
+
 #include "local.h"
 
 FILE *
-funopen(const void *cookie, int (*readfn)(void *, char *, int),
+funopen(const void *cookie,
+	int (*readfn)(void *, char *, int),
 	int (*writefn)(void *, const char *, int),
-	fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *))
+	fpos_t (*seekfn)(void *, fpos_t, int),
+	int (*closefn)(void *))
 {
 	FILE *fp;
 	int flags;
@@ -59,7 +67,7 @@
 		return (NULL);
 	fp->_flags = flags;
 	fp->_file = -1;
-	fp->_cookie = (void *)cookie;		/* SAFE: cookie not modified */
+	fp->_cookie = (void *)cookie;
 	fp->_read = readfn;
 	fp->_write = writefn;
 	fp->_seek = seekfn;
diff --git a/libc/stdio/fwalk.c b/libc/upstream-freebsd/lib/libc/stdio/fwalk.c
similarity index 74%
rename from libc/stdio/fwalk.c
rename to libc/upstream-freebsd/lib/libc/stdio/fwalk.c
index b1df891..cb20071 100644
--- a/libc/stdio/fwalk.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fwalk.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fwalk.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,23 +30,37 @@
  * SUCH DAMAGE.
  */
 
-#include <errno.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fwalk.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
 #include <stdio.h>
 #include "local.h"
 #include "glue.h"
 
 int
-_fwalk(int (*function)(FILE *))
+_fwalk(function)
+	int (*function)(FILE *);
 {
 	FILE *fp;
 	int n, ret;
 	struct glue *g;
 
 	ret = 0;
+	/*
+	 * It should be safe to walk the list without locking it;
+	 * new nodes are only added to the end and none are ever
+	 * removed.
+	 *
+	 * Avoid locking this list while walking it or else you will
+	 * introduce a potential deadlock in [at least] refill.c.
+	 */
 	for (g = &__sglue; g != NULL; g = g->next)
-		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
+		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
 			if ((fp->_flags != 0) && ((fp->_flags & __SIGN) == 0))
 				ret |= (*function)(fp);
-		}
 	return (ret);
 }
diff --git a/libc/stdio/fwrite.c b/libc/upstream-freebsd/lib/libc/stdio/fwrite.c
similarity index 65%
rename from libc/stdio/fwrite.c
rename to libc/upstream-freebsd/lib/libc/stdio/fwrite.c
index a97313e..acac943 100644
--- a/libc/stdio/fwrite.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/fwrite.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: fwrite.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,36 +30,70 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fwrite.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
+#include <errno.h>
+#include <stdint.h>
 #include <stdio.h>
+#include "un-namespace.h"
 #include "local.h"
 #include "fvwrite.h"
+#include "libc_private.h"
 
 /*
  * Write `count' objects (each size `size') from memory to the given file.
  * Return the number of whole objects written.
  */
 size_t
-fwrite(const void *buf, size_t size, size_t count, FILE *fp)
+fwrite(buf, size, count, fp)
+	const void * __restrict buf;
+	size_t size, count;
+	FILE * __restrict fp;
 {
 	size_t n;
 	struct __suio uio;
 	struct __siov iov;
-	int ret;
+
+	/*
+	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
+	 */
+	if ((count == 0) || (size == 0))
+		return (0);
+
+	/*
+	 * Check for integer overflow.  As an optimization, first check that
+	 * at least one of {count, size} is at least 2^16, since if both
+	 * values are less than that, their product can't possible overflow
+	 * (size_t is always at least 32 bits on FreeBSD).
+	 */
+	if (((count | size) > 0xFFFF) &&
+	    (count > SIZE_MAX / size)) {
+		errno = EINVAL;
+		fp->_flags |= __SERR;
+		return (0);
+	}
+
+	n = count * size;
 
 	iov.iov_base = (void *)buf;
-	uio.uio_resid = iov.iov_len = n = count * size;
+	uio.uio_resid = iov.iov_len = n;
 	uio.uio_iov = &iov;
 	uio.uio_iovcnt = 1;
 
+	FLOCKFILE(fp);
+	ORIENT(fp, -1);
 	/*
 	 * 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.
 	 */
-	FLOCKFILE(fp);
-	ret = __sfvwrite(fp, &uio);
+	if (__sfvwrite(fp, &uio) != 0)
+	    count = (n - uio.uio_resid) / size;
 	FUNLOCKFILE(fp);
-	if (ret == 0)
-		return (count);
-	return ((n - uio.uio_resid) / size);
+	return (count);
 }
diff --git a/libc/stdio/getc.c b/libc/upstream-freebsd/lib/libc/stdio/getc.c
similarity index 79%
rename from libc/stdio/getc.c
rename to libc/upstream-freebsd/lib/libc/stdio/getc.c
index 16a5b1d..5c94e60 100644
--- a/libc/stdio/getc.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/getc.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: getc.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,32 +30,36 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getc.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
 #include "local.h"
 
-/*
- * A subroutine version of the macro getc_unlocked.
- */
-#undef getc_unlocked
-
-int
-getc_unlocked(FILE *fp)
-{
-	return (__sgetc(fp));
-}
-
-/*
- * A subroutine version of the macro getc.
- */
 #undef getc
+#undef getc_unlocked
 
 int
 getc(FILE *fp)
 {
-	int c;
-
+	int retval;
 	FLOCKFILE(fp);
-	c = __sgetc(fp);
+	/* Orientation set by __sgetc() when buffer is empty. */
+	/* ORIENT(fp, -1); */
+	retval = __sgetc(fp);
 	FUNLOCKFILE(fp);
-	return (c);
+	return (retval);
+}
+
+int
+getc_unlocked(FILE *fp)
+{
+
+	return (__sgetc(fp));
 }
diff --git a/libc/stdio/getchar.c b/libc/upstream-freebsd/lib/libc/stdio/getchar.c
similarity index 75%
rename from libc/stdio/getchar.c
rename to libc/upstream-freebsd/lib/libc/stdio/getchar.c
index 550817d..90c84ab 100644
--- a/libc/stdio/getchar.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/getchar.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: getchar.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,28 +30,39 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-
-/*
- * A subroutine version of the macro getchar_unlocked.
- */
-#undef getchar_unlocked
-
-int
-getchar_unlocked(void)
-{
-	return (getc_unlocked(stdin));
-}
-
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getchar.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
 /*
  * A subroutine version of the macro getchar.
  */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "local.h"
+#include "libc_private.h"
 
 #undef getchar
+#undef getchar_unlocked
 
 int
-getchar(void)
+getchar()
 {
-	return (getc(stdin));
+	int retval;
+	FLOCKFILE(stdin);
+	/* Orientation set by __sgetc() when buffer is empty. */
+	/* ORIENT(stdin, -1); */
+	retval = __sgetc(stdin);
+	FUNLOCKFILE(stdin);
+	return (retval);
+}
+
+int
+getchar_unlocked(void)
+{
+
+	return (__sgetc(stdin));
 }
diff --git a/libc/stdio/putc.c b/libc/upstream-freebsd/lib/libc/stdio/putc.c
similarity index 75%
rename from libc/stdio/putc.c
rename to libc/upstream-freebsd/lib/libc/stdio/putc.c
index 2b05504..d0882f0 100644
--- a/libc/stdio/putc.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/putc.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: putc.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,37 +30,38 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include <errno.h>
-#include "local.h"
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putc.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
-/*
- * A subroutine version of the macro putc_unlocked.
- */
+#include "namespace.h"
+#include <stdio.h>
+#include "un-namespace.h"
+#include "local.h"
+#include "libc_private.h"
+
+#undef putc
 #undef putc_unlocked
 
 int
-putc_unlocked(int c, FILE *fp)
+putc(c, fp)
+	int c;
+	FILE *fp;
 {
-	if (cantwrite(fp)) {
-		errno = EBADF;
-		return (EOF);
-	}
-	return (__sputc(c, fp));
+	int retval;
+	FLOCKFILE(fp);
+	/* Orientation set by __sputc() when buffer is full. */
+	/* ORIENT(fp, -1); */
+	retval = __sputc(c, fp);
+	FUNLOCKFILE(fp);
+	return (retval);
 }
 
-/*
- * A subroutine version of the macro putc.
- */
-#undef putc
-
 int
-putc(int c, FILE *fp)
+putc_unlocked(int ch, FILE *fp)
 {
-	int ret;
 
-	FLOCKFILE(fp);
-	ret = putc_unlocked(c, fp);
-	FUNLOCKFILE(fp);
-	return (ret);
+	return (__sputc(ch, fp));
 }
diff --git a/libc/stdio/putchar.c b/libc/upstream-freebsd/lib/libc/stdio/putchar.c
similarity index 74%
rename from libc/stdio/putchar.c
rename to libc/upstream-freebsd/lib/libc/stdio/putchar.c
index eeed0a2..d263970 100644
--- a/libc/stdio/putchar.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/putchar.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: putchar.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,29 +30,42 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putchar.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
-
-#undef putchar_unlocked
-/*
- * A subrouting version of the macro putchar_unlocked
- */
-int
-putchar_unlocked(int c)
-{
-	FILE *so = stdout;
-
-	return (putc_unlocked(c, so));
-}
+#include "un-namespace.h"
+#include "local.h"
+#include "libc_private.h"
 
 #undef putchar
+#undef putchar_unlocked
 
 /*
  * A subroutine version of the macro putchar
  */
 int
-putchar(int c)
+putchar(c)
+	int c;
 {
+	int retval;
 	FILE *so = stdout;
 
-	return (putc(c, so));
+	FLOCKFILE(so);
+	/* Orientation set by __sputc() when buffer is full. */
+	/* ORIENT(so, -1); */
+	retval = __sputc(c, so);
+	FUNLOCKFILE(so);
+	return (retval);
+}
+
+int
+putchar_unlocked(int ch)
+{
+
+	return (__sputc(ch, stdout));
 }
diff --git a/libc/stdio/puts.c b/libc/upstream-freebsd/lib/libc/stdio/puts.c
similarity index 81%
rename from libc/stdio/puts.c
rename to libc/upstream-freebsd/lib/libc/stdio/puts.c
index 4603a3d..2dc945b 100644
--- a/libc/stdio/puts.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/puts.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: puts.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,21 +30,31 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)puts.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
 #include <string.h>
-#include "local.h"
+#include "un-namespace.h"
 #include "fvwrite.h"
+#include "libc_private.h"
+#include "local.h"
 
 /*
  * Write the given string to stdout, appending a newline.
  */
 int
-puts(const char *s)
+puts(s)
+	char const *s;
 {
+	int retval;
 	size_t c = strlen(s);
 	struct __suio uio;
 	struct __siov iov[2];
-	int ret;
 
 	iov[0].iov_base = (void *)s;
 	iov[0].iov_len = c;
@@ -55,7 +64,8 @@
 	uio.uio_iov = &iov[0];
 	uio.uio_iovcnt = 2;
 	FLOCKFILE(stdout);
-	ret = __sfvwrite(stdout, &uio);
+	ORIENT(stdout, -1);
+	retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
 	FUNLOCKFILE(stdout);
-	return (ret ? EOF : '\n');
+	return (retval);
 }
diff --git a/libc/stdio/putw.c b/libc/upstream-freebsd/lib/libc/stdio/putw.c
similarity index 79%
rename from libc/stdio/putw.c
rename to libc/upstream-freebsd/lib/libc/stdio/putw.c
index 12955fe..8fc1b4d 100644
--- a/libc/stdio/putw.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/putw.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: putw.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,12 +30,24 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)putw.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
 #include <stdio.h>
+#include "un-namespace.h"
 #include "fvwrite.h"
+#include "libc_private.h"
 
 int
-putw(int w, FILE *fp)
+putw(w, fp)
+	int w;
+	FILE *fp;
 {
+	int retval;
 	struct __suio uio;
 	struct __siov iov;
 
@@ -44,5 +55,8 @@
 	iov.iov_len = uio.uio_resid = sizeof(w);
 	uio.uio_iov = &iov;
 	uio.uio_iovcnt = 1;
-	return (__sfvwrite(fp, &uio));
+	FLOCKFILE(fp);
+	retval = __sfvwrite(fp, &uio);
+	FUNLOCKFILE(fp);
+	return (retval);
 }
diff --git a/libc/stdio/remove.c b/libc/upstream-freebsd/lib/libc/stdio/remove.c
similarity index 82%
rename from libc/stdio/remove.c
rename to libc/upstream-freebsd/lib/libc/stdio/remove.c
index d09d76f..f08e47c 100644
--- a/libc/stdio/remove.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/remove.c
@@ -1,5 +1,3 @@
-/*	$OpenBSD: remove.c,v 1.7 2005/08/08 08:05:36 espie Exp $	*/
-
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -15,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -32,18 +30,26 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include <unistd.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)remove.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
 
 int
-remove(const char *file)
+remove(file)
+	const char *file;
 {
-	struct stat st;
+	struct stat sb;
 
-	if (lstat(file, &st) < 0)
+	if (lstat(file, &sb) < 0)
 		return (-1);
-	if (S_ISDIR(st.st_mode))
+	if (S_ISDIR(sb.st_mode))
 		return (rmdir(file));
 	return (unlink(file));
 }
diff --git a/libc/stdio/rget.c b/libc/upstream-freebsd/lib/libc/stdio/rget.c
similarity index 88%
rename from libc/stdio/rget.c
rename to libc/upstream-freebsd/lib/libc/stdio/rget.c
index 4cd97cb..71c75e0 100644
--- a/libc/stdio/rget.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/rget.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: rget.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,6 +30,12 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rget.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 #include "local.h"
 
@@ -42,7 +47,6 @@
 int
 __srget(FILE *fp)
 {
-	_SET_ORIENTATION(fp, -1);
 	if (__srefill(fp) == 0) {
 		fp->_r--;
 		return (*fp->_p++);
diff --git a/libc/stdio/setbuf.c b/libc/upstream-freebsd/lib/libc/stdio/setbuf.c
similarity index 84%
rename from libc/stdio/setbuf.c
rename to libc/upstream-freebsd/lib/libc/stdio/setbuf.c
index 883b895..0daef54 100644
--- a/libc/stdio/setbuf.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/setbuf.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: setbuf.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,11 +30,17 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setbuf.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 #include "local.h"
 
 void
-setbuf(FILE *fp, char *buf)
+setbuf(FILE * __restrict fp, char * __restrict buf)
 {
 	(void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
 }
diff --git a/libc/stdio/setbuffer.c b/libc/upstream-freebsd/lib/libc/stdio/setbuffer.c
similarity index 81%
rename from libc/stdio/setbuffer.c
rename to libc/upstream-freebsd/lib/libc/stdio/setbuffer.c
index 8725ff7..dd1caa0 100644
--- a/libc/stdio/setbuffer.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/setbuffer.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: setbuffer.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,20 +30,30 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setbuffer.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <stdio.h>
 
 void
-setbuffer(FILE *fp, char *buf, int size)
+setbuffer(fp, buf, size)
+	FILE *fp;
+	char *buf;
+	int size;
 {
 
-	(void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
+	(void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size);
 }
 
 /*
  * set line buffering
  */
 int
-setlinebuf(FILE *fp)
+setlinebuf(fp)
+	FILE *fp;
 {
 
 	return (setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0));
diff --git a/libc/stdio/tempnam.c b/libc/upstream-freebsd/lib/libc/stdio/tempnam.c
similarity index 81%
rename from libc/stdio/tempnam.c
rename to libc/upstream-freebsd/lib/libc/stdio/tempnam.c
index 3b7ec75..ea4a2c8 100644
--- a/libc/stdio/tempnam.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/tempnam.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: tempnam.c,v 1.14 2005/08/08 08:05:36 espie Exp $ */
 /*
  * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -11,7 +10,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -28,6 +27,12 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)tempnam.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/param.h>
 #include <errno.h>
 #include <stdio.h>
@@ -42,7 +47,8 @@
 extern char *_mktemp(char *);
 
 char *
-tempnam(const char *dir, const char *pfx)
+tempnam(dir, pfx)
+	const char *dir, *pfx;
 {
 	int sverrno;
 	char *f, *name;
@@ -54,26 +60,26 @@
 		pfx = "tmp.";
 
 	if (issetugid() == 0 && (f = getenv("TMPDIR"))) {
-		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXXXXXX", f,
+		(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%sXXXXXXXXXX", f,
+		(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%sXXXXXXXXX", f, pfx);
+	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
 	if ((f = _mktemp(name)))
 		return(f);
 
 	f = _PATH_TMP;
-	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXXXXX", f, pfx);
+	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
 	if ((f = _mktemp(name)))
 		return(f);
 
diff --git a/libc/stdio/tmpnam.c b/libc/upstream-freebsd/lib/libc/stdio/tmpnam.c
similarity index 84%
rename from libc/stdio/tmpnam.c
rename to libc/upstream-freebsd/lib/libc/stdio/tmpnam.c
index 32e0a22..05bcb5b 100644
--- a/libc/stdio/tmpnam.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/tmpnam.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: tmpnam.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993, 1994
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,6 +30,12 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)tmpnam.c	8.3 (Berkeley) 3/28/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/types.h>
 
 #include <stdio.h>
@@ -42,14 +47,15 @@
 extern char *_mktemp(char *);
 
 char *
-tmpnam(char *s)
+tmpnam(s)
+	char *s;
 {
 	static u_long tmpcount;
 	static char buf[L_tmpnam];
 
 	if (s == NULL)
 		s = buf;
-	(void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXXXXX", P_tmpdir, tmpcount);
+	(void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXX", P_tmpdir, tmpcount);
 	++tmpcount;
 	return (_mktemp(s));
 }
diff --git a/libc/stdio/wsetup.c b/libc/upstream-freebsd/lib/libc/stdio/wsetup.c
similarity index 84%
rename from libc/stdio/wsetup.c
rename to libc/upstream-freebsd/lib/libc/stdio/wsetup.c
index 0834223..37bfc58 100644
--- a/libc/stdio/wsetup.c
+++ b/libc/upstream-freebsd/lib/libc/stdio/wsetup.c
@@ -1,4 +1,3 @@
-/*	$OpenBSD: wsetup.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -14,7 +13,7 @@
  * 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. Neither the name of the University nor the names of 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.
  *
@@ -31,6 +30,13 @@
  * SUCH DAMAGE.
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)wsetup.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "local.h"
@@ -38,10 +44,11 @@
 /*
  * 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.
+ * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno.
  */
 int
-__swsetup(FILE *fp)
+__swsetup(fp)
+	FILE *fp;
 {
 	/* make sure stdio is set up */
 	if (!__sdidinit)
@@ -51,8 +58,11 @@
 	 * If we are not writing, we had better be reading and writing.
 	 */
 	if ((fp->_flags & __SWR) == 0) {
-		if ((fp->_flags & __SRW) == 0)
+		if ((fp->_flags & __SRW) == 0) {
+			errno = EBADF;
+			fp->_flags |= __SERR;
 			return (EOF);
+		}
 		if (fp->_flags & __SRD) {
 			/* clobber any ungetc data */
 			if (HASUB(fp))
@@ -67,11 +77,8 @@
 	/*
 	 * Make a buffer if necessary, then set _w.
 	 */
-	if (fp->_bf._base == NULL) {
-		if ((fp->_flags & (__SSTR | __SALC)) == __SSTR)
-			return (EOF);
+	if (fp->_bf._base == NULL)
 		__smakebuf(fp);
-	}
 	if (fp->_flags & __SLBF) {
 		/*
 		 * It is line buffered, so make _lbfsize be -_bufsize
diff --git a/libc/upstream-freebsd/libc_private.h b/libc/upstream-freebsd/libc_private.h
new file mode 100644
index 0000000..ecdbb7e
--- /dev/null
+++ b/libc/upstream-freebsd/libc_private.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_FREEBSD_LIBC_PRIVATE_H_included
+#define _BIONIC_FREEBSD_LIBC_PRIVATE_H_included
+
+#define FLOCKFILE(fp)   do { if (__isthreaded) flockfile(fp); } while (0)
+#define FUNLOCKFILE(fp) do { if (__isthreaded) funlockfile(fp); } while (0)
+
+#define STDIO_THREAD_LOCK()   /* TODO: until we have the FreeBSD findfp.c, this is useless. */
+#define STDIO_THREAD_UNLOCK() /* TODO: until we have the FreeBSD findfp.c, this is useless. */
+
+#define ORIENT(fp, o) /* Only needed for wide-character stream support. */
+
+#endif
diff --git a/libc/upstream-freebsd/spinlock.h b/libc/upstream-freebsd/spinlock.h
new file mode 100644
index 0000000..f5c3785
--- /dev/null
+++ b/libc/upstream-freebsd/spinlock.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
+#define _BIONIC_FREEBSD_SPINLOCK_H_included
+
+/* TODO: until we have the FreeBSD findfp.c, this is useless. */
+
+#endif
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 4b5a1f9..2e779d8 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -193,3 +193,21 @@
 
   ASSERT_EQ(0, pclose(fp));
 }
+
+TEST(stdio, getc) {
+  FILE* fp = fopen("/proc/version", "r");
+  ASSERT_TRUE(fp != NULL);
+  ASSERT_EQ('L', getc(fp));
+  ASSERT_EQ('i', getc(fp));
+  ASSERT_EQ('n', getc(fp));
+  ASSERT_EQ('u', getc(fp));
+  ASSERT_EQ('x', getc(fp));
+  fclose(fp);
+}
+
+TEST(stdio, putc) {
+  FILE* fp = fopen("/proc/version", "r");
+  ASSERT_TRUE(fp != NULL);
+  ASSERT_EQ(EOF, putc('x', fp));
+  fclose(fp);
+}