[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
coreutils-5.92 - dd skip option completely broken
From: |
Theodoros V. Kalamatianos |
Subject: |
coreutils-5.92 - dd skip option completely broken |
Date: |
Mon, 31 Oct 2005 09:46:57 +0200 (EET) |
While trying to implement the per-block seek/skip options I suggested I
stumbled on yet another bug in coreutils-5.92. This time it affects dd and
I believe it is major enough to consider coreutils-5.92 unusable and pull
that release back. Initially I thought that the dd skip= option drops
2 * ibs bytes for each record when reading from stdin, but it seems the
bug is not that simple.
This is a correct run from coreutils-5.2.1:
(I have added extra newlines to make the output more readable)
# echo aaabbccddddeeeeffffgggg > testfile
# dd --version
dd (coreutils) 5.2.1
Written by Paul Rubin, David MacKenzie, and Stuart Kemp.
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# dd if=testfile skip=1 bs=1
aabbccddddeeeeffffgggg
23+0 records in
23+0 records out
# dd if=testfile skip=1 bs=2
abbccddddeeeeffffgggg
11+0 records in
11+0 records out
# dd if=testfile skip=2 bs=2
bccddddeeeeffffgggg
10+0 records in
10+0 records out
# cat testfile | dd skip=1 bs=1
aabbccddddeeeeffffgggg
23+0 records in
23+0 records out
# cat testfile | dd skip=1 bs=2
abbccddddeeeeffffgggg
11+0 records in
11+0 records out
# cat testfile | dd skip=2 bs=2
bccddddeeeeffffgggg
10+0 records in
10+0 records out
And this comes from coreutils-5.92:
# ./dd --version
dd (coreutils) 5.92
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.
Written by Paul Rubin, David MacKenzie, and Stuart Kemp.
# ./dd if=testfile skip=1 bs=1
aabbccddddeeeeffffgggg
23+0 records in
23+0 records out
23 bytes (23 B) copied, 0,000158 seconds, 146 kB/s
# ./dd if=testfile skip=1 bs=2
abbccddddeeeeffffgggg
11+0 records in
11+0 records out
22 bytes (22 B) copied, 0,000109 seconds, 202 kB/s
# ./dd if=testfile skip=2 bs=2
bccddddeeeeffffgggg
10+0 records in
10+0 records out
20 bytes (20 B) copied, 0,000105 seconds, 190 kB/s
(all goes well up to this point)
# cat testfile | ./dd skip=1 bs=1
abbccddddeeeeffffgggg
22+0 records in
22+0 records out
22 bytes (22 B) copied, 0,000155 seconds, 142 kB/s
(notice that two initial 'a' chars have been dropped)
# cat testfile | ./dd skip=1 bs=2
bccddddeeeeffffgggg
10+0 records in
10+0 records out
20 bytes (20 B) copied, 0,000101 seconds, 198 kB/s
# cat testfile | ./dd skip=2 bs=2
cddddeeeeffffgggg
9+0 records in
9+0 records out
18 bytes (18 B) copied, 8,8e-05 seconds, 205 kB/s
And this a test run to verify that this indeed happens with larger block
sizes:
# dd if=/dev/zero bs=1024 count=10 | ./dd bs=1024 skip=1 | wc
10+0 records in
10+0 records out
8+0 records in
8+0 records out
8192 bytes (8,2 kB) copied, 9,1e-05 seconds, 90,0 MB/s
0 0 8192
`wc' should have counted 10*1024 - 1*1024 = 9216 bytes. But this is where
it becomes complicated:
# dd if=/dev/zero bs=1024 count=10 | ./dd bs=2 skip=512 | wc
10+0 records in
10+0 records out
4607+0 records in
4607+0 records out
9214 bytes (9,2 kB) copied, 0,021989 seconds, 419 kB/s
0 0 9214
# dd if=/dev/zero bs=1024 count=10 | ./dd bs=4 skip=512 | wc
10+0 records in
10+0 records out
2047+0 records in
2047+0 records out
8188 bytes (8,2 kB) copied, 0,009488 seconds, 863 kB/s
0 0 8188
It seems that it just reads and drops one more record than it should.
I have verified with `wc' that the characters are indeed dropped end not
e.g. replaced with a null. I'll see if I can trace this bug, but it may
take some time.
Regards,
Theodoros Kalamatianos
- coreutils-5.92 - dd skip option completely broken,
Theodoros V. Kalamatianos <=