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.
This commit is contained in:
Richard Jones
2009-11-02 17:02:32 +00:00
parent 55a7427b76
commit 90cf7fc904
3 changed files with 64 additions and 1 deletions

View File

@@ -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)

View File

@@ -1 +1 @@
206
207

View File

@@ -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