|
Mark McLoughlin |
371244 |
From 57d7cc602d14c6b50e2826e427a5de124e479f95 Mon Sep 17 00:00:00 2001
|
|
Mark McLoughlin |
371244 |
From: Daniel P. Berrange <berrange@redhat.com>
|
|
Mark McLoughlin |
371244 |
Date: Mon, 12 Oct 2009 20:32:33 +0100
|
|
Mark McLoughlin |
371244 |
Subject: [PATCH] Fix virFileReadLimFD/virFileReadAll to handle EINTR
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
The fread_file_lim() function uses fread() but never handles
|
|
Mark McLoughlin |
371244 |
EINTR results, causing unexpected failures when reading QEMU
|
|
Mark McLoughlin |
371244 |
help arg info. It was unneccessarily using FILE * instead
|
|
Mark McLoughlin |
371244 |
of plain UNIX file handles, which prevented use of saferead()
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
* src/util/util.c: Switch fread_file_lim over to use saferead
|
|
Mark McLoughlin |
371244 |
instead of fread, remove FILE * use, and rename
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
(cherry picked from commit 11a36d956cb8a5e439e535bff3e0cfce50a64bca)
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
Fedora-patch: libvirt-fix-qemu-restore-from-raw2.patch
|
|
Mark McLoughlin |
371244 |
---
|
|
Mark McLoughlin |
371244 |
src/util.c | 45 ++++++++++++---------------------------------
|
|
Mark McLoughlin |
371244 |
1 files changed, 12 insertions(+), 33 deletions(-)
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
diff --git a/src/util.c b/src/util.c
|
|
Mark McLoughlin |
371244 |
index 1878e33..7bc3a66 100644
|
|
Mark McLoughlin |
371244 |
--- a/src/util.c
|
|
Mark McLoughlin |
371244 |
+++ b/src/util.c
|
|
Mark McLoughlin |
371244 |
@@ -887,7 +887,7 @@ virExec(virConnectPtr conn,
|
|
Mark McLoughlin |
371244 |
number of bytes. If the length of the input is <= max_len, and
|
|
Mark McLoughlin |
371244 |
upon error while reading that data, it works just like fread_file. */
|
|
Mark McLoughlin |
371244 |
static char *
|
|
Mark McLoughlin |
371244 |
-fread_file_lim (FILE *stream, size_t max_len, size_t *length)
|
|
Mark McLoughlin |
371244 |
+saferead_lim (int fd, size_t max_len, size_t *length)
|
|
Mark McLoughlin |
371244 |
{
|
|
Mark McLoughlin |
371244 |
char *buf = NULL;
|
|
Mark McLoughlin |
371244 |
size_t alloc = 0;
|
|
Mark McLoughlin |
371244 |
@@ -895,8 +895,8 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
|
|
Mark McLoughlin |
371244 |
int save_errno;
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
for (;;) {
|
|
Mark McLoughlin |
371244 |
- size_t count;
|
|
Mark McLoughlin |
371244 |
- size_t requested;
|
|
Mark McLoughlin |
371244 |
+ int count;
|
|
Mark McLoughlin |
371244 |
+ int requested;
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
if (size + BUFSIZ + 1 > alloc) {
|
|
Mark McLoughlin |
371244 |
alloc += alloc / 2;
|
|
Mark McLoughlin |
371244 |
@@ -912,12 +912,12 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
|
|
Mark McLoughlin |
371244 |
/* Ensure that (size + requested <= max_len); */
|
|
Mark McLoughlin |
371244 |
requested = MIN (size < max_len ? max_len - size : 0,
|
|
Mark McLoughlin |
371244 |
alloc - size - 1);
|
|
Mark McLoughlin |
371244 |
- count = fread (buf + size, 1, requested, stream);
|
|
Mark McLoughlin |
371244 |
+ count = saferead (fd, buf + size, requested);
|
|
Mark McLoughlin |
371244 |
size += count;
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
if (count != requested || requested == 0) {
|
|
Mark McLoughlin |
371244 |
save_errno = errno;
|
|
Mark McLoughlin |
371244 |
- if (ferror (stream))
|
|
Mark McLoughlin |
371244 |
+ if (count < 0)
|
|
Mark McLoughlin |
371244 |
break;
|
|
Mark McLoughlin |
371244 |
buf[size] = '\0';
|
|
Mark McLoughlin |
371244 |
*length = size;
|
|
Mark McLoughlin |
371244 |
@@ -930,12 +930,12 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
|
|
Mark McLoughlin |
371244 |
return NULL;
|
|
Mark McLoughlin |
371244 |
}
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
-/* A wrapper around fread_file_lim that maps a failure due to
|
|
Mark McLoughlin |
371244 |
+/* A wrapper around saferead_lim that maps a failure due to
|
|
Mark McLoughlin |
371244 |
exceeding the maximum size limitation to EOVERFLOW. */
|
|
Mark McLoughlin |
371244 |
-static int virFileReadLimFP(FILE *fp, int maxlen, char **buf)
|
|
Mark McLoughlin |
371244 |
+int virFileReadLimFD(int fd, int maxlen, char **buf)
|
|
Mark McLoughlin |
371244 |
{
|
|
Mark McLoughlin |
371244 |
size_t len;
|
|
Mark McLoughlin |
371244 |
- char *s = fread_file_lim (fp, maxlen+1, &len;;
|
|
Mark McLoughlin |
371244 |
+ char *s = saferead_lim (fd, maxlen+1, &len;;
|
|
Mark McLoughlin |
371244 |
if (s == NULL)
|
|
Mark McLoughlin |
371244 |
return -1;
|
|
Mark McLoughlin |
371244 |
if (len > maxlen || (int)len != len) {
|
|
Mark McLoughlin |
371244 |
@@ -949,37 +949,16 @@ static int virFileReadLimFP(FILE *fp, int maxlen, char **buf)
|
|
Mark McLoughlin |
371244 |
return len;
|
|
Mark McLoughlin |
371244 |
}
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
-/* Like virFileReadLimFP, but use a file descriptor rather than a FILE*. */
|
|
Mark McLoughlin |
371244 |
-int virFileReadLimFD(int fd_arg, int maxlen, char **buf)
|
|
Mark McLoughlin |
371244 |
-{
|
|
Mark McLoughlin |
371244 |
- int fd = dup (fd_arg);
|
|
Mark McLoughlin |
371244 |
- if (fd >= 0) {
|
|
Mark McLoughlin |
371244 |
- FILE *fp = fdopen (fd, "r");
|
|
Mark McLoughlin |
371244 |
- if (fp) {
|
|
Mark McLoughlin |
371244 |
- int len = virFileReadLimFP (fp, maxlen, buf);
|
|
Mark McLoughlin |
371244 |
- int saved_errno = errno;
|
|
Mark McLoughlin |
371244 |
- fclose (fp);
|
|
Mark McLoughlin |
371244 |
- errno = saved_errno;
|
|
Mark McLoughlin |
371244 |
- return len;
|
|
Mark McLoughlin |
371244 |
- } else {
|
|
Mark McLoughlin |
371244 |
- int saved_errno = errno;
|
|
Mark McLoughlin |
371244 |
- close (fd);
|
|
Mark McLoughlin |
371244 |
- errno = saved_errno;
|
|
Mark McLoughlin |
371244 |
- }
|
|
Mark McLoughlin |
371244 |
- }
|
|
Mark McLoughlin |
371244 |
- return -1;
|
|
Mark McLoughlin |
371244 |
-}
|
|
Mark McLoughlin |
371244 |
-
|
|
Mark McLoughlin |
371244 |
int virFileReadAll(const char *path, int maxlen, char **buf)
|
|
Mark McLoughlin |
371244 |
{
|
|
Mark McLoughlin |
371244 |
- FILE *fh = fopen(path, "r");
|
|
Mark McLoughlin |
371244 |
- if (fh == NULL) {
|
|
Mark McLoughlin |
371244 |
+ int fd = open(path, O_RDONLY);
|
|
Mark McLoughlin |
371244 |
+ if (fd < 0) {
|
|
Mark McLoughlin |
371244 |
virReportSystemError(NULL, errno, _("Failed to open file '%s'"), path);
|
|
Mark McLoughlin |
371244 |
return -1;
|
|
Mark McLoughlin |
371244 |
}
|
|
Mark McLoughlin |
371244 |
|
|
Mark McLoughlin |
371244 |
- int len = virFileReadLimFP (fh, maxlen, buf);
|
|
Mark McLoughlin |
371244 |
- fclose(fh);
|
|
Mark McLoughlin |
371244 |
+ int len = virFileReadLimFD(fd, maxlen, buf);
|
|
Mark McLoughlin |
371244 |
+ close(fd);
|
|
Mark McLoughlin |
371244 |
if (len < 0) {
|
|
Mark McLoughlin |
371244 |
virReportSystemError(NULL, errno, _("Failed to read file '%s'"), path);
|
|
Mark McLoughlin |
371244 |
return -1;
|
|
Mark McLoughlin |
371244 |
--
|
|
Mark McLoughlin |
371244 |
1.6.2.5
|
|
Mark McLoughlin |
371244 |
|