summaryrefslogtreecommitdiffstats
path: root/daemon/file.c
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2009-11-02 17:02:32 +0000
committerRichard Jones <rjones@redhat.com>2009-11-02 17:48:39 +0000
commit90cf7fc904fca42665fe04cdd90a4c547d23b00c (patch)
tree135162288c8a132c24947a5333c48a00bcac5824 /daemon/file.c
parent55a7427b7679e25134cd43488a9f74cb542416ea (diff)
downloadlibguestfs-90cf7fc904fca42665fe04cdd90a4c547d23b00c.tar.gz
libguestfs-90cf7fc904fca42665fe04cdd90a4c547d23b00c.tar.xz
libguestfs-90cf7fc904fca42665fe04cdd90a4c547d23b00c.zip
New API call: pread
guestfs_pread lets you do partial file reads from arbitrary places within a file. It works like the pread(2) system call.
Diffstat (limited to 'daemon/file.c')
-rw-r--r--daemon/file.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/daemon/file.c b/daemon/file.c
index 7e2f062a..7854adef 100644
--- a/daemon/file.c
+++ b/daemon/file.c
@@ -369,6 +369,58 @@ do_read_file (const char *path, size_t *size_r)
return r;
}
+char *
+do_pread (const char *path, int count, int64_t offset, size_t *size_r)
+{
+ int fd;
+ ssize_t r;
+ char *buf;
+
+ /* The actual limit on messages is smaller than this. This check
+ * just limits the amount of memory we'll try and allocate in the
+ * function. If the message is larger than the real limit, that
+ * will be caught later when we try to serialize the message.
+ */
+ if (count >= GUESTFS_MESSAGE_MAX) {
+ reply_with_error ("pread: %s: count is too large for the protocol, use smaller reads", path);
+ return NULL;
+ }
+
+ CHROOT_IN;
+ fd = open (path, O_RDONLY);
+ CHROOT_OUT;
+
+ if (fd == -1) {
+ reply_with_perror ("open: %s", path);
+ return NULL;
+ }
+
+ buf = malloc (count);
+ if (buf == NULL) {
+ reply_with_perror ("malloc");
+ close (fd);
+ return NULL;
+ }
+
+ r = pread (fd, buf, count, offset);
+ if (r == -1) {
+ reply_with_perror ("pread: %s", path);
+ close (fd);
+ free (buf);
+ return NULL;
+ }
+
+ if (close (fd) == -1) {
+ reply_with_perror ("close: %s", path);
+ close (fd);
+ free (buf);
+ return NULL;
+ }
+
+ *size_r = r;
+ return buf;
+}
+
/* This runs the 'file' command. */
char *
do_file (const char *path)