From 45af1632aa64a5ba1b108e248920e67c180e8485 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Fri, 7 Nov 2014 11:37:33 +0200 Subject: genfile: improve sparse mode * tests/genfile.c (generate_sparse_file): Handle '-' argument (read from stdin); If content strings starts with '=', treat it as fragment size and use default pattern to fill it. * doc/genfile.texi: Document changes to genfile. --- tests/genfile.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/genfile.c b/tests/genfile.c index fa480ef..d41336b 100644 --- a/tests/genfile.c +++ b/tests/genfile.c @@ -32,6 +32,7 @@ #include #include #include +#include #define obstack_chunk_alloc malloc #define obstack_chunk_free free #include @@ -506,6 +507,53 @@ mksparse (int fd, off_t displ, char *marks) } } +static int +make_fragment (int fd, char *offstr, char *mapstr) +{ + int i; + off_t displ = get_size (offstr, 1); + + file_length += displ; + + if (!mapstr || !*mapstr) + { + mkhole (fd, displ); + return 1; + } + else if (*mapstr == '=') + { + off_t n = get_size (mapstr + 1, 1); + + switch (pattern) + { + case DEFAULT_PATTERN: + for (i = 0; i < block_size; i++) + buffer[i] = i & 255; + break; + + case ZEROS_PATTERN: + memset (buffer, 0, block_size); + break; + } + + if (lseek (fd, displ, SEEK_CUR) == -1) + error (EXIT_FAILURE, errno, "lseek"); + + for (; n; n--) + { + if (write (fd, buffer, block_size) != block_size) + error (EXIT_FAILURE, errno, "write"); + file_length += block_size; + } + } + else + { + file_length += block_size * strlen (mapstr); + mksparse (fd, displ, mapstr); + } + return 0; +} + static void generate_sparse_file (int argc, char **argv) { @@ -526,20 +574,33 @@ generate_sparse_file (int argc, char **argv) file_length = 0; - for (i = 0; i < argc; i += 2) + while (argc) { - off_t displ = get_size (argv[i], 1); - file_length += displ; - - if (i == argc-1) + if (argv[0][0] == '-' && argv[0][1] == 0) { - mkhole (fd, displ); - break; + char buf[256]; + while (fgets (buf, sizeof (buf), stdin)) + { + size_t n = strlen (buf); + + while (n > 0 && c_isspace (buf[n-1])) + buf[--n] = 0; + + n = strcspn (buf, " \t"); + buf[n++] = 0; + while (buf[n] && c_isblank (buf[n])) + ++n; + make_fragment (fd, buf, buf + n); + } + ++argv; + --argc; } else { - file_length += block_size * strlen (argv[i+1]); - mksparse (fd, displ, argv[i+1]); + if (make_fragment (fd, argv[0], argv[1])) + break; + argc -= 2; + argv += 2; } } -- cgit v1.2.1