New API: fill-pattern for creating files with predefined patterns.
authorRichard Jones <rjones@redhat.com>
Wed, 12 May 2010 16:32:39 +0000 (17:32 +0100)
committerRichard Jones <rjones@redhat.com>
Wed, 12 May 2010 16:33:16 +0000 (17:33 +0100)
daemon/fill.c
src/MAX_PROC_NR
src/generator.ml

index 5a391aa..807ee39 100644 (file)
@@ -75,3 +75,49 @@ do_fill (int c, int len, const char *path)
 
   return 0;
 }
 
   return 0;
 }
+
+int
+do_fill_pattern (const char *pattern, int len, const char *path)
+{
+  size_t patlen = strlen (pattern);
+
+  if (patlen < 1) {
+    reply_with_error ("pattern string must be non-empty");
+    return -1;
+  }
+
+  if (len < 0) {
+    reply_with_error ("%d: length is < 0", len);
+    return -1;
+  }
+  size_t len_sz = (size_t) len;
+
+  int fd;
+  CHROOT_IN;
+  fd = open (path, O_WRONLY | O_CREAT | O_NOCTTY, 0666);
+  CHROOT_OUT;
+
+  if (fd == -1) {
+    reply_with_perror ("open: %s", path);
+    return -1;
+  }
+
+  /* XXX This implementation won't be very efficient for large files. */
+  size_t n = 0;
+  while (n < len_sz) {
+    size_t wrlen = len_sz - n < patlen ? len_sz - n : patlen;
+    if (xwrite (fd, pattern, wrlen) == -1) {
+      reply_with_perror ("write: %s", path);
+      close (fd);
+      return -1;
+    }
+    n += wrlen;
+  }
+
+  if (close (fd) == -1) {
+    reply_with_perror ("close: %s", path);
+    return -1;
+  }
+
+  return 0;
+}
index 7f05eed..2c2b1af 100644 (file)
@@ -1 +1 @@
-244
+245
index d2abafc..31f0e02 100755 (executable)
@@ -4252,7 +4252,9 @@ content of the file is C<len> octets of C<c>, where C<c>
 must be a number in the range C<[0..255]>.
 
 To fill a file with zero bytes (sparsely), it is
 must be a number in the range C<[0..255]>.
 
 To fill a file with zero bytes (sparsely), it is
-much more efficient to use C<guestfs_truncate_size>.");
+much more efficient to use C<guestfs_truncate_size>.
+To create a file with a pattern of repeating bytes
+use C<guestfs_fill_pattern>.");
 
   ("available", (RErr, [StringList "groups"]), 216, [],
    [InitNone, Always, TestRun [["available"; ""]]],
 
   ("available", (RErr, [StringList "groups"]), 216, [],
    [InitNone, Always, TestRun [["available"; ""]]],
@@ -4612,6 +4614,17 @@ filename is not printable, coreutils uses a special
 backslash syntax.  For more information, see the GNU
 coreutils info file.");
 
 backslash syntax.  For more information, see the GNU
 coreutils info file.");
 
+  ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
+   [InitBasicFS, Always, TestOutputBuffer (
+      [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
+       ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
+   "fill a file with a repeating pattern of bytes",
+   "\
+This function is like C<guestfs_fill> except that it creates
+a new file of length C<len> containing the repeating pattern
+of bytes in C<pattern>.  The pattern is truncated if necessary
+to ensure the length of the file is exactly C<len> bytes.");
+
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions
 ]
 
 let all_functions = non_daemon_functions @ daemon_functions