Introduce loop_read_exact helper

Usually when using loop_read(), we want to read the full buffer.
Add a helper that mirrors loop_write(), and returns 0 when full buffer
was read, and an error otherwise.

Use -ENODATA for the short read, to distinguish it from a read error.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2015-03-09 22:10:54 -04:00
parent ad7bcf526d
commit a6dcc7e592
8 changed files with 52 additions and 66 deletions
+2 -2
View File
@@ -1163,9 +1163,9 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
if (fd < 0)
_exit(EXIT_FAILURE);
k = loop_read(fd, buf, 36, false);
r = loop_read_exact(fd, buf, 36, false);
safe_close(fd);
if (k != 36)
if (k < 0)
_exit(EXIT_FAILURE);
k = send(pair[1], buf, 36, MSG_NOSIGNAL);
+16 -12
View File
@@ -2326,6 +2326,17 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
return n;
}
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
ssize_t n;
n = loop_read(fd, buf, nbytes, do_poll);
if (n < 0)
return n;
if ((size_t) n != nbytes)
return -EIO;
return 0;
}
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
const uint8_t *p = buf;
@@ -2580,8 +2591,9 @@ char* dirname_malloc(const char *path) {
int dev_urandom(void *p, size_t n) {
static int have_syscall = -1;
int r, fd;
ssize_t k;
_cleanup_close_ fd = -1;
int r;
/* Gathers some randomness from the kernel. This call will
* never block, and will always return some data from the
@@ -2616,22 +2628,14 @@ int dev_urandom(void *p, size_t n) {
return -errno;
} else
/* too short read? */
return -EIO;
return -ENODATA;
}
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return errno == ENOENT ? -ENOSYS : -errno;
k = loop_read(fd, p, n, true);
safe_close(fd);
if (k < 0)
return (int) k;
if ((size_t) k != n)
return -EIO;
return 0;
return loop_read_exact(fd, p, n, true);
}
void initialize_srand(void) {
+1
View File
@@ -432,6 +432,7 @@ int sigaction_many(const struct sigaction *sa, ...);
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
bool is_device_path(const char *path);