Merge "Use [u]int32_t instead of __[u]int32_t in sys/types.h"
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index f64c108..797ce62 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -33,8 +33,12 @@
     benchmark_main.cpp \
     math_benchmark.cpp \
     property_benchmark.cpp \
+    pthread_benchmark.cpp \
+    semaphore_benchmark.cpp \
+    stdio_benchmark.cpp \
     string_benchmark.cpp \
     time_benchmark.cpp \
+    unistd_benchmark.cpp \
 
 # Build benchmarks for the device (with bionic's .so). Run with:
 #   adb shell bionic-benchmarks
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
new file mode 100644
index 0000000..621fcb6
--- /dev/null
+++ b/benchmarks/pthread_benchmark.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "benchmark.h"
+
+#include <pthread.h>
+
+static void BM_pthread_self(int iters) {
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_self();
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_pthread_self);
+
+static void BM_pthread_getspecific(int iters) {
+  StopBenchmarkTiming();
+  pthread_key_t key;
+  pthread_key_create(&key, NULL);
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_getspecific(key);
+  }
+
+  StopBenchmarkTiming();
+  pthread_key_delete(key);
+}
+BENCHMARK(BM_pthread_getspecific);
+
+static void DummyPthreadOnceInitFunction() {
+}
+
+static void BM_pthread_once(int iters) {
+  StopBenchmarkTiming();
+  pthread_once_t once = PTHREAD_ONCE_INIT;
+  pthread_once(&once, DummyPthreadOnceInitFunction);
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_once(&once, DummyPthreadOnceInitFunction);
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_pthread_once);
+
+static void BM_pthread_mutex_lock(int iters) {
+  StopBenchmarkTiming();
+  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_mutex_lock(&mutex);
+    pthread_mutex_unlock(&mutex);
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_pthread_mutex_lock);
+
+static void BM_pthread_mutex_lock_ERRORCHECK(int iters) {
+  StopBenchmarkTiming();
+  pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_mutex_lock(&mutex);
+    pthread_mutex_unlock(&mutex);
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
+
+static void BM_pthread_mutex_lock_RECURSIVE(int iters) {
+  StopBenchmarkTiming();
+  pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    pthread_mutex_lock(&mutex);
+    pthread_mutex_unlock(&mutex);
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
new file mode 100644
index 0000000..a11fcc1
--- /dev/null
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "benchmark.h"
+
+#include <semaphore.h>
+
+static void BM_semaphore_sem_getvalue(int iters) {
+  StopBenchmarkTiming();
+  sem_t semaphore;
+  sem_init(&semaphore, 1, 1);
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    int dummy;
+    sem_getvalue(&semaphore, &dummy);
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_semaphore_sem_getvalue);
+
+static void BM_semaphore_sem_wait_sem_post(int iters) {
+  StopBenchmarkTiming();
+  sem_t semaphore;
+  sem_init(&semaphore, 1, 1);
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    sem_wait(&semaphore);
+    sem_post(&semaphore);
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_semaphore_sem_wait_sem_post);
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
new file mode 100644
index 0000000..e899df7
--- /dev/null
+++ b/benchmarks/stdio_benchmark.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "benchmark.h"
+
+#include <stdio.h>
+
+#define KB 1024
+#define MB 1024*KB
+
+#define AT_COMMON_SIZES \
+    Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(8)->Arg(16)->Arg(32)->Arg(64)->Arg(512)-> \
+    Arg(1*KB)->Arg(4*KB)->Arg(8*KB)->Arg(16*KB)->Arg(64*KB)
+
+static void BM_stdio_fread(int iters, int chunk_size) {
+  StopBenchmarkTiming();
+  FILE* fp = fopen("/dev/zero", "rw");
+  char* buf = new char[chunk_size];
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    fread(buf, chunk_size, 1, fp);
+  }
+
+  StopBenchmarkTiming();
+  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
+  delete[] buf;
+  fclose(fp);
+}
+BENCHMARK(BM_stdio_fread)->AT_COMMON_SIZES;
+
+
+static void BM_stdio_fwrite(int iters, int chunk_size) {
+  StopBenchmarkTiming();
+  FILE* fp = fopen("/dev/zero", "rw");
+  char* buf = new char[chunk_size];
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+      fwrite(buf, chunk_size, 1, fp);
+  }
+
+  StopBenchmarkTiming();
+  SetBenchmarkBytesProcessed(int64_t(iters) * int64_t(chunk_size));
+  delete[] buf;
+  fclose(fp);
+}
+BENCHMARK(BM_stdio_fwrite)->AT_COMMON_SIZES;
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp
new file mode 100644
index 0000000..e839bf8
--- /dev/null
+++ b/benchmarks/unistd_benchmark.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "benchmark.h"
+
+#include <unistd.h>
+
+static void BM_unistd_getpid(int iters) {
+  StartBenchmarkTiming();
+
+  for (int i = 0; i < iters; ++i) {
+    getpid();
+  }
+
+  StopBenchmarkTiming();
+}
+BENCHMARK(BM_unistd_getpid);
diff --git a/libc/Android.mk b/libc/Android.mk
index 35efa5b..bbba7bf 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -73,15 +73,10 @@
     bionic/strntoumax.c \
     bionic/strtotimeval.c \
     bionic/system_properties_compat.c \
