overhaul the random stuff ;-)

This commit is contained in:
tg 2004-05-24 19:06:55 +00:00
parent bcd702035d
commit 712a3cc064
11 changed files with 142 additions and 68 deletions

View File

@ -1,11 +1,11 @@
# $MirBSD: Makefile,v 1.3 2004/05/23 12:47:00 tg Exp $
# $MirBSD: Makefile,v 1.4 2004/05/24 19:06:54 tg Exp $
# $OpenBSD: Makefile,v 1.18 2004/02/16 19:07:19 deraadt Exp $
PROG= ksh
SRCS= alloc.c c_ksh.c c_sh.c c_test.c c_ulimit.c edit.c emacs.c \
eval.c exec.c expr.c history.c io.c jobs.c lex.c mail.c \
main.c misc.c missing.c path.c shf.c syn.c table.c trap.c \
tree.c tty.c var.c version.c vi.c
main.c misc.c missing.c path.c rnd.c shf.c syn.c table.c \
trap.c tree.c tty.c var.c version.c vi.c
MAN= ksh.1 sh.1
CPPFLAGS+= -DHAVE_CONFIG_H -I. -DKSH

View File

@ -1,4 +1,4 @@
/* $MirBSD: conf-end.h,v 1.3 2004/05/24 16:35:08 tg Exp $ */
/* $MirBSD: conf-end.h,v 1.4 2004/05/24 19:06:54 tg Exp $ */
/* $OpenBSD: conf-end.h,v 1.2 1996/08/25 12:37:58 downsj Exp $ */
/* Include ksh features? */
@ -82,6 +82,14 @@
# undef JOBS /* if no JOB_SIGS, no job control support */
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#else
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif /* HAVE_SYS_TYPES_H */
#endif /* HAVE_SYS_PARAM_H */
/* pdksh assumes system calls return EINTR if a signal happened (this so
* the signal handler doesn't have to longjmp()). I don't know if this
* happens (or can be made to happen) with sigset() et. al. (the bsd41 signal

View File

@ -1,4 +1,4 @@
/* $MirBSD: config.h,v 1.8 2004/05/24 17:15:37 tg Exp $ */
/* $MirBSD: config.h,v 1.9 2004/05/24 19:06:54 tg Exp $ */
/* $OpenBSD: config.h,v 1.9 2003/10/22 07:40:38 jmc Exp $ */
/*
@ -248,12 +248,18 @@
/* Define if you have the nice function. */
#define HAVE_NICE 1
/* Define if you have the random function. */
#define HAVE_RANDOM 1
/* Define if you have the setrlimit function. */
#define HAVE_SETRLIMIT 1
/* Define if you have the sigsetjmp function. */
#define HAVE_SIGSETJMP 1
/* Define if you have the srandom function. */
#define HAVE_SRANDOM 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
@ -329,6 +335,9 @@
/* Define if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1

View File

@ -1,4 +1,4 @@
dnl $MirBSD: configure.in,v 1.5 2004/05/24 16:35:08 tg Exp $
dnl $MirBSD: configure.in,v 1.6 2004/05/24 19:06:54 tg Exp $
dnl
dnl Process this file with autoconf to produce a configure script
dnl
@ -26,8 +26,9 @@ dnl
AC_HEADER_DIRENT
KSH_UNISTD_H
KSH_TERM_CHECK
AC_CHECK_HEADERS(stddef.h stdlib.h string.h memory.h fcntl.h limits.h paths.h \
sys/param.h sys/resource.h values.h ulimit.h sys/time.h)
AC_CHECK_HEADERS(sys/param.h sys/types.h sys/resource.h sys/time.h \
stddef.h stdlib.h string.h limits.h paths.h \
memory.h fcntl.h values.h ulimit.h)
AC_HEADER_TIME
KSH_HEADER_SYS_WAIT
dnl
@ -73,8 +74,9 @@ KSH_MEMMOVE
KSH_MEMSET
AC_CHECK_FUNCS(arc4random arc4random_addrandom arc4random_push confstr \
dup2 flock getcwd getgroups getpagesize getrusage getwd killpg \
mkstemp nice setrlimit strcasecmp strerror strlcat strlcpy \
strstr sysconf tcsetpgrp ulimit valloc wait3 waitpid)
mkstemp nice random setrlimit srandom strcasecmp strerror \
strlcat strlcpy strstr sysconf tcsetpgrp ulimit valloc wait3 \
waitpid)
AC_CHECK_FUNCS(sigsetjmp _setjmp, break)
AC_FUNC_MMAP
KSH_FUNC_LSTAT

View File

@ -1,4 +1,4 @@
.\" $MirBSD: ksh.1tbl,v 1.25 2004/05/23 13:01:35 tg Exp $
.\" $MirBSD: ksh.1tbl,v 1.26 2004/05/24 19:06:54 tg Exp $
.\" $OpenBSD: ksh.1tbl,v 1.70 2004/05/09 06:07:42 otto Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
@ -1560,11 +1560,17 @@ if the shell doesn't know where it is.
A pseudo-random number generator.
Every time
.Ev RANDOM
is referenced, it is assigned the next random number in the range
is referenced, it is assigned a random number in the range
0\-32767.
The pseudo-random number generator is seeded via
Until the variable is written to, the
.Xr arc4random 3
if the function exists, else with a less random mechanism.
function is being used, after a write or if the function is not available,
.Xr random 3 ,
or, if that does not exist,
.Xr rand 3 ,
is being used.
On startup and fork, the value is seeded and the initial state of
not being written to initialised.
If a feedback function is provided, changed values are propagated
back to the arcfour random number generator.
.It Ev REPLY
@ -5125,7 +5131,10 @@ deleted and a new prompt to be printed.
.Xr wait 2 ,
.Xr getopt 3 ,
.Xr rand 3 ,
.Xr random 3 ,
.Xr signal 3 ,
.Xr srand 3 ,
.Xr srandom 3 ,
.Xr system 3 ,
.Xr environ 7
.Pp

13
main.c
View File

@ -1,4 +1,4 @@
/* $MirBSD: main.c,v 1.6 2004/04/27 19:59:56 tg Exp $ */
/* $MirBSD: main.c,v 1.7 2004/05/24 19:06:55 tg Exp $ */
/* $OpenBSD: main.c,v 1.26 2004/01/08 05:43:14 jmc Exp $ */
/*
@ -94,9 +94,6 @@ main(int argc, char *argv[])
char **wp;
struct env env;
pid_t ppid;
#ifdef KSH
long trnd;
#endif
#ifdef MEM_DEBUG
chmem_set_defaults("ct", 1);
@ -118,9 +115,6 @@ main(int argc, char *argv[])
argc = 1;
}
kshname = *argv;
#ifdef KSH
trnd = *((long *)kshname);
#endif
ainit(&aperm); /* initialize permanent Area */
@ -262,8 +256,9 @@ main(int argc, char *argv[])
ppid = getppid();
setint(global("PPID"), (long) ppid);
#ifdef KSH
trnd ^= ((long) (time((time_t *)0) * kshpid * ppid));
setint(global("RANDOM"), prng_seed(trnd));
rnd_seed( (*((long *)kshname))
^ ((long) (time(NULL) * kshpid * ppid)) );
setint(global("RANDOM"), rnd_get());
#endif /* KSH */
/* setstr can't fail here */
setstr(global(version_param), ksh_version, KSH_RETURN_ERROR);

