ouch, I did a mess in the original function, fix them:
* on errors (read() < 0), continue reading after the done bytes, not
at position 0.
* read buflen - 1 bytes, so there is always room to store the
trailing \0, as expected by user due behavior of snprintf(),
fgets() and others.
}
ssize_t read_str_safe(int fd, char *buf, size_t buflen) {
- size_t todo = buflen;
- size_t done;
+ size_t todo = buflen - 1;
+ size_t done = 0;
do {
- ssize_t r = read(fd, buf, todo);
+ ssize_t r = read(fd, buf + done, todo);
if (r == 0)
break;
- else if (r > 0)
+ else if (r > 0) {
todo -= r;
- else {
+ done += r;
+ } else {
if (errno == EAGAIN || errno == EWOULDBLOCK ||
errno == EINTR)
continue;
}
} while (todo > 0);
- done = buflen - todo;
-
- if (done == 0)
- buf[0] = '\0';
- else {
- if (done < buflen)
- buf[done] = '\0';
- else if (buf[done - 1] != '\0')
- return -ENOSPC;
- }
-
+ buf[done] = '\0';
return done;
}