|
34 | 34 | #include <tmx.h>
|
35 | 35 | #include <regex.h>
|
36 | 36 | #include <math.h>
|
| 37 | +#include <ast_random.h> |
37 | 38 | #include "variables.h"
|
38 | 39 | #include "path.h"
|
39 | 40 | #include "fault.h"
|
@@ -202,6 +203,7 @@ typedef struct _init_
|
202 | 203 | Namfun_t OPTINDEX_init;
|
203 | 204 | Namfun_t SECONDS_init;
|
204 | 205 | struct rand RAND_init;
|
| 206 | + Namfun_t SRAND_init; |
205 | 207 | Namfun_t LINENO_init;
|
206 | 208 | Namfun_t L_ARG_init;
|
207 | 209 | Namfun_t SH_VERSION_init;
|
@@ -716,15 +718,42 @@ static char* get_rand(Namval_t* np, Namfun_t *fp)
|
716 | 718 |
|
717 | 719 | void sh_reseed_rand(struct rand *rp)
|
718 | 720 | {
|
719 |
| - struct tms tp; |
720 |
| - unsigned int time; |
721 |
| - static unsigned int seq; |
722 |
| - timeofday(&tp); |
723 |
| - time = (unsigned int)remainder(dtime(&tp) * 10000.0, (double)UINT_MAX); |
724 |
| - srand(rp->rand_seed = (unsigned int)sh.current_pid ^ time ^ ++seq); |
| 721 | + srand(rp->rand_seed = arc4random()); |
725 | 722 | rp->rand_last = -1;
|
726 | 723 | }
|
727 | 724 |
|
| 725 | +/* |
| 726 | + * The following three functions are for SRANDOM |
| 727 | + */ |
| 728 | +static uint32_t srand_upper_bound; |
| 729 | + |
| 730 | +static void put_srand(Namval_t* np,const char *val,int flags,Namfun_t *fp) |
| 731 | +{ |
| 732 | + if(!val) /* unset */ |
| 733 | + { |
| 734 | + fp = nv_stack(np, NULL); |
| 735 | + if(fp && !fp->nofree) |
| 736 | + free(fp); |
| 737 | + _nv_unset(np,NV_RDONLY); |
| 738 | + return; |
| 739 | + } |
| 740 | + if(flags&NV_INTEGER) |
| 741 | + srand_upper_bound = *(Sfdouble_t*)val; |
| 742 | + else |
| 743 | + srand_upper_bound = sh_arith(val); |
| 744 | +} |
| 745 | + |
| 746 | +static Sfdouble_t nget_srand(Namval_t* np, Namfun_t *fp) |
| 747 | +{ |
| 748 | + return (Sfdouble_t)(srand_upper_bound ? arc4random_uniform(srand_upper_bound) : arc4random()); |
| 749 | +} |
| 750 | + |
| 751 | +static char* get_srand(Namval_t* np, Namfun_t *fp) |
| 752 | +{ |
| 753 | + intmax_t n = (intmax_t)(srand_upper_bound ? arc4random_uniform(srand_upper_bound) : arc4random()); |
| 754 | + return fmtbase(n, 10, 0); |
| 755 | +} |
| 756 | + |
728 | 757 | /*
|
729 | 758 | * These three routines are for LINENO
|
730 | 759 | */
|
@@ -1025,6 +1054,7 @@ static const Namdisc_t HISTFILE_disc = { sizeof(Namfun_t), put_history };
|
1025 | 1054 | static const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex };
|
1026 | 1055 | static const Namdisc_t SECONDS_disc = { sizeof(Namfun_t), put_seconds, get_seconds, nget_seconds };
|
1027 | 1056 | static const Namdisc_t RAND_disc = { sizeof(struct rand), put_rand, get_rand, nget_rand };
|
| 1057 | +static const Namdisc_t SRAND_disc = { sizeof(Namfun_t), put_srand, get_srand, nget_srand }; |
1028 | 1058 | static const Namdisc_t LINENO_disc = { sizeof(Namfun_t), put_lineno, get_lineno, nget_lineno };
|
1029 | 1059 | static const Namdisc_t L_ARG_disc = { sizeof(Namfun_t), put_lastarg, get_lastarg };
|
1030 | 1060 |
|
@@ -1837,6 +1867,8 @@ static Init_t *nv_init(void)
|
1837 | 1867 | ip->SECONDS_init.nofree = 1;
|
1838 | 1868 | ip->RAND_init.hdr.disc = &RAND_disc;
|
1839 | 1869 | ip->RAND_init.hdr.nofree = 1;
|
| 1870 | + ip->SRAND_init.disc = &SRAND_disc; |
| 1871 | + ip->SRAND_init.nofree = 1; |
1840 | 1872 | ip->SH_MATCH_init.hdr.disc = &SH_MATCH_disc;
|
1841 | 1873 | ip->SH_MATCH_init.hdr.nofree = 1;
|
1842 | 1874 | ip->SH_MATH_init.disc = &SH_MATH_disc;
|
@@ -1880,6 +1912,7 @@ static Init_t *nv_init(void)
|
1880 | 1912 | nv_putval(SECONDS, (char*)&d, NV_DOUBLE);
|
1881 | 1913 | nv_stack(RANDNOD, &ip->RAND_init.hdr);
|
1882 | 1914 | nv_putval(RANDNOD, (char*)&d, NV_DOUBLE);
|
| 1915 | + nv_stack(SRANDNOD, &ip->SRAND_init); |
1883 | 1916 | sh_invalidate_rand_seed();
|
1884 | 1917 | nv_stack(LINENO, &ip->LINENO_init);
|
1885 | 1918 | SH_MATCHNOD->nvfun = &ip->SH_MATCH_init.hdr;
|
|
0 commit comments