5
misc.c
View File

@ -1,4 +1,4 @@
/* $MirBSD: misc.c,v 1.6 2004/04/17 00:47:19 tg Exp $ */
/* $MirBSD: misc.c,v 1.7 2004/05/24 19:06:55 tg Exp $ */
/* $OpenBSD: misc.c,v 1.20 2003/10/22 07:40:38 jmc Exp $ */
/*
@ -1268,9 +1268,6 @@ reset_nonblock(fd)
}
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif /* HAVE_SYS_PARAM_H */
#ifndef MAXPATHLEN
# define MAXPATHLEN PATH
#endif /* MAXPATHLEN */

View File

@ -1,4 +1,4 @@
/* $MirBSD: proto.h,v 1.2 2004/04/27 19:59:57 tg Exp $ */
/* $MirBSD: proto.h,v 1.3 2004/05/24 19:06:55 tg Exp $ */
/* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */
/*
@ -213,6 +213,10 @@ int make_path ARGS((const char *cwd, const char *file,
void simplify_path ARGS((char *path));
char *get_phys_path ARGS((const char *path));
void set_current_wd ARGS((char *path));
/* rnd.c */
long rnd_get ARGS((void));
void rnd_put ARGS((long));
void rnd_seed ARGS((long));
/* syn.c */
void initkeywords ARGS((void));
struct op * compile ARGS((Source *s));
@ -276,7 +280,6 @@ void change_random ARGS((void));
int array_ref_len ARGS((const char *cp));
char * arrayname ARGS((const char *str));
void set_array ARGS((const char *var, int reset, char **vals));
long prng_seed ARGS((long));
/* version.c */
/* vi.c: see edit.h */

85
rnd.c Normal file
View File