-    bionic/tcgetpgrp.c \
-    bionic/tcsetpgrp.c \
     bionic/time64.c \
     bionic/unlockpt.c \
-    stdio/asprintf.c \
     stdio/findfp.c \
-    stdio/fprintf.c \
     stdio/fread.c \
-    stdio/freopen.c \
     stdio/fvwrite.c \
     stdio/snprintf.c\
     stdio/sprintf.c \
@@ -96,7 +91,6 @@
     stdlib/setenv.c \
     stdlib/strtod.c \
     unistd/syslog.c \
-    unistd/time.c \
 
 # Fortify implementations of libc functions.
 libc_common_src_files += \
@@ -125,6 +119,7 @@
     bionic/brk.cpp \
     bionic/chmod.cpp \
     bionic/chown.cpp \
+    bionic/clock.cpp \
     bionic/clone.cpp \
     bionic/dirent.cpp \
     bionic/dup2.cpp \
@@ -219,6 +214,7 @@
     bionic/sys_siglist.c \
     bionic/sys_signame.c \
     bionic/tdestroy.cpp \
+    bionic/termios.cpp \
     bionic/thread_atexit.cpp \
     bionic/tmpfile.cpp \
     bionic/umount.cpp \
@@ -319,77 +315,81 @@
     upstream-openbsd/lib/libc/gen/ftok.c \
     upstream-openbsd/lib/libc/gen/getprogname.c \
     upstream-openbsd/lib/libc/gen/setprogname.c \
+    upstream-openbsd/lib/libc/gen/time.c \
     upstream-openbsd/lib/libc/gen/tolower_.c \
     upstream-openbsd/lib/libc/gen/toupper_.c \
     upstream-openbsd/lib/libc/locale/wcscoll.c \
