]> git.kaiwu.me - njs.git/commitdiff
Math.random() method.
authorIgor Sysoev <igor@sysoev.ru>
Wed, 23 Mar 2016 12:49:46 +0000 (15:49 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Wed, 23 Mar 2016 12:49:46 +0000 (15:49 +0300)
31 files changed:
Makefile
njs/njs_array.c
njs/njs_boolean.c
njs/njs_builtin.c
njs/njs_disassembler.c
njs/njs_extern.c
njs/njs_function.c
njs/njs_generator.c
njs/njs_lexer.c
njs/njs_lexer_keyword.c
njs/njs_math.c
njs/njs_nonrecursive_parser.c
njs/njs_number.c
njs/njs_object.c
njs/njs_parser.c
njs/njs_parser_expression.c
njs/njs_regexp.c
njs/njs_string.c
njs/njs_variable.c
njs/njs_vm.c
njs/njs_vm.h
njs/njscript.c
njs/test/njs_unit_test.c
nxt/Makefile
nxt/auto/configure
nxt/auto/getrandom [new file with mode: 0644]
nxt/nxt_random.c [new file with mode: 0644]
nxt/nxt_random.h [new file with mode: 0644]
nxt/nxt_types.h
nxt/test/Makefile
nxt/test/random_unit_test.c [new file with mode: 0644]

index 168795b3dbcf0c40de1f4491fd74947afa7941e2..cf02682d3938657982d8f253243271d54fbfd76d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -34,6 +34,7 @@ $(NXT_BUILDDIR)/libnjs.a: \
        $(NXT_BUILDDIR)/nxt_array.o \
        $(NXT_BUILDDIR)/nxt_rbtree.o \
        $(NXT_BUILDDIR)/nxt_lvlhsh.o \
+       $(NXT_BUILDDIR)/nxt_random.o \
        $(NXT_BUILDDIR)/nxt_malloc.o \
        $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
 
@@ -63,6 +64,7 @@ $(NXT_BUILDDIR)/libnjs.a: \
                $(NXT_BUILDDIR)/nxt_array.o \
                $(NXT_BUILDDIR)/nxt_rbtree.o \
                $(NXT_BUILDDIR)/nxt_lvlhsh.o \
+               $(NXT_BUILDDIR)/nxt_random.o \
                $(NXT_BUILDDIR)/nxt_malloc.o \
                $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
 
@@ -370,12 +372,14 @@ $(NXT_BUILDDIR)/njs_disassembler.o: \
                njs/njs_disassembler.c
 
 $(NXT_BUILDDIR)/njs_unit_test: \
+       $(NXT_BUILDDIR)/libnxt.a \
        $(NXT_BUILDDIR)/libnjs.a \
        njs/test/njs_unit_test.c \
 
        $(NXT_CC) -o $(NXT_BUILDDIR)/njs_unit_test $(NXT_CFLAGS) \
                -I$(NXT_LIB) -Injs \
                njs/test/njs_unit_test.c \
-               $(NXT_BUILDDIR)/libnjs.a -lm $(NXT_PCRE_LIB)
+               $(NXT_BUILDDIR)/libnjs.a \
+               -lm $(NXT_PCRE_LIB)
 
 include $(NXT_LIB)/Makefile
index 35d4b01bad8d00ef4fa070f0ab121a222277d97a..8fdf974f4ad2f3f50a70d85e1c20174556272147 100644 (file)
@@ -11,6 +11,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 13ca020dc9ae9ed106ebb6d5fd96cf528250b54b..8c89708d1805e2d8a3bfb58571daa7e4d2a6a18f 100644 (file)
@@ -9,6 +9,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 965d455962df37be3a938bc8d31b944dc8c1490d..90a43ab5f1f70d17d6e4d845acc54b221fdad580 100644 (file)
@@ -9,6 +9,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index a75608d30cacc678ecc9a671782c081e2581723b..748ec8bf13da06ef4bdb795f695efc41db80ed27 100644 (file)
@@ -9,6 +9,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 11e2358d9a98844ac82084ccb5291036c852f5af..fd48abdca770401c051dc79dc4fd08ef8425cd36 100644 (file)
@@ -12,6 +12,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 058da84fdc7d5cbf8193f530f892dca270a77504..d35a8d0257ca9e5c70797f812a8f6ee30b5813db 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 2cbfa542090c45411b3a13a794a8c9abd48d61c6..42f28c944215475a775666f7a91f35c0e8ea9fe4 100644 (file)
@@ -9,6 +9,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 3cf5ed4b1141909e1e7a15b724864d23259dff01..d3d5cb6672de1bd69c3d0a4ab2f686544e12982a 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index ff9c5c88afb5f364c833d812fe96d22e3e4c2dda..dabf10a1400d3a33b2c6953daa10a7c580f9a65b 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 7beada50c48047cfb7c20710268c1b420bdf5ec2..1473e3d04af88b4803669d9525fa2a484d64ec5b 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
 #include <nxt_mem_cache_pool.h>
+#include <nxt_random.h>
 #include <njscript.h>
 #include <njs_vm.h>
 #include <njs_number.h>
@@ -297,6 +298,20 @@ njs_object_math_pow(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
 }
 
 
+static njs_ret_t
+njs_object_math_random(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    double  num;
+
+    num = nxt_random(&vm->random) / 4294967296.0;
+
+    njs_number_set(&vm->retval, num);
+
+    return NXT_OK;
+}
+
+
 static njs_ret_t
 njs_object_math_round(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
@@ -518,6 +533,12 @@ static const njs_object_prop_t  njs_math_object_properties[] =
                      NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
     },
 
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("random"),
+        .value = njs_native_function(njs_object_math_random, 0, ),
+    },
+
     {
         .type = NJS_METHOD,
         .name = njs_string("round"),
index 9591a05ba616def453cfc443cf3b3108d8631077..b92c0ba447cc995bcbcc9b839ecd0dde17a65039 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index b7775a771324aa2b61ab51fea4850f6eda548cbe..f5c66422fafa56147625bda2e6b811bf0af2257c 100644 (file)
@@ -9,6 +9,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
@@ -163,7 +164,7 @@ njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
     const njs_value_t *number)
 {
     u_char             *p;
-    double             num;
+    double             n, num;
     size_t             size;
     const char         *fmt;
     const njs_value_t  *value;
@@ -184,10 +185,18 @@ njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
         }
 
     } else {
-        if (fabs(num) < 1000000) {
+        n = fabs(num);
+
+        if (n == 0) {
+            fmt = "%g";
+
+        } else if (n < 1) {
+            fmt = "%f";
+
+        } else if (n < 1000000) {
             fmt = "%g";
 
-        } else if (fabs(num) < 1e20) {
+        } else if (n < 1e20) {
             fmt = "%1.f";
 
         } else {
index 71f312f777e66067a5738ed0b300ebad0fa2c55d..a4f1d649f0929800927dc34923bb76af0894bd5b 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 636c0ef321f1cfeb922c972fcbe10a5cc688faba..c858f96ae52d712f5779370f4a09684bf61eeafa 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_utf8.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 1a1f7ef1d235a6f4b4d89822816cb7293e25c0f2..11bc6d8b6108e5bfa587e97a133ad557bd949a4a 100644 (file)
@@ -11,6 +11,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 608a2f4564c1f260c549b35f85ab28c01c575c0f..7181558718839a3de2f158480a83b3511a7a7922 100644 (file)
@@ -13,6 +13,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_malloc.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
index 42ab6444a7ec63b99d60cf6e0aeb32df52aac482..6873907c32ec0d3977ef4d81035af72cbff6c657 100644 (file)
@@ -13,6 +13,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_malloc.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
index 5deb7135071882723c989fc5dffa95a1a77d6445..00e34e32c00c5ef69969ce6fd242c43ed1c8acff 100644 (file)
@@ -12,6 +12,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 9d1df6df41ad5e80a0670a2535264422fb0df4e6..71d1898a6615d26d5f2f81965e2adc8bb38ae49d 100644 (file)
@@ -11,6 +11,7 @@
 #include <nxt_djb_hash.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
 #include <njs_vm.h>
index 19a822aa90e46e4cbf88994cc54af68780c9c038..acb5a3969a2edcbd76d98a47681e1eea31ef9b3b 100644 (file)
@@ -774,6 +774,8 @@ struct njs_vm_s {
     njs_regexp_pattern_t     *pattern;
 
     nxt_array_t              *code;  /* of njs_vm_code_t */
+
+    nxt_random_t             random;
 };
 
 
index 9d0823d5a1c481d9cabb8cd86ce38b8aff0a0f5d..ef41b2e7912add25776f8666f4c20528f4c4cd25 100644 (file)
@@ -10,6 +10,7 @@
 #include <nxt_stub.h>
 #include <nxt_array.h>
 #include <nxt_lvlhsh.h>
+#include <nxt_random.h>
 #include <nxt_malloc.h>
 #include <nxt_mem_cache_pool.h>
 #include <njscript.h>
index 2ac4b13374e2f71e34646696171378676ad1b33c..9e3313bd5e0222088d8204b0cad5a58d022a470b 100644 (file)
@@ -3919,12 +3919,6 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Math.PI"),
       nxt_string("3.14159") },
 
-    { nxt_string("Math.E"),
-      nxt_string("2.71828") },
-
-    { nxt_string("Math.SQRT2"),
-      nxt_string("1.41421") },
-
     { nxt_string("Math.abs(5)"),
       nxt_string("5") },
 
@@ -3970,7 +3964,8 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Math.pow()"),
       nxt_string("NaN") },
 
-    /* ES5: Must be "[object Math]". */
+    /* ES5FIX: "[object Math]". */
+
     { nxt_string("Math"),
       nxt_string("[object Object]") },
 
index 19ae2483bd4869de3c09828232864865d0471b5d..7f9fb31d586611867a085f08121209a5d5318a87 100644 (file)
@@ -9,6 +9,7 @@ $(NXT_BUILDDIR)/libnxt.a: \
        $(NXT_BUILDDIR)/nxt_queue.o \
        $(NXT_BUILDDIR)/nxt_rbtree.o \
        $(NXT_BUILDDIR)/nxt_lvlhsh.o \
+       $(NXT_BUILDDIR)/nxt_random.o \
        $(NXT_BUILDDIR)/nxt_malloc.o \
        $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
 
@@ -19,6 +20,7 @@ $(NXT_BUILDDIR)/libnxt.a: \
                $(NXT_BUILDDIR)/nxt_rbtree.o \
                $(NXT_BUILDDIR)/nxt_lvlhsh.o \
                $(NXT_BUILDDIR)/nxt_malloc.o \
+               $(NXT_BUILDDIR)/nxt_random.o \
                $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
 
 $(NXT_BUILDDIR)/nxt_murmur_hash.o: \
@@ -102,6 +104,16 @@ $(NXT_BUILDDIR)/nxt_malloc.o: \
                -I$(NXT_LIB) \
                $(NXT_LIB)/nxt_malloc.c
 
+$(NXT_BUILDDIR)/nxt_random.o: \
+       $(NXT_LIB)/nxt_types.h \
+       $(NXT_LIB)/nxt_clang.h \
+       $(NXT_LIB)/nxt_random.h \
+       $(NXT_LIB)/nxt_random.c \
+
+       $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_random.o $(NXT_CFLAGS) \
+               -I$(NXT_LIB) \
+               $(NXT_LIB)/nxt_random.c
+
 $(NXT_BUILDDIR)/nxt_mem_cache_pool.o: \
        $(NXT_LIB)/nxt_types.h \
        $(NXT_LIB)/nxt_clang.h \
index 305d0d5360eb7226d12154e36457302679ac07b5..fdb93d03524090107854560017190eb942b69fe1 100755 (executable)
@@ -52,4 +52,5 @@ END
 . ${NXT_AUTO}os
 . ${NXT_AUTO}clang
 . ${NXT_AUTO}memalign
+. ${NXT_AUTO}getrandom
 . ${NXT_AUTO}pcre
diff --git a/nxt/auto/getrandom b/nxt/auto/getrandom
new file mode 100644 (file)
index 0000000..9f94fbd
--- /dev/null
@@ -0,0 +1,24 @@
+
+# Copyright (C) Igor Sysoev
+# Copyright (C) NGINX, Inc.
+
+
+# Linux 3.17 getrandom().
+
+nxt_feature="getrandom()"
+nxt_feature_name=NXT_HAVE_GETRANDOM
+nxt_feature_run=
+nxt_feature_incs=
+nxt_feature_libs=
+nxt_feature_test="#include <unistd.h>
+                  #include <sys/syscall.h>
+                  #include <linux/random.h>
+
+                  int main() {
+                      char  buf[4];
+
+                      (void) syscall(SYS_getrandom, buf, 4, 0);
+
+                      return 0;
+                  }"
+. ${NXT_AUTO}feature
diff --git a/nxt/nxt_random.c b/nxt/nxt_random.c
new file mode 100644 (file)
index 0000000..8f8bedf
--- /dev/null
@@ -0,0 +1,179 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <nxt_types.h>
+#include <nxt_clang.h>
+#include <nxt_random.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <unistd.h>
+#if (NXT_HAVE_GETRANDOM)
+#include <sys/syscall.h>
+#include <linux/random.h>
+#endif
+
+
+/*
+ * The pseudorandom generator based on OpenBSD arc4random.  Although
+ * it is usually stated that arc4random uses RC4 pseudorandom generation
+ * algorithm they are actually different in nxt_random_add().
+ */
+
+
+#define NXT_RANDOM_KEY_SIZE  128
+
+
+nxt_inline uint8_t nxt_random_byte(nxt_random_t *r);
+
+
+void
+nxt_random_init(nxt_random_t *r, nxt_pid_t pid)
+{
+    nxt_uint_t  i;
+
+    r->count = 0;
+    r->pid = pid;
+    r->i = 0;
+    r->j = 0;
+
+    for (i = 0; i < 256; i++) {
+        r->s[i] = i;
+    }
+}
+
+
+void
+nxt_random_stir(nxt_random_t *r, nxt_pid_t pid)
+{
+    int             fd;
+    ssize_t         n;
+    struct timeval  tv;
+    union {
+        uint32_t    value[3];
+        u_char      bytes[NXT_RANDOM_KEY_SIZE];
+    } key;
+
+    if (r->pid == 0) {
+        nxt_random_init(r, pid);
+    }
+
+    r->pid = pid;
+
+    n = 0;
+
+#if (NXT_HAVE_GETRANDOM)
+
+    /* Linux 3.17 getrandom(), it is not available in Glibc. */
+
+    n = syscall(SYS_getrandom, key, NXT_RANDOM_KEY_SIZE, 0));
+
+#endif
+
+    if (n != NXT_RANDOM_KEY_SIZE) {
+        fd = open("/dev/urandom", O_RDONLY);
+
+        if (fd >= 0) {
+            n = read(fd, &key, NXT_RANDOM_KEY_SIZE);
+            (void) close(fd);
+        }
+    }
+
+    if (n != NXT_RANDOM_KEY_SIZE) {
+        (void) gettimeofday(&tv, NULL);
+
+        /* XOR with stack garbage. */
+
+        key.value[0] ^= tv.tv_usec;
+        key.value[1] ^= tv.tv_sec;
+        key.value[2] ^= getpid();
+    }
+
+    nxt_random_add(r, key.bytes, NXT_RANDOM_KEY_SIZE);
+
+    /* Drop the first 3072 bytes. */
+    for (n = 3072; n != 0; n--) {
+        (void) nxt_random_byte(r);
+    }
+
+    /* Stir again after 1,600,000 bytes. */
+    r->count = 400000;
+}
+
+
+void
+nxt_random_add(nxt_random_t *r, const u_char *key, uint32_t len)
+{
+    uint8_t   val;
+    uint32_t  n;
+
+    for (n = 0; n < 256; n++) {
+        val = r->s[r->i];
+        r->j += val + key[n % len];
+
+        r->s[r->i] = r->s[r->j];
+        r->s[r->j] = val;
+
+        r->i++;
+    }
+
+    /* This index is not decremented in RC4 algorithm. */
+    r->i--;
+
+    r->j = r->i;
+}
+
+
+uint32_t
+nxt_random(nxt_random_t *r)
+{
+    uint32_t    val;
+    nxt_pid_t   pid;
+    nxt_bool_t  new_pid;
+
+    new_pid = 0;
+    pid = r->pid;
+
+    if (pid != -1) {
+        pid = getpid();
+
+        if (pid != r->pid) {
+            new_pid = 1;
+        }
+    }
+
+    r->count--;
+
+    if (r->count <= 0 || new_pid) {
+        nxt_random_stir(r, pid);
+    }
+
+    val  = nxt_random_byte(r) << 24;
+    val |= nxt_random_byte(r) << 16;
+    val |= nxt_random_byte(r) << 8;
+    val |= nxt_random_byte(r);
+
+    return val;
+}
+
+
+nxt_inline uint8_t
+nxt_random_byte(nxt_random_t *r)
+{
+    uint8_t  si, sj;
+
+    r->i++;
+    si = r->s[r->i];
+    r->j += si;
+
+    sj = r->s[r->j];
+    r->s[r->i] = sj;
+    r->s[r->j] = si;
+
+    si += sj;
+
+    return r->s[si];
+}
diff --git a/nxt/nxt_random.h b/nxt/nxt_random.h
new file mode 100644 (file)
index 0000000..caa4ddb
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) NGINX, Inc.
+ */
+
+#ifndef _NXT_RANDOM_H_INCLUDED_
+#define _NXT_RANDOM_H_INCLUDED_
+
+
+typedef struct {
+    int32_t    count;
+    nxt_pid_t  pid;
+    uint8_t    i;
+    uint8_t    j;
+    uint8_t    s[256];
+} nxt_random_t;
+
+
+/*
+ * The nxt_random_t structure must be either initialized with zeros
+ * or initialized by nxt_random_init() function.  The later is intended
+ * mainly for unit test.  nxt_random() automatically stirs itself if
+ * process pid changed after fork().  This pid testing can be disabled by
+ * passing -1 as the pid argument to nxt_random_init() or nxt_random_stir()
+ * functions.  The testing can be later enabled by passing any positive
+ * number, for example, a real pid number.
+ */
+
+NXT_EXPORT void nxt_random_init(nxt_random_t *r, nxt_pid_t pid);
+NXT_EXPORT void nxt_random_stir(nxt_random_t *r, nxt_pid_t pid);
+NXT_EXPORT void nxt_random_add(nxt_random_t *r, const u_char *key,
+    uint32_t len);
+NXT_EXPORT uint32_t nxt_random(nxt_random_t *r);
+
+
+#endif /* _NXT_RANDOM_H_INCLUDED_ */
index acf13281c1c85d5c64f9fa294564a8da98a2d85c..0b28cf4e65e2e36b347b97bf749665dfd3702e94 100644 (file)
@@ -90,4 +90,7 @@ typedef time_t         nxt_time_t;
 #endif
 
 
