Linux block reads (2) until all count bytes arrive

I use read (2) to read from a file ( /dev/random , where data comes in very slowly).

However, read () returns only a few bytes after reading, while I would like it to wait for the specified number of bytes to be read (or an error occurred), so the return value should always be considered, or -1.

Is there any way to enable this behavior? The open (2) and read (2) commands do not contain any useful information on this topic, and I did not find any information about the topic on the Internet.

I am fully aware of the workaround by simply placing read() inside the while loop and calling it until all the data has been read. I just would like to know if this can be achieved appropriately, which gives deterministic behavior and includes only O (1) syscalls instead of non-deterministic O (n) in case of solving the while loop.

The following minimal example reproduces the problem.

 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { int fd = open("/dev/random", 0); char buf[128]; size_t bytes = read(fd, buf, sizeof(buf)); printf("Bytes read: %lu\n", bytes); //output is random, usually 8. close(fd); } 
+4
source share
3 answers

While reading may be interrupted by a signal before the requested data is received, this cannot be done.

Unfortunately, you need to check the return value and count the bytes. And yes, the easiest way would be to write a wrapper function.

+3
source

As everyone said

  • It cannot be guaranteed that 128 bytes of randomness are available before your reading returns, and

  • The overhead of getting eight bytes at a time is trivial compared to the amortized cost of generating eight bytes; hence,

  • You must remember that entropy costs huge costs and takes this into account when consuming it.

However, the answer to this question will not be completed without noticing that in man 4 random (on the vaguely recent Linux distribution) you should find the following information:

 The files in the directory /proc/sys/kernel/random (present since 2.3.16) provide an additional interface to the /dev/random device. 

...

 The file read_wakeup_threshold contains the number of bits of entropy required for waking up processes that sleep waiting for entropy from /dev/random. The default is 64. 

That is 64 bits, which is eight bytes. With superuser privileges, you can increase this value, but imho increases it to 1024, and then expects your computer to work fine, probably pretty optimistic. I don’t know all the things that want a bit of entropy, but of course I noticed that my entropy pool goes up and down, so I know something wants it, and I strongly suspect that anything wait for 1024 bits to be available. Anyway, you know a little rope ...

+3
source

From the documentation, / dev / random does everything possible to return the most randomized data that it can use, and which limits the number of bytes that it returns in a single read.

But reading / dev / urandom (pay attention to "u") will return as much data as you requested (buffer size), and sometimes less randomized data.

Here is a useful link

About the behavior of read (), I am sure that it is impossible to change: read () returns the amount of data that underlies plumbery (for example, disk + driver + ...), decided to return, the design of the behavior. The way to do things is, as you said, loop until you get as much data as expected.

0
source

Source: https://habr.com/ru/post/1436809/


All Articles