-    upstream-openbsd/lib/libc/string/strstr.c \
-    upstream-openbsd/lib/libc/string/strsep.c \
-    upstream-openbsd/lib/libc/string/wcslcpy.c \
-    upstream-openbsd/lib/libc/string/strcasecmp.c \
-    upstream-openbsd/lib/libc/string/strdup.c \
-    upstream-openbsd/lib/libc/string/strcspn.c \
-    upstream-openbsd/lib/libc/string/strtok.c \
-    upstream-openbsd/lib/libc/string/strpbrk.c \
-    upstream-openbsd/lib/libc/string/strspn.c \
-    upstream-openbsd/lib/libc/string/wcswidth.c \
-    upstream-openbsd/lib/libc/string/strndup.c \
-    upstream-openbsd/lib/libc/stdio/ungetc.c \
-    upstream-openbsd/lib/libc/stdio/vsnprintf.c \
-    upstream-openbsd/lib/libc/stdio/tmpnam.c \
-    upstream-openbsd/lib/libc/stdio/setbuffer.c \
-    upstream-openbsd/lib/libc/stdio/fsetpos.c \
-    upstream-openbsd/lib/libc/stdio/setbuf.c \
-    upstream-openbsd/lib/libc/stdio/vprintf.c \
-    upstream-openbsd/lib/libc/stdio/perror.c \
-    upstream-openbsd/lib/libc/stdio/remove.c \
-    upstream-openbsd/lib/libc/stdio/getc.c \
-    upstream-openbsd/lib/libc/stdio/funopen.c \
-    upstream-openbsd/lib/libc/stdio/ferror.c \
-    upstream-openbsd/lib/libc/stdio/putchar.c \
-    upstream-openbsd/lib/libc/stdio/vscanf.c \
-    upstream-openbsd/lib/libc/stdio/fflush.c \
-    upstream-openbsd/lib/libc/stdio/fpurge.c \
-    upstream-openbsd/lib/libc/stdio/fputs.c \
-    upstream-openbsd/lib/libc/stdio/tempnam.c \
-    upstream-openbsd/lib/libc/stdio/printf.c \
-    upstream-openbsd/lib/libc/stdio/fileno.c \
-    upstream-openbsd/lib/libc/stdio/stdio.c \
-    upstream-openbsd/lib/libc/stdio/getdelim.c \
-    upstream-openbsd/lib/libc/stdio/fseek.c \
-    upstream-openbsd/lib/libc/stdio/fputc.c \
-    upstream-openbsd/lib/libc/stdio/fgetln.c \
-    upstream-openbsd/lib/libc/stdio/fdopen.c \
-    upstream-openbsd/lib/libc/stdio/fgets.c \
-    upstream-openbsd/lib/libc/stdio/fgetc.c \
-    upstream-openbsd/lib/libc/stdio/feof.c \
-    upstream-openbsd/lib/libc/stdio/vasprintf.c \
-    upstream-openbsd/lib/libc/stdio/refill.c \
-    upstream-openbsd/lib/libc/stdio/getline.c \
-    upstream-openbsd/lib/libc/stdio/rewind.c \
-    upstream-openbsd/lib/libc/stdio/wbuf.c \
-    upstream-openbsd/lib/libc/stdio/gets.c \
-    upstream-openbsd/lib/libc/stdio/fgetpos.c \
-    upstream-openbsd/lib/libc/stdio/fscanf.c \
-    upstream-openbsd/lib/libc/stdio/putc.c \
-    upstream-openbsd/lib/libc/stdio/vsprintf.c \
-    upstream-openbsd/lib/libc/stdio/rget.c \
+    upstream-openbsd/lib/libc/locale/wcsxfrm.c \
+    upstream-openbsd/lib/libc/stdio/asprintf.c \
     upstream-openbsd/lib/libc/stdio/clrerr.c \
-    upstream-openbsd/lib/libc/stdio/scanf.c \
-    upstream-openbsd/lib/libc/stdio/puts.c \
-    upstream-openbsd/lib/libc/stdio/getchar.c \
+    upstream-openbsd/lib/libc/stdio/fdopen.c \
+    upstream-openbsd/lib/libc/stdio/feof.c \
+    upstream-openbsd/lib/libc/stdio/ferror.c \
+    upstream-openbsd/lib/libc/stdio/fflush.c \
+    upstream-openbsd/lib/libc/stdio/fgetc.c \
+    upstream-openbsd/lib/libc/stdio/fgetln.c \
+    upstream-openbsd/lib/libc/stdio/fgetpos.c \
+    upstream-openbsd/lib/libc/stdio/fgets.c \
+    upstream-openbsd/lib/libc/stdio/fileno.c \
+    upstream-openbsd/lib/libc/stdio/fprintf.c \
+    upstream-openbsd/lib/libc/stdio/fpurge.c \
+    upstream-openbsd/lib/libc/stdio/fputc.c \
+    upstream-openbsd/lib/libc/stdio/fputs.c \
+    upstream-openbsd/lib/libc/stdio/freopen.c \
+    upstream-openbsd/lib/libc/stdio/fscanf.c \
+    upstream-openbsd/lib/libc/stdio/fseek.c \
+    upstream-openbsd/lib/libc/stdio/fsetpos.c \
     upstream-openbsd/lib/libc/stdio/ftell.c \
