diff options
-rw-r--r-- | daemon/fill.c | 46 | ||||
-rw-r--r-- | src/MAX_PROC_NR | 2 | ||||
-rwxr-xr-x | src/generator.ml | 15 |
3 files changed, 61 insertions, 2 deletions
diff --git a/daemon/fill.c b/daemon/fill.c index 5a391aac..807ee390 100644 --- a/daemon/fill.c +++ b/daemon/fill.c @@ -75,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; +} diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 7f05eede..2c2b1af8 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -244 +245 diff --git a/src/generator.ml b/src/generator.ml index d2abafcb..31f0e027 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -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 -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"; ""]]], @@ -4612,6 +4614,17 @@ filename is not printable, coreutils uses a special 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 |