Why is it that I cannot mmap /dev/random or /dev/urandom on Linux?

I get errno 19 which is ENODEV.

When I try the same code with /dev/zero it works.

    int fd = open(path, O_RDONLY);
    assert (fd > 0);

    void* random = mmap(NULL, size, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0);
    int err = errno;

    assert (random != MAP_FAILED);

You cannot mmap() /dev/random or /dev/urandom. Nor can you seek() them for that matter. And as a general rule, you cannot mmap() unseekable things. Pipes are another example of things you cannot mmap() because they are not seekable.

/dev/random and /dev/urandom are fundamentally stream-based, sequential access, devices. They produce bytes on demand when you read them. Random access to these devices has no meaning. mmap() implies random access.

  • It seems like an interesting problem to solve, at least for /dev/urandom. Thanks for your answer! – stojanman May 8 '15 at 16:04
  • 7
    What "problem" would you solve? What random access semantics would you confer on /dev/urandom? For example, what would it mean to read the 42nd byte of /dev/urandom, then read the 46378th byte, then read the 42nd byte again? Would the 42nd byte still have the same value? Random access to these devices seems non-sensical. – Celada May 8 '15 at 16:06
  • @Celada's answer is so clear. However, it is probably interesting to note that /dev/random being a stream device is more likely a question of practicality rather than a conceptual problem. "Would the 42nd byte still have the same value?", both would make sense. An old random value would still be random as long as there is no observable pattern in the observed array of bytes. A new random value would obvously be random. – foki Jan 12 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.