+typedef pid_t          nxt_pid_t;
+
+
 #endif /* _NXT_TYPES_H_INCLUDED_ */
index 2a085b144986fc62891e51273f9e06a3e101a059..08288b57b1fe197ebdd505b2bfd9088ebc707a33 100644 (file)
@@ -1,9 +1,11 @@
 
 lib_test: \
+       $(NXT_BUILDDIR)/random_unit_test \
        $(NXT_BUILDDIR)/rbtree_unit_test \
        $(NXT_BUILDDIR)/lvlhsh_unit_test \
        $(NXT_BUILDDIR)/utf8_unit_test \
 
+       $(NXT_BUILDDIR)/random_unit_test
        $(NXT_BUILDDIR)/rbtree_unit_test
        $(NXT_BUILDDIR)/lvlhsh_unit_test
        $(NXT_BUILDDIR)/utf8_unit_test
@@ -43,3 +45,12 @@ $(NXT_BUILDDIR)/lvlhsh_unit_test: \
                $(NXT_BUILDDIR)/nxt_murmur_hash.o \
                $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \
                $(NXT_BUILDDIR)/nxt_malloc.o
+
+$(NXT_BUILDDIR)/random_unit_test: \
+       $(NXT_BUILDDIR)/nxt_random.o \
+       $(NXT_LIB)/test/random_unit_test.c \
+
+       $(NXT_CC) -o $(NXT_BUILDDIR)/random_unit_test $(NXT_CFLAGS) \
+               -I$(NXT_LIB) \
+               $(NXT_LIB)/test/random_unit_test.c \
+               $(NXT_BUILDDIR)/nxt_random.o
diff --git a/nxt/test/random_unit_test.c b/nxt/test/random_unit_test.c
new file mode 100644 (file)
index 0000000..ef721d1
--- /dev/null
@@ -0,0 +1,60 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) NGINX, Inc.
+ */
+
+#include <nxt_types.h>
+#include <nxt_clang.h>
+#include <nxt_stub.h>
+#include <nxt_random.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static nxt_int_t
+random_unit_test()
+{
+    nxt_uint_t    n;
+    nxt_random_t  r;
+
+    nxt_random_init(&r, -1);
+
+    r.count = 400000;
+
+    nxt_random_add(&r, (u_char *) "arc4random", sizeof("arc4random") - 1);
+
+    /*
+     * Test arc4random() numbers.
+     * RC4 pseudorandom numbers would be 0x4642AFC3 and 0xBAF0FFF0.
+     */
+
+    if (nxt_random(&r) == 0xD6270B27) {
+
+        for (n = 100000; n != 0; n--) {
+            (void) nxt_random(&r);
+        }
+
+        if (nxt_random(&r) == 0x6FCAE186) {
+            printf("random unit test passed\n");
+
+            nxt_random_stir(&r, getpid());
+
+            printf("random unit test: 0x%08X\n", nxt_random(&r));
+
+            return NXT_OK;
+        }
+    }
+
+    printf("random unit test failed\n");
+
+    return NXT_ERROR;
+}
+
+
+int
+main(void)
+{
+    return random_unit_test();
+}