[Libguestfs] [PATCH 3/4] New API call: pread
Richard W.M. Jones
rjones at redhat.com
Mon Nov 2 17:58:59 UTC 2009
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages. http://et.redhat.com/~rjones/libguestfs/
See what it can do: http://et.redhat.com/~rjones/libguestfs/recipes.html
-------------- next part --------------
>From 90cf7fc904fca42665fe04cdd90a4c547d23b00c Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Mon, 2 Nov 2009 17:02:32 +0000
Subject: [PATCH 3/4] 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.
---
daemon/file.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/MAX_PROC_NR | 2 +-
src/generator.ml | 11 +++++++++++
3 files changed, 64 insertions(+), 1 deletions(-)
diff --git a/daemon/file.c b/daemon/file.c
index 7e2f062..7854ade 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)
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index b35cfaf..c92ba56 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-206
+207
diff --git a/src/generator.ml b/src/generator.ml
index 001d021..bbdb330 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -3856,6 +3856,17 @@ message size to be exceeded, causing
this call to fail. The caller must split up such requests
into smaller groups of names.");
+ ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
+ [InitISOFS, Always, TestOutputBuffer (
+ [["pread"; "/known-4"; "1"; "3"]], "\n")],
+ "read part of a file",
+ "\
+This command lets you read part of a file. It reads C<count>
+bytes of the file, starting at C<offset>, from file C<path>.
+
+This may read fewer bytes than requested. For further details
+see the L<pread(2)> system call.");
+
]
let all_functions = non_daemon_functions @ daemon_functions
--
1.6.5.rc2
More information about the Libguestfs
mailing list