+    upstream-openbsd/lib/libc/stdio/funopen.c \
     upstream-openbsd/lib/libc/stdio/fwalk.c \
+    upstream-openbsd/lib/libc/stdio/getc.c \
+    upstream-openbsd/lib/libc/stdio/getchar.c \
+    upstream-openbsd/lib/libc/stdio/getdelim.c \
+    upstream-openbsd/lib/libc/stdio/getline.c \
+    upstream-openbsd/lib/libc/stdio/gets.c \
+    upstream-openbsd/lib/libc/stdio/perror.c \
+    upstream-openbsd/lib/libc/stdio/printf.c \
+    upstream-openbsd/lib/libc/stdio/putc.c \
+    upstream-openbsd/lib/libc/stdio/putchar.c \
+    upstream-openbsd/lib/libc/stdio/puts.c \
+    upstream-openbsd/lib/libc/stdio/refill.c \
+    upstream-openbsd/lib/libc/stdio/remove.c \
+    upstream-openbsd/lib/libc/stdio/rewind.c \
+    upstream-openbsd/lib/libc/stdio/rget.c \
+    upstream-openbsd/lib/libc/stdio/scanf.c \
+    upstream-openbsd/lib/libc/stdio/setbuf.c \
+    upstream-openbsd/lib/libc/stdio/setbuffer.c \
+    upstream-openbsd/lib/libc/stdio/stdio.c \
+    upstream-openbsd/lib/libc/stdio/tempnam.c \
+    upstream-openbsd/lib/libc/stdio/tmpnam.c \
+    upstream-openbsd/lib/libc/stdio/ungetc.c \
+    upstream-openbsd/lib/libc/stdio/vasprintf.c \
+    upstream-openbsd/lib/libc/stdio/vprintf.c \
+    upstream-openbsd/lib/libc/stdio/vscanf.c \
+    upstream-openbsd/lib/libc/stdio/vsnprintf.c \
+    upstream-openbsd/lib/libc/stdio/vsprintf.c \
+    upstream-openbsd/lib/libc/stdio/wbuf.c \
+    upstream-openbsd/lib/libc/stdlib/atoi.c \
+    upstream-openbsd/lib/libc/stdlib/atol.c \
+    upstream-openbsd/lib/libc/stdlib/atoll.c \
+    upstream-openbsd/lib/libc/stdlib/strtoimax.c \
+    upstream-openbsd/lib/libc/stdlib/strtol.c \
+    upstream-openbsd/lib/libc/stdlib/strtoll.c \
     upstream-openbsd/lib/libc/stdlib/strtoul.c \
     upstream-openbsd/lib/libc/stdlib/strtoull.c \
-    upstream-openbsd/lib/libc/stdlib/atoi.c \
-    upstream-openbsd/lib/libc/stdlib/atoll.c \
-    upstream-openbsd/lib/libc/stdlib/atol.c \
-    upstream-openbsd/lib/libc/stdlib/strtoimax.c \
     upstream-openbsd/lib/libc/stdlib/strtoumax.c \
-    upstream-openbsd/lib/libc/stdlib/strtoll.c \
-    upstream-openbsd/lib/libc/stdlib/strtol.c \
     upstream-openbsd/lib/libc/stdlib/system.c \
-    upstream-openbsd/lib/libc/locale/wcsxfrm.c \
+    upstream-openbsd/lib/libc/string/strcasecmp.c \
+    upstream-openbsd/lib/libc/string/strcspn.c \
+    upstream-openbsd/lib/libc/string/strdup.c \
+    upstream-openbsd/lib/libc/string/strndup.c \
+    upstream-openbsd/lib/libc/string/strpbrk.c \
+    upstream-openbsd/lib/libc/string/strsep.c \
+    upstream-openbsd/lib/libc/string/strspn.c \
+    upstream-openbsd/lib/libc/string/strstr.c \
+    upstream-openbsd/lib/libc/string/strtok.c \
+    upstream-openbsd/lib/libc/string/wcslcpy.c \
+    upstream-openbsd/lib/libc/string/wcswidth.c \
 
 libc_arch_static_src_files := \
     bionic/dl_iterate_phdr_static.cpp \
