--- /dev/null
+#!/usr/bin/perl
+
+use IO::Handle;
+use IO::File;
+use POSIX;
+
+$want= 1;
+$filename= "/usr/share/dict/words";
+@randfile= ("/dev/urandom", "/dev/random");
+
+sub fail ($) { die "random-word: $_[0]\n"; }
+open D, ">/dev/null" or fail("open /dev/null: $!");
+
+while ($ARGV[0] =~ m/^\-/) {
+ $_= shift @ARGV;
+ if (m/^\-\-?$/) {
+ last;
+ } elsif (m/^\-n(\d+)$/) {
+ $want= $1;
+ } elsif (m/^\-f/ && length > 2) {
+ $filename= $';
+ } elsif (m/^\-r/ && length > 2) {
+ @randfile= ($');
+ } elsif (m/^\-D$/) {
+ open D, ">&STDERR" or fail("dup stderr for debug: $!");
+ } else {
+ fail("unknown option \`$_'");
+ }
+}
+
+sub debug ($) {
+ print D "random-word: debug: $_[0]\n"
+ or fail("write debug: $!");
+}
+
+for $randfile (@randfile) {
+ $r= new IO::File "$randfile", 'r';
+ debug("open $randfile ".($r ? "ok" : "failed $!"));
+ last if $r;
+ $!==&ENOENT or fail("cannot open $randfile: $!");
+}
+$r or fail("could not open any random device: $!\n (tried @randfile)");
+$r->autoflush(0);
+
+$w= new IO::File $filename, 'r';
+$w or fail("cannot open $filename: $!");
+debug("open $filename ok");
+@words= <$w>;
+$w->error and fail("cannot read $filename: $!");
+debug("read $filename ok");
+
+while (@out < $want) {
+ $!=0; read $r,$rbytes,4;
+ length $rbytes==4 or fail("cannot read $randfile: $!");
+ $wordno= unpack 'L',$rbytes;
+ $wordno &= ~0x80000000;
+ $wordno %= @words;
+ $_= $words[$wordno];
+ chomp;
+ debug("picked $wordno \`$_'");
+ next unless m/^([a-z][-a-z]+)$/;
+ push @out, $1;
+ debug("good, now ".scalar @out);
+}
+
+debug("enough");
+
+print join(' ',@out), "\n"
+ or fail("cannot write output: $!");