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