diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs
index 07125896274329cd95db96bdaf68e0c781e7a685..c69caa447ab40094b222ea88225d22560c8e1c04 100644
--- a/src/header/stdlib/mod.rs
+++ b/src/header/stdlib/mod.rs
@@ -628,9 +628,21 @@ pub unsafe extern "C" fn rand() -> c_int {
     }
 }
 
-// #[no_mangle]
-pub extern "C" fn rand_r(seed: *mut c_uint) -> c_int {
-    unimplemented!();
+#[no_mangle]
+pub unsafe extern "C" fn rand_r(seed: *mut c_uint) -> c_int {
+    if seed.is_null() {
+        errno::EINVAL
+    } else {
+        // set the type explicitly so this will fail if the array size for XorShiftRng changes
+        let seed_arr: [u8; 16] = mem::transmute([*seed; 16 / mem::size_of::<c_uint>()]);
+
+        let mut rng = XorShiftRng::from_seed(seed_arr);
+        let ret = rng.gen_range(0, RAND_MAX);
+
+        *seed = ret as _;
+
+        ret
+    }
 }
 
 // #[no_mangle]
diff --git a/tests/expected/stdlib/rand.stdout b/tests/expected/stdlib/rand.stdout
index 60210f3e9df671359f5045cc4dcd64ebe2d6e5f9..4e35003bf8c2569ba9b9223c9129efd63ffb239c 100644
--- a/tests/expected/stdlib/rand.stdout
+++ b/tests/expected/stdlib/rand.stdout
@@ -2,3 +2,7 @@
 201425341
 201425341
 67141780
+264204
+271585843
+264204
+271585843
diff --git a/tests/stdlib/rand.c b/tests/stdlib/rand.c
index 52908fae709db4375790716445eb3c56b903a935..29791888d8a0855660e8b1694b63083e11e914ce 100644
--- a/tests/stdlib/rand.c
+++ b/tests/stdlib/rand.c
@@ -31,4 +31,40 @@ int main(void) {
         puts("srand(1) doesn't work");
         exit(EXIT_FAILURE);
     }
+
+    // Ensure rand_r() fails with NULL input
+    if (rand_r(NULL) != EINVAL) {
+        puts("rand_r(NULL) doesn't return EINVAL");
+        exit(EXIT_FAILURE);
+    }
+
+    // Ensure rand_r() produces unique values
+    int seed = 259;
+    int rand_r_seed259_1 = rand_r((unsigned *)&seed);
+    printf("%d\n", rand_r_seed259_1);
+
+    int rand_r_seed259_2 = rand_r((unsigned *)&seed);
+    printf("%d\n", rand_r_seed259_2);
+
+    if (rand_r_seed259_1 == rand_r_seed259_2) {
+        puts("rand_r() fails to produce unique values");
+        exit(EXIT_FAILURE);
+    }
+
+    // Ensure rand_r() returns reproducible values
+    seed = 259;
+    int rand_r_seed259_1_2 = rand_r((unsigned *)&seed);
+    printf("%d\n", rand_r_seed259_1_2);
+
+    int rand_r_seed259_2_2 = rand_r((unsigned *)&seed);
+    printf("%d\n", rand_r_seed259_2_2);
+
+    if (rand_r_seed259_1 != rand_r_seed259_1_2
+        || rand_r_seed259_2 != rand_r_seed259_2_2)
+    {
+        puts("rand_r() is not reproducible");
+	exit(EXIT_FAILURE);
+    }
+
+    return 0;
 }