/* Be prepared for files from /proc which generally report a file size of 0. */
assert_cc(READ_FULL_BYTES_MAX < SSIZE_MAX);
- if (st.st_size > 0) {
+ if (st.st_size > 0 && n_retries > 1) {
+ /* Let's use the file size if we have more than 1 attempt left. On the last attempt
+ * we'll ignore the file size */
+
if (st.st_size > SSIZE_MAX) { /* Avoid overflow with 32-bit size_t and 64-bit off_t. */
if (max_size == SIZE_MAX)
buf = malloc(size + 1);
if (!buf)
return -ENOMEM;
+
/* Use a bigger allocation if we got it anyway, but not more than the limit. */
size = MIN3(MALLOC_SIZEOF_SAFE(buf) - 1, max_size, READ_FULL_BYTES_MAX);
break;
}
- /* Hmm... either we read too few bytes from /proc or less likely the content
- * of the file might have been changed (and is now bigger) while we were
- * processing, let's try again either with a bigger guessed size or the new
- * file size. */
-
- if (n_retries <= 0) {
- if (max_size == SIZE_MAX)
- return st.st_size > 0 ? -EIO : -EFBIG;
+ /* We have no further attempts left? Then the file is apparently larger than our limits. Give up. */
+ if (n_retries <= 0)
+ return -EFBIG;
- /* Accept a short read, but truncate it appropropriately. */
- n = MIN(n, max_size);
- truncated = true;
- break;
- }
+ /* Hmm... either we read too few bytes from /proc or less likely the content of the file
+ * might have been changed (and is now bigger) while we were processing, let's try again
+ * either with the new file size. */
if (lseek(fd, 0, SEEK_SET) < 0)
return -errno;