[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#9157: [PATCH] dd: sparse conv flag
From: |
Glenn Morris |
Subject: |
bug#9157: [PATCH] dd: sparse conv flag |
Date: |
Sat, 06 Aug 2011 16:52:46 -0400 |
User-agent: |
Gnus (www.gnus.org), GNU Emacs (www.gnu.org/software/emacs/) |
This bug was reported via bcc. Because of this, the bug tracking system
did not know which package it was associated with and assigned it to
debbugs.gnu.org. I have reassigned it to the coreutils package and am
sending this so that the bug-coreutils mailing list sees the report.
See the complete report at http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9157
Roman Rybalko wrote:
> ---
> doc/coreutils.texi | 4 +++
> src/dd.c | 22 +++++++++++++++-
> tests/Makefile.am | 1 +
> tests/dd/sparse | 70
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 96 insertions(+), 1 deletions(-)
> create mode 100755 tests/dd/sparse
>
> diff --git a/doc/coreutils.texi b/doc/coreutils.texi
> index 424446c..761c698 100644
> --- a/doc/coreutils.texi
> +++ b/doc/coreutils.texi
> @@ -8127,6 +8127,10 @@ Pad every input block to size of @samp{ibs} with
> trailing zero bytes.
> When used with @samp{block} or @samp{unblock}, pad with spaces instead of
> zero bytes.
>
> address@hidden sparse
> address@hidden sparse
> +Make sparse output file.
> +
> @end table
>
> The following ``conversions'' are really file flags
> diff --git a/src/dd.c b/src/dd.c
> index 0824f6c..0393740 100644
> --- a/src/dd.c
> +++ b/src/dd.c
> @@ -126,7 +126,8 @@ enum
> C_NOCREAT = 010000,
> C_EXCL = 020000,
> C_FDATASYNC = 040000,
> - C_FSYNC = 0100000
> + C_FSYNC = 0100000,
> + C_SPARSE = 0200000
> };
>
> /* Status bit masks. */
> @@ -268,6 +269,7 @@ static struct symbol_value const conversions[] =
> {"sync", C_SYNC}, /* Pad input records to ibs with NULs. */
> {"fdatasync", C_FDATASYNC}, /* Synchronize output data before
> finishing. */
> {"fsync", C_FSYNC}, /* Also synchronize output metadata. */
> + {"sparse", C_SPARSE}, /* Make sparse output file. */
> {"", 0}
> };
>
> @@ -533,6 +535,9 @@ Each CONV symbol may be:\n\
> fsync likewise, but also write metadata\n\
> "), stdout);
> fputs (_("\
> + sparse make sparse output file\n\
> +"), stdout);
> + fputs (_("\
> \n\
> Each FLAG symbol may be:\n\
> \n\
> @@ -985,6 +990,21 @@ iwrite (int fd, char const *buf, size_t size)
> {
> ssize_t nwritten;
> process_signals ();
> + if (conversions_mask & C_SPARSE)
> + {
> + off_t seek_size = 0;
> + while (total_written + seek_size < size && buf[total_written +
> seek_size] == 0)
> + ++seek_size;
> + if (seek_size)
> + {
> + off_t cur_off = 0;
> + cur_off = lseek(fd, seek_size, SEEK_CUR);
> + if (cur_off < 0)
> + break;
> + total_written += seek_size;
> + continue;
> + }
> + }
> nwritten = write (fd, buf + total_written, size - total_written);
> if (nwritten < 0)
> {
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index ebd1b11..0f1376a 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -364,6 +364,7 @@ TESTS = \
> dd/skip-seek \
> dd/skip-seek2 \
> dd/skip-seek-past-file \
> + dd/sparse \
> dd/stderr \
> dd/unblock \
> dd/unblock-sync \
> diff --git a/tests/dd/sparse b/tests/dd/sparse
> new file mode 100755
> index 0000000..f0e0806
> --- /dev/null
> +++ b/tests/dd/sparse
> @@ -0,0 +1,70 @@
> +#!/bin/sh
> +# Ensure that dd conv=sparse works.
> +
> +# Copyright (C) 2003, 2005-2011 Free Software Foundation, Inc.
> +
> +# This program is free software: you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation, either version 3 of the License, or
> +# (at your option) any later version.
> +
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +. "${srcdir=.}/init.sh"; path_prepend_ ../src
> +print_ver_ dd
> +
> +# sometimes we may read less than 1M
> +dd if=/dev/zero of=sample0 count=1 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c %s sample0`" = "1048576" ] || fail=1
> +dd if=/dev/urandom of=sample1 count=1 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c %s sample1`" = "1048576" ] || fail=1
> +
> +# test 1
> +dd if=sample1 of=test1 seek=0 bs=1M 2> /dev/null || fail=1
> +dd if=sample0 of=test1 seek=1 bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=test1 seek=2 bs=1M 2> /dev/null || fail=1
> +
> +# test 1-1
> +dd if=test1 of=out1-1 conv=sparse bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out1-1-check bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out1-1-check seek=2 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c '%s %b %B' out1-1`" = "`stat -c '%s %b %B' out1-1-check`" ] ||
> fail=1
> +
> +# test 1-2
> +dd if=test1 of=out1-2 seek=1 conv=sparse bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out1-2-check seek=1 bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out1-2-check seek=3 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c '%s %b %B' out1-2`" = "`stat -c '%s %b %B' out1-2-check`" ] ||
> fail=1
> +
> +# test 1-3
> +dd if=test1 of=out1-3 seek=1 skip=1 conv=sparse bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out1-3-check seek=2 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c '%s %b %B' out1-3`" = "`stat -c '%s %b %B' out1-3-check`" ] ||
> fail=1
> +
> +# test 2
> +dd if=sample0 of=test2 seek=0 bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=test2 seek=1 bs=1M 2> /dev/null || fail=1
> +dd if=sample0 of=test2 seek=2 bs=1M 2> /dev/null || fail=1
> +
> +# test 2-1
> +dd if=test2 of=out2-1 conv=sparse bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out2-1-check seek=1 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c '%s %b %B' out2-1`" = "`stat -c '%s %b %B' out2-1-check`" ] ||
> fail=1
> +
> +# test 2-2
> +dd if=test2 of=out2-2 seek=1 conv=sparse bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out2-2-check seek=2 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c '%s %b %B' out2-2`" = "`stat -c '%s %b %B' out2-2-check`" ] ||
> fail=1
> +
> +# test 2-3
> +dd if=test2 of=out2-3 seek=1 skip=1 conv=sparse bs=1M 2> /dev/null || fail=1
> +dd if=sample1 of=out2-3-check seek=1 bs=1M 2> /dev/null || fail=1
> +[ "`stat -c '%s %b %B' out2-3`" = "`stat -c '%s %b %B' out2-3-check`" ] ||
> fail=1
> +
> +Exit $fail
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- bug#9157: [PATCH] dd: sparse conv flag,
Glenn Morris <=