New API: Implement pwrite system call (partial fix for RHBZ#592883).
authorRichard Jones <rjones@redhat.com>
Tue, 18 May 2010 22:20:30 +0000 (23:20 +0100)
committerRichard Jones <rjones@redhat.com>
Thu, 20 May 2010 09:30:12 +0000 (10:30 +0100)
daemon/file.c
src/MAX_PROC_NR
src/generator.ml

index 7d37f56..aca1caa 100644 (file)
@@ -456,6 +456,37 @@ do_pread (const char *path, int count, int64_t offset, size_t *size_r)
   return buf;
 }
 
+int
+do_pwrite (const char *path, const char *content, size_t size, int64_t offset)
+{
+  int fd;
+  ssize_t r;
+
+  CHROOT_IN;
+  fd = open (path, O_WRONLY);
+  CHROOT_OUT;
+
+  if (fd == -1) {
+    reply_with_perror ("open: %s", path);
+    return -1;
+  }
+
+  r = pwrite (fd, content, size, offset);
+  if (r == -1) {
+    reply_with_perror ("pwrite: %s", path);
+    close (fd);
+    return -1;
+  }
+
+  if (close (fd) == -1) {
+    reply_with_perror ("close: %s", path);
+    close (fd);
+    return -1;
+  }
+
+  return r;
+}
+
 /* This runs the 'file' command. */
 char *
 do_file (const char *path)
index 5d165ff..e06108c 100644 (file)
@@ -1 +1 @@
-246
+247
index dfab8dc..32a8140 100755 (executable)
@@ -4062,7 +4062,9 @@ 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.");
+see the L<pread(2)> system call.
+
+See also C<guestfs_pwrite>.");
 
   ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
    [InitEmpty, Always, TestRun (
@@ -4658,6 +4660,32 @@ to ensure the length of the file is exactly C<len> bytes.");
 This call creates a file called C<path>.  The content of the
 file is the string C<content> (which can contain any 8 bit data).");
 
+  ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning],
+   [InitBasicFS, Always, TestOutput (
+      [["write"; "/new"; "new file contents"];
+       ["pwrite"; "/new"; "data"; "4"];
+       ["cat"; "/new"]], "new data contents");
+    InitBasicFS, Always, TestOutput (
+      [["write"; "/new"; "new file contents"];
+       ["pwrite"; "/new"; "is extended"; "9"];
+       ["cat"; "/new"]], "new file is extended");
+    InitBasicFS, Always, TestOutput (
+      [["write"; "/new"; "new file contents"];
+       ["pwrite"; "/new"; ""; "4"];
+       ["cat"; "/new"]], "new file contents")],
+   "write to part of a file",
+   "\
+This command writes to part of a file.  It writes the data
+buffer C<content> to the file C<path> starting at offset C<offset>.
+
+This command implements the L<pwrite(2)> system call, and like
+that system call it may not write the full data requested.  The
+return value is the number of bytes that were actually written
+to the file.  This could even be 0, although short writes are
+unlikely for regular files in ordinary circumstances.
+
+See also C<guestfs_pread>.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions