Also, the idea of using 'random' bytes from a 'random' file when I don't yet have a seed for a random-number generator seems like a bit of a chicken-and-egg problem, don't you think? ;-)
No. The problem with using any PRNG is that if the bad guys knows which PRNG you're using and can get his hands on enough consecutive values it generates, then he can theoretically work out where you are in the sequence and thereby predict the value(s) it will generate. Ignoring the issue of how he gets his hands on the values for a moment, if you can use some mechanism to translate the predictable values generated, into some other value in a non-predicable way, then you have effectively disassociated the numbers you use from those that can be predicted.
So, by using even Perl's built-in rand() to pick a file at random from a directory who's contents is not fixed in stone--say the current tmp directory on whatever system. And then picking a random offset and converting what you find to a number to seed your chosen PRNG.
Unless the bad guy can duplicate the contents of that directory exactly, even if you set srand( 1 ) therebye allowing him to know the two (file & offset) numbers you will use, he cannot know what value you will get from the chosen file. The directory doesn't have to change frequently, or even at all so long as the bad guy cannot predict what will be in it. If it does change occasionally, that fine too, but it is not essential.
Seed Perl's rand() from the millisecond portion of the time() from Time::HiRes first and even if you used a "well-known directory" that never changed, the bad guy would need to be able to predict the exact time that you're program grabbed the time() to be able to work out which file and bytes you used.
So why not just use the time() to seed the chosen PRNG?
Because the range of values that you will get from the milliseconds of time() is limited. Each system has a granularity which shows up if you print the time in a tight loop. But if you're going to use a full 32-bit PRNG, that accepts a full 32-bit value as the seed, then you are artificially restricting the starting places within the sequence of the PRNG.
Example: The Mersenne Twister PRNG, can generate 2**19973-1 values before it loops. However, it only accepts 2**32 starting points. So the bad guy has a much greater chance of predicting which part of the overall sequence you are using by exhuastive compare (or Guassian Elimination or whatever) than if you could pick a starting point from the full 2**19973 possibles.
If you used a value as your seed that can only produce some subset of that 2**32 starting points, you made the job easier again.
But, most directories will have considerably less than 2**32 files in them, and most of those files will have considerably less than 2**32 bytes from which to choose. So the effect of a restricted srand() value at this stage is less important. The initial choices of file and offset will wrap over a much smaller range, but the 32-bit value you get from 4 bytes you read from that random file/ random offset have (theoretically) the full 2**32 range. It's this value that is unpredictable and this value you use to seed your chosen generator across it's full range of possibilities.
Now, if you want to retrieve the full 2**19973-1 range of starting points, pick two seeds using the file mechanism. Use the first to seed srand() and the second to discard the first subsequence from the PRNG. You've now made full use of the 2**32 start points and offset into the sequence a random number of places also.
Discarding a possible 2**32 values from rand() may be impractical from a time standpoint, so maybe you discard values from the sequence for 3 or 4 (wall-clock) seconds after seeding the chosen PRNG. That way, prediction becomes a matter of knowing the performance of your CPU and predicting the load upon the cpu at the time when your discard loop runs. That is, the bad guy would need to be able to emulate all the programs running, and the exact workloads the are processing, and the sheduling order of everything, exactly, in order that he could predict where you actually started using the sequence from.
In fact, maybe that alone is enough.