diff options
author | seanc <seanc@FreeBSD.org> | 2003-02-11 19:32:18 +0000 |
---|---|---|
committer | seanc <seanc@FreeBSD.org> | 2003-02-11 19:32:18 +0000 |
commit | 0f9b087524425d34260b48dfe452fe59123a8921 (patch) | |
tree | 097b8974b8e346530a10af46d5f0dba419e30286 /games/random/random.c | |
parent | 978695f103a5c784ac63a0337e502e29660341f3 (diff) | |
download | FreeBSD-src-0f9b087524425d34260b48dfe452fe59123a8921.zip FreeBSD-src-0f9b087524425d34260b48dfe452fe59123a8921.tar.gz |
Update random(6) to have the ability to randomize a file/stdin based
off of lines or words. See the man page for details.
Reviewed by: markm
MFC after: 3 days
Diffstat (limited to 'games/random/random.c')
-rw-r--r-- | games/random/random.c | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/games/random/random.c b/games/random/random.c index 9c66da4..f0d5df3 100644 --- a/games/random/random.c +++ b/games/random/random.c @@ -52,33 +52,60 @@ static const char rcsid[] = #include <err.h> #include <errno.h> +#include <fcntl.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> +#include "randomize_fd.h" void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { double denom; - int ch, random_exit, selected, unbuffer_output; - char *ep; + int ch, fd, random_exit, randomize_lines, random_type, ret, + selected, unique_output, unbuffer_output; + char *ep, *filename; - random_exit = unbuffer_output = 0; denom = 0; - while ((ch = getopt(argc, argv, "er")) != -1) + filename = NULL; + random_type = RANDOM_TYPE_UNSET; + random_exit = randomize_lines = random_type = unbuffer_output = 0; + unique_output = 1; + while ((ch = getopt(argc, argv, "ef:hlruUw")) != -1) switch (ch) { case 'e': random_exit = 1; break; + case 'f': + randomize_lines = 1; + if (!strcmp(optarg, "-")) + filename = strdup("/dev/fd/0"); + else + filename = optarg; + break; + case 'l': + randomize_lines = 1; + random_type = RANDOM_TYPE_LINES; + break; case 'r': unbuffer_output = 1; break; + case 'u': + randomize_lines = 1; + unique_output = 1; + break; + case 'U': + randomize_lines = 1; + unique_output = 0; + break; + case 'w': + randomize_lines = 1; + random_type = RANDOM_TYPE_WORDS; + break; default: case '?': usage(); @@ -90,7 +117,7 @@ main(argc, argv) switch (argc) { case 0: - denom = 2; + denom = (randomize_lines ? 1 : 2); break; case 1: errno = 0; @@ -109,10 +136,6 @@ main(argc, argv) srandomdev(); - /* Compute a random exit status between 0 and denom - 1. */ - if (random_exit) - return ((denom * random()) / LONG_MAX); - /* * Act as a filter, randomly choosing lines of the standard input * to write to the standard output. @@ -121,6 +144,22 @@ main(argc, argv) setbuf(stdout, NULL); /* + * Act as a filter, randomizing lines read in from a given file + * descriptor and write the output to standard output. + */ + if (randomize_lines) { + if ((fd = open(filename, O_RDONLY, 0)) < 0) + err(1, "%s", optarg); + ret = randomize_fd(fd, random_type, unique_output, denom); + if (!random_exit) + return(ret); + } + + /* Compute a random exit status between 0 and denom - 1. */ + if (random_exit) + return ((denom * random()) / LONG_MAX); + + /* * Select whether to print the first line. (Prime the pump.) * We find a random number between 0 and denom - 1 and, if it's * 0 (which has a 1 / denom chance of being true), we select the @@ -148,6 +187,6 @@ void usage() { - (void)fprintf(stderr, "usage: random [-er] [denominator]\n"); + (void)fprintf(stderr, "usage: random [-elruUw] [-f filename] [denominator]\n"); exit(1); } |