[Libguestfs] [PATCH 4/7] lib: Move read_whole_file function into separate library.

Richard W.M. Jones rjones at redhat.com
Tue Sep 29 11:54:51 UTC 2015


Allow this useful function to be called from elsewhere.

This commit is almost, but not completely refactoring.  I made a minor
change to the function so that it \0-terminates the returned data,
which is convenient for some callers.
---
 po/POTFILES            |  1 +
 src/Makefile.am        |  1 +
 src/guestfs-internal.h |  3 ++
 src/inspect-icon.c     | 72 +++------------------------------------
 src/whole-file.c       | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 101 insertions(+), 67 deletions(-)
 create mode 100644 src/whole-file.c

diff --git a/po/POTFILES b/po/POTFILES
index bb68183..9d92690 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -349,6 +349,7 @@ src/structs-free.c
 src/test-utils.c
 src/tmpdirs.c
 src/utils.c
+src/whole-file.c
 test-tool/test-tool.c
 v2v/domainxml-c.c
 v2v/kvmuid-c.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 38a4f50..f5ecaa6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -126,6 +126,7 @@ libguestfs_la_SOURCES = \
 	structs-copy.c \
 	structs-free.c \
 	tmpdirs.c \
+	whole-file.c \
 	libguestfs.syms
 
 libguestfs_la_CPPFLAGS = \
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 22e8e06..75ca71c 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -754,6 +754,9 @@ extern int guestfs_int_lazy_make_tmpdir (guestfs_h *g);
 extern void guestfs_int_remove_tmpdir (guestfs_h *g);
 extern void guestfs_int_recursive_remove_dir (guestfs_h *g, const char *dir);
 
+/* whole-file.c */
+extern int guestfs_int_read_whole_file (guestfs_h *g, const char *filename, char **data_r, size_t *size_r);
+
 /* drives.c */
 extern size_t guestfs_int_checkpoint_drives (guestfs_h *g);
 extern void guestfs_int_rollback_drives (guestfs_h *g, size_t);
diff --git a/src/inspect-icon.c b/src/inspect-icon.c
index 33d0aa7..15c721b 100644
--- a/src/inspect-icon.c
+++ b/src/inspect-icon.c
@@ -25,7 +25,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
-#include <sys/stat.h>
 #include <errno.h>
 #include <sys/wait.h>
 
@@ -43,8 +42,6 @@
 #define CAN_DO_WINDOWS 1
 #endif
 
-static int read_whole_file (guestfs_h *g, const char *filename, char **data_r, size_t *size_r);
-
 /* All these icon_*() functions return the same way.  One of:
  *
  *   ret == NULL:
@@ -272,7 +269,7 @@ get_png (guestfs_h *g, struct inspect_fs *fs, const char *filename,
     return NOT_FOUND;
 
   /* Successfully passed checks and downloaded.  Read it into memory. */
-  if (read_whole_file (g, local, &ret, size_r) == -1)
+  if (guestfs_int_read_whole_file (g, local, &ret, size_r) == -1)
     return NULL;
 
   return ret;
@@ -419,7 +416,7 @@ icon_cirros (guestfs_h *g, struct inspect_fs *fs, size_t *size_r)
     return NOT_FOUND;
 
   /* Read it into memory. */
-  if (read_whole_file (g, pngfile, &ret, size_r) == -1)
+  if (guestfs_int_read_whole_file (g, pngfile, &ret, size_r) == -1)
     return NULL;
 
   return ret;
@@ -488,7 +485,7 @@ icon_windows_xp (guestfs_h *g, struct inspect_fs *fs, size_t *size_r)
   if (!WIFEXITED (r) || WEXITSTATUS (r) != 0)
     return NOT_FOUND;
 
-  if (read_whole_file (g, pngfile, &ret, size_r) == -1)
+  if (guestfs_int_read_whole_file (g, pngfile, &ret, size_r) == -1)
     return NULL;
 
   return ret;
@@ -540,7 +537,7 @@ icon_windows_7 (guestfs_h *g, struct inspect_fs *fs, size_t *size_r)
   if (!WIFEXITED (r) || WEXITSTATUS (r) != 0)
     return NOT_FOUND;
 