diff --git a/libc/bionic/clock.cpp b/libc/bionic/clock.cpp
new file mode 100644
index 0000000..98f71af
--- /dev/null
+++ b/libc/bionic/clock.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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 <time.h>
+#include <sys/sysconf.h>
+#include <sys/times.h>
+
+// http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html
+clock_t clock() {
+  tms t;
+  times(&t);
+  return (t.tms_utime + t.tms_stime) * (CLOCKS_PER_SEC / sysconf(_SC_CLK_TCK));
+}
diff --git a/libc/bionic/tcgetpgrp.c b/libc/bionic/tcgetpgrp.c
deleted file mode 100644
index ebff66a..0000000
--- a/libc/bionic/tcgetpgrp.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**     * Redistributions of source code must retain the above copyright
-**       notice, this list of conditions and the following disclaimer.
-**     * 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.
-**     * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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 <termios.h>
-
-pid_t tcgetpgrp(int fd)
-{
-    pid_t _pid;
-    return ioctl(fd, TIOCGPGRP, &_pid) ? (pid_t)-1 : _pid;
-}
diff --git a/libc/bionic/tcsetpgrp.c b/libc/bionic/tcsetpgrp.c
deleted file mode 100644
index 06d9cd0..0000000
--- a/libc/bionic/tcsetpgrp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**     * Redistributions of source code must retain the above copyright
-**       notice, this list of conditions and the following disclaimer.
-**     * 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.
-**     * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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 <termios.h>
-
-int tcsetpgrp(int fd, pid_t _pid)
-{
-    return ioctl(fd, TIOCSPGRP, &_pid);
-}
diff --git a/libc/bionic/termios.cpp b/libc/bionic/termios.cpp
new file mode 100644
index 0000000..082dcdc
--- /dev/null
+++ b/libc/bionic/termios.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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 <termios.h>
+#include <unistd.h>
+
+static speed_t cfgetspeed(const termios* s) {
+  return (s->c_cflag & CBAUD);
+}
+
+speed_t cfgetispeed(const termios* s) {
+  return cfgetspeed(s);
+}
+
+speed_t cfgetospeed(const termios* s) {
+  return cfgetspeed(s);
+}
+
+void cfmakeraw(termios* s) {
+  s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+  s->c_oflag &= ~OPOST;
+  s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+  s->c_cflag &= ~(CSIZE|PARENB);
+  s->c_cflag |= CS8;
+}
+
+int cfsetispeed(termios* s, speed_t speed) {
+  return cfsetspeed(s, speed);
+}
+
+int cfsetospeed(termios* s, speed_t speed) {
+  return cfsetspeed(s, speed);
+}
+
+int cfsetspeed(termios* s, speed_t speed) {
+  // TODO: check 'speed' is valid.
+  s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
+  return 0;
+}
+
+int tcdrain(int fd) {
+  // A non-zero argument to TCSBRK means "don't send a break".
+  // The drain is a side-effect of the ioctl!
+  return ioctl(fd, TCSBRK, static_cast<unsigned long>(1));
+}
+
+int tcflow(int fd, int action) {
+  return ioctl(fd, TCXONC, static_cast<unsigned long>(action));
+}
+
+int tcflush(int fd, int queue) {
+  return ioctl(fd, TCFLSH, static_cast<unsigned long>(queue));
+}
+
+int tcgetattr(int fd, termios* s) {
+  return ioctl(fd, TCGETS, s);
+}
+
+pid_t tcgetsid(int fd) {
+  pid_t sid;
+  if (ioctl(fd, TIOCGSID, &sid) == -1) {
+    return -1;
+  }
+  return sid;
+}
+
+int tcsendbreak(int fd, int duration) {
+  return ioctl(fd, TCSBRKP, static_cast<unsigned long>(duration));
+}
+
+int tcsetattr(int fd, int optional_actions, const termios* s) {
+  int cmd;
+  switch (optional_actions) {
+    case TCSANOW: cmd = TCSETS; break;
+    case TCSADRAIN: cmd = TCSETSW; break;
+    case TCSAFLUSH: cmd = TCSETSF; break;
+    default: errno = EINVAL; return -1;
+  }
+  return ioctl(fd, cmd, s);
+}
+
+pid_t tcgetpgrp(int fd) {
+  pid_t pid;
+  if (ioctl(fd, TIOCGPGRP, &pid) == -1) {
+    return -1;
+  }
+  return pid;
+}
+
+int tcsetpgrp(int fd, pid_t pid) {
+  return ioctl(fd, TIOCSPGRP, &pid);
+}
diff --git a/libc/include/sys/times.h b/libc/include/sys/times.h
index 1b9b8b2..6ce5b55 100644
--- a/libc/include/sys/times.h
+++ b/libc/include/sys/times.h
@@ -25,6 +25,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _SYS_TIMES_H_
 #define _SYS_TIMES_H_
 
