diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-11-26 12:23:30 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-11-26 12:23:30 +0100 |
commit | 07e4a197953d12902fb97beb48830a5323a52280 (patch) | |
tree | 2606081e24020a6d9985531651099b0fc2aa3381 /src/evalfunc.c | |
parent | 06b0b4bc27077013e9b4b48fd1d9b33e543ccf99 (diff) | |
download | vim-git-07e4a197953d12902fb97beb48830a5323a52280.tar.gz |
patch 8.1.2343: using time() for srand() is not very randomv8.1.2343
Problem: Using time() for srand() is not very random.
Solution: use /dev/urandom if available
Diffstat (limited to 'src/evalfunc.c')
-rw-r--r-- | src/evalfunc.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index a3e5b3e38..c6e4679e5 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -7095,10 +7095,45 @@ f_sqrt(typval_T *argvars, typval_T *rettv) static void f_srand(typval_T *argvars, typval_T *rettv) { + static int dev_urandom_state = -1; // FAIL or OK once tried + if (rettv_list_alloc(rettv) == FAIL) return; if (argvars[0].v_type == VAR_UNKNOWN) - list_append_number(rettv->vval.v_list, (varnumber_T)vim_time()); + { + if (dev_urandom_state != FAIL) + { + int fd = open("/dev/urandom", O_RDONLY); + struct { + union { + UINT32_T number; + char bytes[sizeof(UINT32_T)]; + } cont; + } buf; + + // Attempt reading /dev/urandom. + if (fd == -1) + dev_urandom_state = FAIL; + else + { + buf.cont.number = 0; + if (read(fd, buf.cont.bytes, sizeof(UINT32_T)) + != sizeof(UINT32_T)) + dev_urandom_state = FAIL; + else + { + dev_urandom_state = OK; + list_append_number(rettv->vval.v_list, + (varnumber_T)buf.cont.number); + } + close(fd); + } + + } + if (dev_urandom_state != OK) + // Reading /dev/urandom doesn't work, fall back to time(). + list_append_number(rettv->vval.v_list, (varnumber_T)vim_time()); + } else { int error = FALSE; @@ -7107,7 +7142,7 @@ f_srand(typval_T *argvars, typval_T *rettv) if (error) return; - list_append_number(rettv->vval.v_list, x); + list_append_number(rettv->vval.v_list, (varnumber_T)x); } list_append_number(rettv->vval.v_list, 362436069); list_append_number(rettv->vval.v_list, 521288629); |