-  if (read_whole_file (g, pngfile, &ret, size_r) == -1)
+  if (guestfs_int_read_whole_file (g, pngfile, &ret, size_r) == -1)
     return NULL;
 
   return ret;
@@ -577,7 +574,7 @@ icon_windows_8 (guestfs_h *g, struct inspect_fs *fs, size_t *size_r)
   if (filename_downloaded == NULL)
     return NOT_FOUND;
 
-  if (read_whole_file (g, filename_downloaded, &ret, size_r) == -1)
+  if (guestfs_int_read_whole_file (g, filename_downloaded, &ret, size_r) == -1)
     return NULL;
 
   return ret;
@@ -606,62 +603,3 @@ icon_windows (guestfs_h *g, struct inspect_fs *fs, size_t *size_r)
 }
 
 #endif /* CAN_DO_WINDOWS */
-
-/* Read the whole file into a memory buffer and return it.  The file
- * should be a regular, local, trusted file.
- */
-static int
-read_whole_file (guestfs_h *g, const char *filename,
-                 char **data_r, size_t *size_r)
-{
-  int fd;
-  char *data;
-  off_t size;
-  off_t n;
-  ssize_t r;
-  struct stat statbuf;
-
-  fd = open (filename, O_RDONLY|O_CLOEXEC);
-  if (fd == -1) {
-    perrorf (g, "open: %s", filename);
-    return -1;
-  }
-
-  if (fstat (fd, &statbuf) == -1) {
-    perrorf (g, "stat: %s", filename);
-    close (fd);
-    return -1;
-  }
-
-  size = statbuf.st_size;
-  data = safe_malloc (g, size);
-
-  n = 0;
-  while (n < size) {
-    r = read (fd, &data[n], size - n);
-    if (r == -1) {
-      perrorf (g, "read: %s", filename);
-      free (data);
-      close (fd);
-      return -1;
-    }
-    if (r == 0) {
-      error (g, _("read: %s: unexpected end of file"), filename);
-      free (data);
-      close (fd);
-      return -1;
-    }
-    n += r;
-  }
-
-  if (close (fd) == -1) {
-    perrorf (g, "close: %s", filename);
-    free (data);
-    return -1;
-  }
-
-  *data_r = data;
-  *size_r = size;
-
-  return 0;
-}
diff --git a/src/whole-file.c b/src/whole-file.c
new file mode 100644
index 0000000..38050d9
--- /dev/null
+++ b/src/whole-file.c
@@ -0,0 +1,91 @@
+/* libguestfs
+ * Copyright (C) 2011-2015 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "guestfs.h"
+#include "guestfs-internal.h"
+
+/* Read the whole file into a memory buffer and return it.  The file
+ * should be a regular, local, trusted file.
+ */
+int
+guestfs_int_read_whole_file (guestfs_h *g, const char *filename,
+                             char **data_r, size_t *size_r)
+{
+  int fd;
+  char *data;
+  off_t size;
+  off_t n;
+  ssize_t r;
+  struct stat statbuf;
+
+  fd = open (filename, O_RDONLY|O_CLOEXEC);
+  if (fd == -1) {
+    perrorf (g, "open: %s", filename);
+    return -1;
+  }
+
+  if (fstat (fd, &statbuf) == -1) {
+    perrorf (g, "stat: %s", filename);
+    close (fd);
+    return -1;
+  }
+
+  size = statbuf.st_size;
+  data = safe_malloc (g, size + 1);
+
+  n = 0;
+  while (n < size) {
+    r = read (fd, &data[n], size - n);
+    if (r == -1) {
+      perrorf (g, "read: %s", filename);
+      free (data);
+      close (fd);
+      return -1;
+    }
+    if (r == 0) {
+      error (g, _("read: %s: unexpected end of file"), filename);
+      free (data);
+      close (fd);
+      return -1;
+    }
+    n += r;
+  }
+
+  if (close (fd) == -1) {
+    perrorf (g, "close: %s", filename);
+    free (data);
+    return -1;
+  }
+
+  /* For convenience of callers, \0-terminate the data. */
+  data[size] = '\0';
+
+  *data_r = data;
+  if (size_r != NULL)
+    *size_r = size;
+
+  return 0;
+}
-- 
2.5.0




More information about the Libguestfs mailing list