@@ -34,7 +35,7 @@
 
 __BEGIN_DECLS
 
-extern clock_t times(struct tms *);
+extern clock_t times(struct tms*);
 
 __END_DECLS
 
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 0d44355..b9685ca 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -31,87 +31,23 @@
 #include <sys/cdefs.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
-#include <stdint.h>
 #include <linux/termios.h>
 
 __BEGIN_DECLS
 
-/* Redefine these to match their ioctl number */
-#undef  TCSANOW
-#define TCSANOW    TCSETS
-
-#undef  TCSADRAIN
-#define TCSADRAIN  TCSETSW
-
-#undef  TCSAFLUSH
-#define TCSAFLUSH  TCSETSF
-
-static __inline__ int tcgetattr(int fd, struct termios *s)
-{
-    return ioctl(fd, TCGETS, s);
-}
-
-static __inline__ int tcsetattr(int fd, int __opt, const struct termios *s)
-{
-    return ioctl(fd, __opt, (void *)s);
-}
-
-static __inline__ int tcflow(int fd, int action)
-{
-    return ioctl(fd, TCXONC, (void *)(intptr_t)action);
-}
-
-static __inline__ int tcflush(int fd, int __queue)
-{
-    return ioctl(fd, TCFLSH, (void *)(intptr_t)__queue);
-}
-
-static __inline__ int tcdrain(int fd)
-{
-    return ioctl(fd, TCSBRK, (void *)(intptr_t)1);
-}
-
-static __inline__ pid_t tcgetsid(int fd)
-{
-    pid_t _pid;
-    return ioctl(fd, TIOCGSID, &_pid) ? (pid_t)-1 : _pid;
-}
-
-static __inline__ int tcsendbreak(int fd, int __duration)
-{
-    return ioctl(fd, TCSBRKP, (void *)(uintptr_t)__duration);
-}
-
-static __inline__ speed_t cfgetospeed(const struct termios *s)
-{
-    return (speed_t)(s->c_cflag & CBAUD);
-}
-
-static __inline__ int cfsetospeed(struct termios *s, speed_t  speed)
-{
-    s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
-    return 0;
-}
-
-static __inline__ speed_t cfgetispeed(const struct termios *s)
-{
-    return (speed_t)(s->c_cflag & CBAUD);
-}
-
-static __inline__ int cfsetispeed(struct termios *s, speed_t  speed)
-{
-    s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
-  return 0;
-}
-
-static __inline__ void cfmakeraw(struct termios *s)
-{
-    s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
-    s->c_oflag &= ~OPOST;
-    s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
-    s->c_cflag &= ~(CSIZE|PARENB);
-    s->c_cflag |= CS8;
-}
+speed_t cfgetispeed(const struct termios*);
+speed_t cfgetospeed(const struct termios*);
+void cfmakeraw(struct termios*);
+int cfsetispeed(struct termios*, speed_t);
+int cfsetospeed(struct termios*, speed_t);
+int cfsetspeed(struct termios*, speed_t);
+int tcdrain(int);
+int tcflow(int, int);
+int tcflush(int, int);
+int tcgetattr(int, struct termios*);
+pid_t tcgetsid(int);
+int tcsendbreak(int, int);
+int tcsetattr(int, int, const struct termios*);
 
 __END_DECLS
 
