bug-coreutils
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]