@ -0,0 +1,85 @@
/* $MirBSD: rnd.c,v 1.1 2004/05/24 19:06:55 tg Exp $
*-
* Copyright (c) 2004
* Thorsten Glaser <x86@ePost.de>
*
* Licensee is hereby permitted to deal in this work without restric-
* tion, including unlimited rights to use, publically perform, modi-
* fy, merge, distribute, sell, give away or sublicence, provided the
* above copyright notices, these terms and the disclaimer are retai-
* ned in all redistributions, or reproduced in accompanying documen-
* tation or other materials provided with binary redistributions.
*
* Licensor hereby provides this work "AS IS" and WITHOUT WARRANTY of
* any kind, expressed or implied, to the maximum extent permitted by
* applicable law, but with the warranty of being written without ma-
* licious intent or gross negligence; in no event shall an author or
* contributor be held liable for any direct, indirect or other dama-
* ge, however caused, arising in any way out of the usage of covered
* work, even if advised of the possibility of such damage.
*/
#include "sh.h"
#include "proto.h"
#ifndef HAVE_SRANDOM
#undef HAVE_RANDOM
#endif
#ifdef KSH
int rnd_state;
void
rnd_seed(long newval)
{
rnd_put(time(NULL) ^ (getpid() << 16) ^ newval);
rnd_state = 0;
}
long
rnd_get(void)
{
#ifdef HAVE_ARC4RANDOM
if (!rnd_state) {
return arc4random() & 0x7FFF;
} else
#endif
#ifdef HAVE_RANDOM
return random() & 0x7FFF;
#else
return rand();
#endif
}
void
rnd_put(long newval)
{
u_int32_t sv;
rnd_state = 1 | rnd_get();
sv = (((u_int32_t)rnd_get()) << (newval & 7)) ^ (u_int32_t)newval;
#if defined(HAVE_ARC4RANDOM_PUSH)
arc4random_push(sv);
#elif defined(HAVE_ARC4RANDOM_ADDRANDOM)
arc4random_addrandom(sv, 4);
#endif
#ifdef HAVE_ARC4RANDOM
sv ^= arc4random();
#endif
#ifdef HAVE_RANDOM
srandom(sv);
#else
srand(sv);
#endif
while (rnd_state) {
rnd_get();
rnd_state >>= 1;
}
rnd_state = 1;
}
#endif /* def KSH */

4
sh.h
View File

@ -1,4 +1,4 @@
/* $MirBSD: sh.h,v 1.7 2004/05/23 12:47:01 tg Exp $ */
/* $MirBSD: sh.h,v 1.8 2004/05/24 19:06:55 tg Exp $ */
/* $OpenBSD: sh.h,v 1.17 2004/05/10 16:28:47 pvalchev Exp $ */
/* $From: sh.h,v 1.2 1994/05/19 18:32:40 michael Exp michael $ */
@ -28,8 +28,6 @@ extern void * malloc ARGS((size_t));
extern void * realloc ARGS((void *, size_t));
extern int free ARGS((void *));
extern int exit ARGS((int));
extern int rand ARGS((void));
extern void srand ARGS((unsigned int));
extern int atoi ARGS((const char *));
#endif /* HAVE_STDLIB_H */

40
var.c
View File

@ -1,4 +1,4 @@
/* $MirBSD: var.c,v 1.5 2004/05/23 12:47:01 tg Exp $ */
/* $MirBSD: var.c,v 1.6 2004/05/24 19:06:55 tg Exp $ */
/* $OpenBSD: var.c,v 1.17 2004/05/08 19:42:35 deraadt Exp $ */
#include "sh.h"
@ -889,7 +889,7 @@ makenv()
void
change_random()
{
srand(prng_seed(rand() ^ time(NULL)));
rnd_seed(time(NULL) * getpid());
}
/*
@ -942,7 +942,7 @@ getspec(vp)
break;
case V_RANDOM:
vp->flag &= ~SPECIAL;
setint(vp, (long) (rand() & 0x7fff));
setint(vp, rnd_get());
vp->flag |= SPECIAL;
break;
#endif /* KSH */
@ -1044,8 +1044,7 @@ setspec(vp)
break;
case V_RANDOM:
vp->flag &= ~SPECIAL;
srand(prng_seed(((unsigned int)intval(vp))
^ ((unsigned long)rand() << 24)));
rnd_put(intval(vp));
vp->flag |= SPECIAL;
break;
case V_SECONDS:
@ -1236,34 +1235,3 @@ set_array(var, reset, vals)
setstr(vq, vals[i], KSH_RETURN_ERROR);
}
}
/* Return a seed PRNG value, and feed one back to arc4random */
long
prng_seed(val)
long val;
{
unsigned long i, j;
#ifdef HAVE_ARC4RANDOM
i = arc4random();
#else
i = ((long) (time((time_t *)0) * getpid()));
#endif
j = (rand() << 16) | rand();
i ^= val;
j ^= val;
#if defined(HAVE_ARC4RANDOM_PUSH)
arc4random_push(j);
#elif defined(HAVE_ARC4RANDOM_ADDRANDOM)
arc4random_addrandom((u_char *)(&j), sizeof (j));
#else
while (j) {
rand();
j >>= 1;
}
#endif
return i;
}