diff --git a/libc/unistd/time.c b/libc/unistd/time.c
deleted file mode 100644
index 18aa62c..0000000
--- a/libc/unistd/time.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*	$OpenBSD: time.c,v 1.5 2005/08/08 08:05:34 espie Exp $ */
-/*
- * Copyright (c) 1983, 1993
- *	The 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. 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 <time.h>
-
-time_t
-time(time_t *t)
-{
-	struct timeval tt;
-	time_t ret;
-
-	if (gettimeofday(&tt, (struct timezone *)0) < 0)
-		ret = -1;
-	else
-		ret = tt.tv_sec;
-	if (t != NULL)
-		*t = ret;
-	return ret;
-}
-
-// return monotonically increasing CPU time in ticks relative to unspecified epoch
-static inline clock_t clock_now(void)
-{
-	struct timespec tm;
-	clock_gettime( CLOCK_MONOTONIC, &tm);
-	return tm.tv_sec * CLOCKS_PER_SEC + (tm.tv_nsec * (CLOCKS_PER_SEC/1e9));
-}
-
-// initialized by the constructor below
-static clock_t clock_start;
-
-// called by dlopen when .so is loaded
-__attribute__((constructor)) static void clock_crt0(void)
-{
-	clock_start = clock_now();
-}
-
-// return elapsed CPU time in clock ticks, since start of program execution
-// (spec says epoch is undefined, but glibc uses crt0 as epoch)
-clock_t
-clock(void)
-{
-	// note that if we are executing in a different thread than crt0, then the
-	// pthread_create that made us had a memory barrier so clock_start is defined
-	return clock_now() - clock_start;
-}
diff --git a/libc/upstream-netbsd/netbsd-compat.h b/libc/upstream-netbsd/netbsd-compat.h
index f830f38..84be931 100644
--- a/libc/upstream-netbsd/netbsd-compat.h
+++ b/libc/upstream-netbsd/netbsd-compat.h
@@ -25,6 +25,7 @@
 #define __type_fit(t, a) (0 == 0)
 
 #define _GNU_SOURCE
+#define __USE_BSD
 
 // TODO: we don't yet have thread-safe environment variables.
 #define __readlockenv() 0
diff --git a/libc/stdio/fprintf.c b/libc/upstream-openbsd/lib/libc/gen/time.c
similarity index 80%
copy from libc/stdio/fprintf.c
copy to libc/upstream-openbsd/lib/libc/gen/time.c
index 7415b2f..3a57500 100644
--- a/libc/stdio/fprintf.c
+++ b/libc/upstream-openbsd/lib/libc/gen/time.c
@@ -1,11 +1,8 @@
-/*	$OpenBSD: fprintf.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
-/*-
- * Copyright (c) 1990, 1993
+/*	$OpenBSD: time.c,v 1.5 2005/08/08 08:05:34 espie Exp $ */
+/*
+ * Copyright (c) 1983, 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:
@@ -31,17 +28,17 @@
  * SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/time.h>
 
-int
-fprintf(FILE *fp, const char *fmt, ...)
+time_t
+time(time_t *t)
 {
-	int ret;
-	va_list ap;
+	struct timeval tt;
 
-	va_start(ap, fmt);
-	ret = vfprintf(fp, fmt, ap);
-	va_end(ap);
-	return (ret);
+	if (gettimeofday(&tt, (struct timezone *)0) < 0)
+		return (-1);
+	if (t)
+		*t = (time_t)tt.tv_sec;
+	return (tt.tv_sec);
 }
diff --git a/libc/stdio/asprintf.c b/libc/upstream-openbsd/lib/libc/stdio/asprintf.c
similarity index 87%
rename from libc/stdio/asprintf.c
rename to libc/upstream-openbsd/lib/libc/stdio/asprintf.c
index c3d8d61..5424c90 100644
--- a/libc/stdio/asprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/asprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: asprintf.c,v 1.15 2005/10/10 12:00:52 espie Exp $	*/
+/*	$OpenBSD: asprintf.c,v 1.19 2011/05/30 18:48:33 martynas Exp $	*/
 
 /*
  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -23,14 +23,17 @@
 #include <stdarg.h>
 #include "local.h"
 
+/* PRINTFLIKE2 */
 int
 asprintf(char **str, const char *fmt, ...)
 {
 	int ret;
 	va_list ap;
 	FILE f;
+	struct __sfileext fext;
 	unsigned char *_base;
 
+	_FILEEXT_SETUP(&f, &fext);
 	f._file = -1;
 	f._flags = __SWR | __SSTR | __SALC;
 	f._bf._base = f._p = (unsigned char *)malloc(128);
@@ -50,7 +53,10 @@
 	return (ret);
 
 err:
-	free(f._bf._base);
+	if (f._bf._base) {
+		free(f._bf._base);
+		f._bf._base = NULL;
+	}
 	*str = NULL;
 	errno = ENOMEM;
 	return (-1);
diff --git a/libc/stdio/fprintf.c b/libc/upstream-openbsd/lib/libc/stdio/fprintf.c
similarity index 95%
rename from libc/stdio/fprintf.c
rename to libc/upstream-openbsd/lib/libc/stdio/fprintf.c
index 7415b2f..a391142 100644
--- a/libc/stdio/fprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fprintf.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: fprintf.c,v 1.7 2011/05/30 18:48:33 martynas Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+/* PRINTFLIKE2 */
 int
 fprintf(FILE *fp, const char *fmt, ...)
 {
diff --git a/libc/stdio/freopen.c b/libc/upstream-openbsd/lib/libc/stdio/freopen.c
similarity index 95%
rename from libc/stdio/freopen.c
rename to libc/upstream-openbsd/lib/libc/stdio/freopen.c
index f0386e9..3158fb1 100644
--- a/libc/stdio/freopen.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/freopen.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: freopen.c,v 1.9 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: freopen.c,v 1.13 2009/11/09 00:18:27 kurt Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,19 +31,18 @@
  * SUCH DAMAGE.
  */
 
-#define __USE_BSD
-
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <limits.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "local.h"
 
-/*
- * Re-direct an existing, open (probably) file to some other file.
+/* 
+ * 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.
  */
@@ -141,6 +140,14 @@
 		}
 	}
 
+	/* _file is only a short */
+	if (f > SHRT_MAX) {
+		fp->_flags = 0;		/* set it free */
+		FUNLOCKFILE(fp);
+		errno = EMFILE;
+		return (NULL);
+	}
+
 	fp->_flags = flags;
 	fp->_file = f;
 	fp->_cookie = fp;
diff --git a/libc/upstream-openbsd/openbsd-compat.h b/libc/upstream-openbsd/openbsd-compat.h
index 428156f..2c3fe56 100644
--- a/libc/upstream-openbsd/openbsd-compat.h
+++ b/libc/upstream-openbsd/openbsd-compat.h
@@ -18,5 +18,6 @@
 #define _BIONIC_OPENBSD_COMPAT_H_included
 
 #define _GNU_SOURCE
+#define __USE_BSD
 
 #endif
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 1903b04..0bfb0c3 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -172,3 +172,15 @@
   ASSERT_EQ(0, fstat64(tf.fd, &sb));
   ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
 }
+
+TEST(stdlib, system) {
+  int status;
+
+  status = system("exit 0");
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(0, WEXITSTATUS(status));
+
+  status = system("exit 1");
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(1, WEXITSTATUS(status));
+}