- Justify why the buffer is three bytes longer than the file's content (Yann) - Check for malloc failure (Yann) - Don't close file descriptor on failure as it's opened outside the function - set errno to indicate why the function failed Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- lib/libfile.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/libfile.c b/lib/libfile.c index c257baaa2733..a7762ab833f6 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -314,7 +314,9 @@ EXPORT_SYMBOL(read_file); * This function reads a file descriptor from offset 0 until EOF to an * allocated buffer. * - * Return: The buffer containing the file or NULL on failure + * Return: On success, returns a nul-terminated buffer with the file's + * contents that should be deallocated with free(). + * On error, NULL is returned and errno is set to an error code. */ void *read_fd(int fd, size_t *out_size) { @@ -329,24 +331,33 @@ void *read_fd(int fd, size_t *out_size) off = lseek(fd, SEEK_SET, 0); } if (off < 0) { - ret = off; - goto close_fd; + errno = -off; + return NULL; } + /* For user convenience, we always nul-terminate the buffer in + * case it contains a string. As we don't want to assume the string + * to be either an array of char or wchar_t, we just unconditionally + * add 2 bytes as terminator. As the two byte terminator needs to be + * aligned, we just make it three bytes + */ buf = malloc(size + 3); + if (!buf) { + errno = ENOMEM; + return NULL; + } + ret = read_full(fd, buf, size); if (ret < 0) { free(buf); - goto close_fd; + errno = -ret; + return NULL; } - memset(&buf[size], '\0', 3); + memset(buf + size, '\0', 3); *out_size = size; -close_fd: - close(fd); - - return ret < 0 ? NULL : buf; + return buf; } EXPORT_SYMBOL(read_fd); -- 2.39.2