aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/random/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/random/random.c')
-rw-r--r--usr.bin/random/random.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/usr.bin/random/random.c b/usr.bin/random/random.c
index 9f78a2711cc9..b3b349cbb75a 100644
--- a/usr.bin/random/random.c
+++ b/usr.bin/random/random.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h>
#include <limits.h>
#include <locale.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -67,11 +68,12 @@ main(int argc, char *argv[])
{
double denom;
int ch, fd, random_exit, randomize_lines, random_type, ret,
- selected, unique_output, unbuffer_output;
+ unique_output, unbuffer_output;
+ bool selected;
char *ep;
const char *filename;
- denom = 0;
+ denom = 0.;
filename = "/dev/fd/0";
random_type = RANDOM_TYPE_UNSET;
random_exit = randomize_lines = unbuffer_output = 0;
@@ -119,16 +121,16 @@ main(int argc, char *argv[])
switch (argc) {
case 0:
- denom = (randomize_lines ? 1 : 2);
+ denom = (randomize_lines ? 1. : 2.);
break;
case 1:
errno = 0;
denom = strtod(*argv, &ep);
if (errno == ERANGE)
err(1, "%s", *argv);
- if (denom <= 0 || *ep != '\0')
+ if (denom < 1. || *ep != '\0')
errx(1, "denominator is not valid.");
- if (random_exit && denom > 256)
+ if (random_exit && denom > 256.)
errx(1, "denominator must be <= 256 for random exit.");
break;
default:
@@ -160,24 +162,25 @@ main(int argc, char *argv[])
return (arc4random_uniform(denom));
/*
- * 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
- * line.
+ * Filter stdin, selecting lines with probability 1/denom, one
+ * character at a time.
*/
- selected = (arc4random_uniform(denom) == 0);
- while ((ch = getchar()) != EOF) {
- if (selected)
- (void)putchar(ch);
- if (ch == '\n') {
- /* End of that line. See if we got an error. */
- if (ferror(stdout))
- err(2, "stdout");
-
- /* Now see if the next line is to be printed. */
- selected = (arc4random_uniform(denom) == 0);
+ do {
+ selected = random_uniform_denom(denom);
+ if (selected) {
+ while ((ch = getchar()) != EOF) {
+ putchar(ch);
+ if (ch == '\n')
+ break;
+ }
+ } else {
+ while ((ch = getchar()) != EOF)
+ if (ch == '\n')
+ break;
}
- }
+ if (ferror(stdout))
+ err(2, "stdout");
+ } while (ch != EOF);
if (ferror(stdin))
err(2, "stdin");
exit (0);