Merge "Upgrade to the current NetBSD rand implementation."
diff --git a/libc/Android.mk b/libc/Android.mk
index 13d2647..2fc4300 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -140,7 +140,6 @@
 	stdio/__sprintf_chk.c \
 	stdio/__vsnprintf_chk.c \
 	stdio/__vsprintf_chk.c \
-	stdlib/_rand48.c \
 	stdlib/assert.c \
 	stdlib/atexit.c \
 	stdlib/atoi.c \
@@ -151,19 +150,14 @@
 	stdlib/div.c \
 	stdlib/exit.c \
 	stdlib/getenv.c \
-	stdlib/jrand48.c \
 	stdlib/ldiv.c \
 	stdlib/lldiv.c \
 	stdlib/locale.c \
-	stdlib/lrand48.c \
-	stdlib/mrand48.c \
-	stdlib/nrand48.c \
 	stdlib/putenv.c \
 	stdlib/qsort.c \
 	stdlib/seed48.c \
 	stdlib/setenv.c \
 	stdlib/setjmperr.c \
-	stdlib/srand48.c \
 	stdlib/strntoimax.c \
 	stdlib/strntoumax.c \
 	stdlib/strtod.c \
@@ -265,8 +259,6 @@
 	bionic/clearenv.c \
 	bionic/dirname.c \
 	bionic/dirname_r.c \
-	bionic/drand48.c \
-	bionic/erand48.c \
 	bionic/err.c \
 	bionic/fdprintf.c \
 	bionic/fork.c \
@@ -342,6 +334,14 @@
 	upstream-netbsd/libc/regex/regfree.c \
 	upstream-netbsd/libc/stdio/getdelim.c \
 	upstream-netbsd/libc/stdio/getline.c \
+	upstream-netbsd/libc/stdlib/drand48.c \
+	upstream-netbsd/libc/stdlib/erand48.c \
+	upstream-netbsd/libc/stdlib/jrand48.c \
+	upstream-netbsd/libc/stdlib/lrand48.c \
+	upstream-netbsd/libc/stdlib/mrand48.c \
+	upstream-netbsd/libc/stdlib/nrand48.c \
+	upstream-netbsd/libc/stdlib/_rand48.c \
+	upstream-netbsd/libc/stdlib/srand48.c \
 	upstream-netbsd/libc/stdlib/tdelete.c \
 	upstream-netbsd/libc/stdlib/tfind.c \
 	upstream-netbsd/libc/stdlib/tsearch.c \
diff --git a/libc/private/rand48.h b/libc/private/rand48.h
index afa49f6..1ad8b0d 100644
--- a/libc/private/rand48.h
+++ b/libc/private/rand48.h
@@ -1,3 +1,5 @@
+/*	$NetBSD: rand48.h,v 1.6 2011/05/18 19:36:36 dsl Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -9,17 +11,17 @@
  * This software is provided ``as is'', and comes with no warranties
  * of any kind. I shall in no event be liable for anything that happens
  * to anyone/anything when using this software.
- *
- *	$OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $
  */
 
 #ifndef _RAND48_H_
 #define _RAND48_H_
 
-#include <math.h>
 #include <stdlib.h>
 
-void		__dorand48(unsigned short[3]);
+extern void		__dorand48(unsigned short[3]);
+extern unsigned short	__rand48_seed[3];
+extern unsigned short	__rand48_mult[3];
+extern unsigned short	__rand48_add;
 
 #define	RAND48_SEED_0	(0x330e)
 #define	RAND48_SEED_1	(0xabcd)
