New API: fill-pattern for creating files with predefined patterns.
[libguestfs.git] / daemon / fill.c
index b1b0f5e..807ee39 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
 
@@ -37,12 +38,12 @@ do_fill (int c, int len, const char *path)
   char buf[BUFSIZ];
 
   if (c < 0 || c > 255) {
-    reply_with_error ("fill: %d: byte number must be in range 0..255", c);
+    reply_with_error ("%d: byte number must be in range 0..255", c);
     return -1;
   }
   memset (buf, c, BUFSIZ);
   if (len < 0) {
-    reply_with_error ("fill: %d: length is < 0", len);
+    reply_with_error ("%d: length is < 0", len);
     return -1;
   }
   len_sz = (size_t) len;
@@ -74,3 +75,49 @@ do_fill (int c, int len, const char *path)
 
   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;
+}