diff --git a/libc/stdlib/lrand48.c b/libc/stdlib/lrand48.c
deleted file mode 100644
index 21beb85..0000000
--- a/libc/stdlib/lrand48.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*	$OpenBSD: lrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
-/*
- * Copyright (c) 1993 Martin Birgmeier
- * All rights reserved.
- *
- * You may redistribute unmodified or modified versions of this source
- * code provided that the above copyright notice and this and the
- * following conditions are retained.
- *
- * This software is provided ``as is'', and comes with no warranties
- * of any kind. I shall in no event be liable for anything that happens
- * to anyone/anything when using this software.
- */
-
-#include "rand48.h"
-
-extern unsigned short __rand48_seed[3];
-
-long
-lrand48(void)
-{
-	__dorand48(__rand48_seed);
-	return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1);
-}
diff --git a/libc/stdlib/nrand48.c b/libc/stdlib/nrand48.c
deleted file mode 100644
index f1f548c..0000000
--- a/libc/stdlib/nrand48.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*	$OpenBSD: nrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
-/*
- * Copyright (c) 1993 Martin Birgmeier
- * All rights reserved.
- *
- * You may redistribute unmodified or modified versions of this source
- * code provided that the above copyright notice and this and the
- * following conditions are retained.
- *
- * This software is provided ``as is'', and comes with no warranties
- * of any kind. I shall in no event be liable for anything that happens
- * to anyone/anything when using this software.
- */
-
-#include "rand48.h"
-
-long
-nrand48(unsigned short xseed[3])
-{
-	__dorand48(xseed);
-	return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
-}
diff --git a/libc/stdlib/_rand48.c b/libc/upstream-netbsd/libc/stdlib/_rand48.c
similarity index 82%
rename from libc/stdlib/_rand48.c
rename to libc/upstream-netbsd/libc/stdlib/_rand48.c
index 7c950f7..0468026 100644
--- a/libc/stdlib/_rand48.c
+++ b/libc/upstream-netbsd/libc/stdlib/_rand48.c
@@ -1,4 +1,5 @@
-/*	$OpenBSD: _rand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
+/*	$NetBSD: _rand48.c,v 1.7 2005/06/12 05:21:27 lukem Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -12,6 +13,13 @@
  * to anyone/anything when using this software.
  */
 
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: _rand48.c,v 1.7 2005/06/12 05:21:27 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <assert.h>
+
 #include "rand48.h"
 
 unsigned short __rand48_seed[3] = {
@@ -32,6 +40,8 @@
 	unsigned long accu;
 	unsigned short temp[2];
 
+	_DIAGASSERT(xseed != NULL);
+
 	accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
 	 (unsigned long) __rand48_add;
 	temp[0] = (unsigned short) accu;	/* lower 16 bits */
diff --git a/libc/bionic/drand48.c b/libc/upstream-netbsd/libc/stdlib/drand48.c
similarity index 65%
rename from libc/bionic/drand48.c
rename to libc/upstream-netbsd/libc/stdlib/drand48.c
index 93272cf..6fba607 100644
--- a/libc/bionic/drand48.c
+++ b/libc/upstream-netbsd/libc/stdlib/drand48.c
@@ -1,3 +1,5 @@
+/*	$NetBSD: drand48.c,v 1.6 2005/06/12 05:21:28 lukem Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -12,10 +14,16 @@
  */
 
 #include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: drand48.c,v 1.6 2005/06/12 05:21:28 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
 
+#include "namespace.h"
 #include "rand48.h"
 
-extern unsigned short __rand48_seed[3];
+#ifdef __weak_alias
+__weak_alias(drand48,_drand48)
+#endif
 
 double
 drand48(void)
diff --git a/libc/bionic/erand48.c b/libc/upstream-netbsd/libc/stdlib/erand48.c
similarity index 64%
rename from libc/bionic/erand48.c
rename to libc/upstream-netbsd/libc/stdlib/erand48.c
index 4ecbead..f1d8b4d 100644
--- a/libc/bionic/erand48.c
+++ b/libc/upstream-netbsd/libc/stdlib/erand48.c
@@ -1,3 +1,5 @@
+/*	$NetBSD: erand48.c,v 1.9 2006/03/22 20:52:16 drochner Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -12,12 +14,27 @@
  */
 
 #include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: erand48.c,v 1.9 2006/03/22 20:52:16 drochner Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <math.h>
 
 #include "rand48.h"
 
+#ifdef __weak_alias
+__weak_alias(erand48,_erand48)
+#endif
+
 double
 erand48(unsigned short xseed[3])
 {
+
+	_DIAGASSERT(xseed != NULL);
+
 	__dorand48(xseed);
 	return ldexp((double) xseed[0], -48) +
 	       ldexp((double) xseed[1], -32) +
diff --git a/libc/stdlib/jrand48.c b/libc/upstream-netbsd/libc/stdlib/jrand48.c
similarity index 60%
rename from libc/stdlib/jrand48.c
rename to libc/upstream-netbsd/libc/stdlib/jrand48.c
index cb8c592..0ab594e 100644
--- a/libc/stdlib/jrand48.c
+++ b/libc/upstream-netbsd/libc/stdlib/jrand48.c
@@ -1,4 +1,5 @@
-/*	$OpenBSD: jrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
+/*	$NetBSD: jrand48.c,v 1.8 2005/06/12 05:21:28 lukem Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -12,11 +13,27 @@
  * to anyone/anything when using this software.
  */
 
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: jrand48.c,v 1.8 2005/06/12 05:21:28 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+
 #include "rand48.h"
 
+#ifdef __weak_alias
+__weak_alias(jrand48,_jrand48)
+#endif
+
 long
 jrand48(unsigned short xseed[3])
 {
+
+	_DIAGASSERT(xseed != NULL);
+
 	__dorand48(xseed);
 	return ((long) xseed[2] << 16) + (long) xseed[1];
 }
diff --git a/libc/upstream-netbsd/libc/stdlib/lrand48.c b/libc/upstream-netbsd/libc/stdlib/lrand48.c
new file mode 100644
index 0000000..78f869e
--- /dev/null
+++ b/libc/upstream-netbsd/libc/stdlib/lrand48.c
@@ -0,0 +1,34 @@
+/*	$NetBSD: lrand48.c,v 1.8 2005/06/12 05:21:28 lukem Exp $	*/
+
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: lrand48.c,v 1.8 2005/06/12 05:21:28 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include "rand48.h"
+
+#ifdef __weak_alias
+__weak_alias(lrand48,_lrand48)
+#endif
+
+long
+lrand48(void)
+{
+	__dorand48(__rand48_seed);
+	return (long)((unsigned long) __rand48_seed[2] << 15) +
+	    ((unsigned long) __rand48_seed[1] >> 1);
+}
diff --git a/libc/stdlib/mrand48.c b/libc/upstream-netbsd/libc/stdlib/mrand48.c
similarity index 64%
rename from libc/stdlib/mrand48.c
rename to libc/upstream-netbsd/libc/stdlib/mrand48.c
index 977264a..c787ce6 100644
--- a/libc/stdlib/mrand48.c
+++ b/libc/upstream-netbsd/libc/stdlib/mrand48.c
@@ -1,4 +1,5 @@
-/*	$OpenBSD: mrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
+/*	$NetBSD: mrand48.c,v 1.7 2005/06/12 05:21:28 lukem Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -12,9 +13,17 @@
  * to anyone/anything when using this software.
  */
 
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: mrand48.c,v 1.7 2005/06/12 05:21:28 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
 #include "rand48.h"
 
-extern unsigned short __rand48_seed[3];
+#ifdef __weak_alias
+__weak_alias(mrand48,_mrand48)
+#endif
 
 long
 mrand48(void)
diff --git a/libc/upstream-netbsd/libc/stdlib/nrand48.c b/libc/upstream-netbsd/libc/stdlib/nrand48.c
new file mode 100644
index 0000000..fc73185
--- /dev/null
+++ b/libc/upstream-netbsd/libc/stdlib/nrand48.c
@@ -0,0 +1,39 @@
+/*	$NetBSD: nrand48.c,v 1.9 2005/06/12 05:21:28 lukem Exp $	*/
+
+/*
+ * Copyright (c) 1993 Martin Birgmeier
+ * All rights reserved.
+ *
+ * You may redistribute unmodified or modified versions of this source
+ * code provided that the above copyright notice and this and the
+ * following conditions are retained.
+ *
+ * This software is provided ``as is'', and comes with no warranties
+ * of any kind. I shall in no event be liable for anything that happens
+ * to anyone/anything when using this software.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: nrand48.c,v 1.9 2005/06/12 05:21:28 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+
+#include "rand48.h"
+
+#ifdef __weak_alias
+__weak_alias(nrand48,_nrand48)
+#endif
+
+long
+nrand48(unsigned short xseed[3])
+{
+	_DIAGASSERT(xseed != NULL);
+
+	__dorand48(xseed);
+	return (long)((unsigned long) xseed[2] << 15) +
+	    ((unsigned long) xseed[1] >> 1);
+}
diff --git a/libc/stdlib/srand48.c b/libc/upstream-netbsd/libc/stdlib/srand48.c
similarity index 64%
rename from libc/stdlib/srand48.c
rename to libc/upstream-netbsd/libc/stdlib/srand48.c
index f76b6cc..a9673fe 100644
--- a/libc/stdlib/srand48.c
+++ b/libc/upstream-netbsd/libc/stdlib/srand48.c
@@ -1,4 +1,5 @@
-/*	$OpenBSD: srand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */
+/*	$NetBSD: srand48.c,v 1.7 2005/06/12 05:21:28 lukem Exp $	*/
+
 /*
  * Copyright (c) 1993 Martin Birgmeier
  * All rights reserved.
@@ -12,18 +13,24 @@
  * to anyone/anything when using this software.
  */
 
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: srand48.c,v 1.7 2005/06/12 05:21:28 lukem Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
 #include "rand48.h"
 
-extern unsigned short __rand48_seed[3];
-extern unsigned short __rand48_mult[3];
-extern unsigned short __rand48_add;
+#ifdef __weak_alias
+__weak_alias(srand48,_srand48)
+#endif
 
 void
 srand48(long seed)
 {
 	__rand48_seed[0] = RAND48_SEED_0;
 	__rand48_seed[1] = (unsigned short) seed;
-	__rand48_seed[2] = (unsigned short) (seed >> 16);
+	__rand48_seed[2] = (unsigned short) ((unsigned long)seed >> 16);
 	__rand48_mult[0] = RAND48_MULT_0;
 	__rand48_mult[1] = RAND48_MULT_1;
 	__rand48_mult[2] = RAND48_MULT_2;
diff --git a/tests/Android.mk b/tests/Android.mk
index 38f8ceb..259aced 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -23,6 +23,7 @@
     pthread_test.cpp \
     regex_test.cpp \
     stdio_test.cpp \
+    stdlib_test.cpp \
     string_test.cpp \
     stubs_test.cpp \
 
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
new file mode 100644
index 0000000..a9c62d4
--- /dev/null
+++ b/tests/stdlib_test.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 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 <gtest/gtest.h>
+
+#include <stdlib.h>
+
+TEST(stdlib, drand48) {
+  srand48(0x01020304);
+  EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
+  EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
+  EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
+  EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
+}
+
+TEST(stdlib, lrand48_random_rand) {
+  srand48(0x01020304);
+  EXPECT_EQ(1409163720, lrand48());
+  EXPECT_EQ(397769746, lrand48());
+  EXPECT_EQ(902267124, lrand48());
+  EXPECT_EQ(132366131, lrand48());
+
+#if __BIONIC__
+  // On bionic, random(3) is equivalent to lrand48...
+  srandom(0x01020304);
+  EXPECT_EQ(1409163720, random());
+  EXPECT_EQ(397769746, random());
+  EXPECT_EQ(902267124, random());
+  EXPECT_EQ(132366131, random());
+
+  // ...and rand(3) is the bottom 32 bits.
+  srand(0x01020304);
+  EXPECT_EQ(static_cast<int>(1409163720), rand());
+  EXPECT_EQ(static_cast<int>(397769746), rand());
+  EXPECT_EQ(static_cast<int>(902267124), rand());
+  EXPECT_EQ(static_cast<int>(132366131), rand());
+#endif
+}
+
+TEST(stdlib, mrand48) {
+  srand48(0x01020304);
+  EXPECT_EQ(-1476639856, mrand48());
+  EXPECT_EQ(795539493, mrand48());
+  EXPECT_EQ(1804534249, mrand48());
+  EXPECT_EQ(264732262, mrand48());
+}