diff options
Diffstat (limited to 'tests/dd')
-rwxr-xr-x | tests/dd/ascii.sh | 74 | ||||
-rwxr-xr-x | tests/dd/bytes.sh | 63 | ||||
-rwxr-xr-x | tests/dd/direct.sh | 35 | ||||
-rwxr-xr-x | tests/dd/misc.sh | 127 | ||||
-rwxr-xr-x | tests/dd/no-allocate.sh | 76 | ||||
-rwxr-xr-x | tests/dd/nocache.sh | 58 | ||||
-rwxr-xr-x | tests/dd/nocache_eof.sh | 97 | ||||
-rwxr-xr-x | tests/dd/not-rewound.sh | 31 | ||||
-rwxr-xr-x | tests/dd/reblock.sh | 72 | ||||
-rwxr-xr-x | tests/dd/skip-seek-past-dev.sh | 58 | ||||
-rwxr-xr-x | tests/dd/skip-seek-past-file.sh | 92 | ||||
-rwxr-xr-x | tests/dd/skip-seek.pl | 88 | ||||
-rwxr-xr-x | tests/dd/skip-seek2.sh | 38 | ||||
-rwxr-xr-x | tests/dd/sparse.sh | 93 | ||||
-rwxr-xr-x | tests/dd/stats.sh | 76 | ||||
-rwxr-xr-x | tests/dd/stderr.sh | 43 | ||||
-rwxr-xr-x | tests/dd/unblock-sync.sh | 35 | ||||
-rwxr-xr-x | tests/dd/unblock.pl | 59 |
18 files changed, 1215 insertions, 0 deletions
diff --git a/tests/dd/ascii.sh b/tests/dd/ascii.sh new file mode 100755 index 0000000..56f3b52 --- /dev/null +++ b/tests/dd/ascii.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# test conv=ascii + +# Copyright (C) 2014-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd printf + +{ + # Two lines, EBCDIC " A A" and " A ", followed by all the bytes in order. + env printf '\100\301\100\301\100\301\100\100' && + env printf $(env printf '\\%03o' $(seq 0 255)); +} >in || framework_failure_ + +{ + # The converted lines, with trailing spaces removed. +env printf \ +' A A\n A\n'\ +'\000\001\002\003\n\234\011\206\177\n'\ +'\227\215\216\013\n\014\015\016\017\n'\ +'\020\021\022\023\n\235\205\010\207\n'\ +'\030\031\222\217\n\034\035\036\037\n'\ +'\200\201\202\203\n\204\012\027\033\n'\ +'\210\211\212\213\n\214\005\006\007\n'\ +'\220\221\026\223\n\224\225\226\004\n'\ +'\230\231\232\233\n\024\025\236\032\n'\ +'\040\240\241\242\n\243\244\245\246\n'\ +'\247\250\325\056\n\074\050\053\174\n'\ +'\046\251\252\253\n\254\255\256\257\n'\ +'\260\261\041\044\n\052\051\073\176\n'\ +'\055\057\262\263\n\264\265\266\267\n'\ +'\270\271\313\054\n\045\137\076\077\n'\ +'\272\273\274\275\n\276\277\300\301\n'\ +'\302\140\072\043\n\100\047\075\042\n'\ +'\303\141\142\143\n\144\145\146\147\n'\ +'\150\151\304\305\n\306\307\310\311\n'\ +'\312\152\153\154\n\155\156\157\160\n'\ +'\161\162\136\314\n\315\316\317\320\n'\ +'\321\345\163\164\n\165\166\167\170\n'\ +'\171\172\322\323\n\324\133\326\327\n'\ +'\330\331\332\333\n\334\335\336\337\n'\ +'\340\341\342\343\n\344\135\346\347\n'\ +'\173\101\102\103\n\104\105\106\107\n'\ +'\110\111\350\351\n\352\353\354\355\n'\ +'\175\112\113\114\n\115\116\117\120\n'\ +'\121\122\356\357\n\360\361\362\363\n'\ +'\134\237\123\124\n\125\126\127\130\n'\ +'\131\132\364\365\n\366\367\370\371\n'\ +'\060\061\062\063\n\064\065\066\067\n'\ +'\070\071\372\373\n\374\375\376\377\n'; +} >exp || framework_failure_ + +dd if=in of=out conv=ascii cbs=4 || fail=1 + +compare exp out \ + || { od -v -to1 exp > exp2 || framework_failure_; + od -v -to1 out > out2 || framework_failure_; + compare exp2 out2; + fail=1; } + +Exit $fail diff --git a/tests/dd/bytes.sh b/tests/dd/bytes.sh new file mode 100755 index 0000000..539f041 --- /dev/null +++ b/tests/dd/bytes.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# Copyright (C) 2012-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +echo 0123456789abcdefghijklm > in || framework_failure_ + +# count bytes +for operands in "count=14B" "count=14 iflag=count_bytes"; do + dd $operands conv=swab < in > out 2> /dev/null || fail=1 + case $(cat out) in + 1032547698badc) ;; + *) fail=1 ;; + esac +done + +for operands in "iseek=10B" "skip=10 iflag=skip_bytes"; do + # skip bytes + dd $operands < in > out 2> /dev/null || fail=1 + case $(cat out) in + abcdefghijklm) ;; + *) fail=1 ;; + esac + + # skip records and bytes from pipe + echo 0123456789abcdefghijklm | + dd $operands bs=2 > out 2> /dev/null || fail=1 + case $(cat out) in + abcdefghijklm) ;; + *) fail=1 ;; + esac +done + +truncate -s8 expected2 +printf '\0\0\0\0\0\0\0\0abcdefghijklm\n' > expected + +for operands in "oseek=8B" "seek=8 oflag=seek_bytes"; do + # seek bytes + echo abcdefghijklm | + dd $operands bs=5 > out 2> /dev/null || fail=1 + compare expected out || fail=1 + + # Just truncation, no I/O + dd $operands bs=5 of=out2 count=0 2> /dev/null || fail=1 + compare expected2 out2 || fail=1 +done + +Exit $fail diff --git a/tests/dd/direct.sh b/tests/dd/direct.sh new file mode 100755 index 0000000..640f4c4 --- /dev/null +++ b/tests/dd/direct.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# ensure that dd's iflag=direct and oflag=direct work + +# Copyright (C) 2009-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +truncate -s 8192 in || framework_failure_ +dd if=in oflag=direct of=out 2> /dev/null \ + || skip_ '512 byte aligned O_DIRECT is not supported on this (file) system' + +truncate -s 511 short || framework_failure_ +truncate -s 8191 m1 || framework_failure_ +truncate -s 8193 p1 || framework_failure_ + +for i in short m1 p1; do + rm -f out + dd if=$i iflag=direct oflag=direct of=out || fail=1 +done + +Exit $fail diff --git a/tests/dd/misc.sh b/tests/dd/misc.sh new file mode 100755 index 0000000..d20cbac --- /dev/null +++ b/tests/dd/misc.sh @@ -0,0 +1,127 @@ +#!/bin/sh +# Ensure dd treats '--' properly. +# Also test some flag values. + +# Copyright (C) 1999-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd +export LC_ALL=C + +tmp_in=dd-in +tmp_in2=dd-in2 +tmp_sym=dd-sym +tmp_out=dd-out + +warn=0 +echo data > $tmp_in || framework_failure_ +ln $tmp_in $tmp_in2 || framework_failure_ +ln -s $tmp_in $tmp_sym || framework_failure_ + +# check status=none suppresses all output to stderr +dd status=none if=$tmp_in of=/dev/null 2> err || fail=1 +compare /dev/null err || fail=1 +dd status=none if=$tmp_in skip=2 of=/dev/null 2> err || fail=1 +compare /dev/null err || fail=1 +# check later status=none overrides earlier status=noxfer +dd status=noxfer status=none if=$tmp_in of=/dev/null 2> err || fail=1 +compare /dev/null err || fail=1 +# check later status=noxfer overrides earlier status=none +dd status=none status=noxfer if=$tmp_in of=/dev/null 2> err || fail=1 +compare /dev/null err && fail=1 + +dd if=$tmp_in of=$tmp_out 2> /dev/null || fail=1 +compare $tmp_in $tmp_out || fail=1 + +rm $tmp_out +dd -- if=$tmp_in of=$tmp_out 2> /dev/null || fail=1 +compare $tmp_in $tmp_out || fail=1 + +if dd oflag=append if=$tmp_in of=$tmp_out 2> /dev/null; then + compare $tmp_in $tmp_out || fail=1 +fi + +case $(cat /dev/stdin <$tmp_in 2>/dev/null) in +(data) + rm -f $tmp_out + dd if=/dev/stdin of=$tmp_out <$tmp_in || fail=1 + compare $tmp_in $tmp_out || fail=1 +esac + +if dd iflag=nofollow if=$tmp_in count=0 2> /dev/null; then + returns_ 1 dd iflag=nofollow if=$tmp_sym count=0 2> /dev/null || fail=1 +fi + +if dd iflag=directory if=. count=0 2> /dev/null; then + dd iflag=directory count=0 <. 2> /dev/null || fail=1 + returns_ 1 dd iflag=directory count=0 <$tmp_in 2> /dev/null || fail=1 +fi + +old_ls=$(ls -u --full-time $tmp_in) +sleep 1 +if dd iflag=noatime if=$tmp_in of=$tmp_out 2> /dev/null; then + new_ls=$(ls -u --full-time $tmp_in) + if test "x$old_ls" != "x$new_ls"; then + cat >&2 <<EOF +================================================================= +$0: WARNING!!! +This operating system has the O_NOATIME file status flag, +but it is silently ignored in some cases. +Therefore, dd options like iflag=noatime may be silently ignored. +================================================================= +EOF + warn=77 + fi +fi + +if dd oflag=nolinks if=$tmp_in of=$tmp_out 2> /dev/null; then + returns_ 1 dd iflag=nolinks if=$tmp_in > /dev/null 2>&1 || fail=1 + returns_ 1 dd iflag=nolinks < $tmp_in > /dev/null 2>&1 || fail=1 + dd oflag=nolinks < $tmp_in > $tmp_out 2>&1 || fail=1 +fi + +outbytes=$(echo x | dd bs=3 ibs=10 obs=10 conv=sync 2>/dev/null | wc -c) +test "$outbytes" -eq 3 || fail=1 + +# A delay is required to trigger a failure. +# There might be some missed failures but it's unlikely. +(echo a; sleep .1; echo b) \ + | dd bs=4 status=noxfer iflag=fullblock >out 2>err || fail=1 +printf 'a\nb\n' > out_ok || framework_failure_ +echo "1+0 records in +1+0 records out" > err_ok || framework_failure_ +compare out_ok out || fail=1 +compare err_ok err || fail=1 + +test $fail -eq 0 && fail=$warn + +# Check a warning is issued for ambiguous 0x... numbers +dd if=/dev/null count=0x1 seek=0x1 skip=0x1 status=none 2>err || fail=1 +cat <<\EOF >exp +dd: warning: '0x' is a zero multiplier; use '00x' if that is intended +dd: warning: '0x' is a zero multiplier; use '00x' if that is intended +dd: warning: '0x' is a zero multiplier; use '00x' if that is intended +EOF +compare exp err || fail=1 + +echo "0+0 records in +0+0 records out" >err_ok || framework_failure_ +big=9999999999999999999999999999999999999999999999999999999999999 +dd if=$tmp_in of=$tmp_out count=00x$big status=noxfer 2>err || fail=1 +compare /dev/null $tmp_out || fail=1 +compare err_ok err || fail=1 + +Exit $fail diff --git a/tests/dd/no-allocate.sh b/tests/dd/no-allocate.sh new file mode 100755 index 0000000..cedfa79 --- /dev/null +++ b/tests/dd/no-allocate.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# make sure that dd doesn't allocate memory unnecessarily + +# Copyright (C) 2013-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +# Determine basic amount of memory needed. +echo . > f || framework_failure_ +vm=$(get_min_ulimit_v_ timeout 10 dd if=f of=f2 status=none) \ + || skip_ "this shell lacks ulimit support" +rm f f2 || framework_failure_ + +# count and skip are zero, we don't need to allocate memory +(ulimit -v $vm && dd bs=30M count=0) || fail=1 +(ulimit -v $vm && dd ibs=30M count=0) || fail=1 +(ulimit -v $vm && dd obs=30M count=0) || fail=1 + +check_dd_seek_alloc() { + local file="$1" + local buf="$2" + test "$file" = 'in' && { dd_file=if; dd_op=skip; } + test "$file" = 'out' && { dd_file=of; dd_op=seek; } + test "$buf" = 'in' && { dd_buf=ibs; } + test "$buf" = 'out' && { dd_buf=obs; } + test "$buf" = 'both' && { dd_buf=bs; } + + # Provide input to the "tape" + timeout 10 dd count=1 if=/dev/zero of=tape& + + # Allocate buffer and read from the "tape" + (ulimit -v $vm \ + && timeout 10 dd $dd_buf=30M $dd_op=1 count=0 $dd_file=tape) + local ret=$? + + # Be defensive in case the tape reader is blocked for some reason + test $ret = 124 && framework_failure_ + + # This should happen without delay, + # and is used to ensure we've not multiple writers to the "tape" + wait + + # We want the "tape" reader to fail iff allocating + # a large buffer corresponding to the file being read + case "$file$buf" in + inout|outin) test $ret = 0;; + *) test $ret != 0;; + esac +} + +# Use a fifo for which seek fails, but read does not. +# For non seekable output we need to allocate a buffer +# when simulating seeking with a read. +if mkfifo tape; then + for file in 'in' 'out'; do + for buf in 'both' 'in' 'out'; do + check_dd_seek_alloc "$file" "$buf" || fail=1 + done + done +fi + +Exit $fail diff --git a/tests/dd/nocache.sh b/tests/dd/nocache.sh new file mode 100755 index 0000000..3aee114 --- /dev/null +++ b/tests/dd/nocache.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# Ensure dd handles the 'nocache' flag + +# Copyright (C) 2011-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +# This should not call posix_fadvise +dd iflag=nocache oflag=nocache if=/dev/null of=/dev/null || fail=1 + +# We should get an error for trying to process a pipe +dd count=0 | returns_ 1 dd iflag=nocache count=0 || fail=1 + +# O_DIRECT is orthogonal to drop cache so mutually exclusive +returns_ 1 dd iflag=nocache,direct if=/dev/null || fail=1 + +# The rest ensure that the documented uses cases +# proceed without error +for f in ifile ofile; do + dd if=/dev/zero of=$f conv=fdatasync count=100 || framework_failure_ +done + +# Advise to drop cache for whole file +if ! dd if=ifile iflag=nocache count=0 2>err; then + # We could check for 'Operation not supported' in err here, + # but that was seen to be brittle. HPUX returns ENOTTY for example. + # So assume that if this basic operation fails, it's due to lack + # of support by the system. + warn_ 'skipping part; this file system lacks support for posix_fadvise()' + skip=1 +fi + +if test "$skip" != 1; then + # Ensure drop cache for whole file + dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0 || fail=1 + + # Drop cache for part of file + dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null || fail=1 + + # Stream data just using readahead cache + dd if=ifile of=ofile iflag=nocache oflag=nocache || fail=1 +fi + +Exit $fail diff --git a/tests/dd/nocache_eof.sh b/tests/dd/nocache_eof.sh new file mode 100755 index 0000000..7de765c --- /dev/null +++ b/tests/dd/nocache_eof.sh @@ -0,0 +1,97 @@ +#!/bin/sh +# Ensure dd invalidates to EOF when appropriate + +# Copyright (C) 2017-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd +require_strace_ fadvise64,fadvise64_64 + +head -c1234567 /dev/zero > in.f || framework_failure_ + +# Check basic operation or skip. +# We could check for 'Operation not supported' error here, +# but that was seen to be brittle. HPUX returns ENOTTY for example. +# So assume that if this basic operation fails, it's due to lack +# of support by the system. +dd if=in.f iflag=nocache count=0 || + skip_ 'this file system lacks support for posix_fadvise()' + +strace_dd() { + strace -o dd.strace -e fadvise64,fadvise64_64 dd status=none "$@" || fail=1 +} + +advised_to_eof() { + grep -F ' 0, POSIX_FADV_DONTNEED' dd.strace >/dev/null +} + +# The commented fadvise64 calls are what are expected with +# a 4KiB page size and 128KiB IO_BUFSIZE. + +strace_dd if=in.f of=out.f bs=1M oflag=nocache,sync +#fadvise64(1, 0, 1048576, POSIX_FADV_DONTNEED) = 0 +#fadvise64(1, 1048576, 131072, POSIX_FADV_DONTNEED) = 0 +#fadvise64(1, 1179648, 0, POSIX_FADV_DONTNEED) = 0 +advised_to_eof || fail=1 + +strace_dd if=in.f count=0 iflag=nocache +#fadvise64(0, 0, 0, POSIX_FADV_DONTNEED) = 0 +advised_to_eof || fail=1 + +strace_dd if=in.f of=/dev/null iflag=nocache skip=10 count=300 +#fadvise64(0, 5120, 131072, POSIX_FADV_DONTNEED) = 0 +#fadvise64(0, 136192, 22528, POSIX_FADV_DONTNEED) = 0 +returns_ 1 advised_to_eof || fail=1 + +strace_dd if=in.f of=/dev/null iflag=nocache bs=1M count=3000 +#fadvise64(0, 0, 1048576, POSIX_FADV_DONTNEED) = 0 +#fadvise64(0, 1048576, 131072, POSIX_FADV_DONTNEED) = 0 +#fadvise64(0, 1179648, 0, POSIX_FADV_DONTNEED) = 0 +advised_to_eof || fail=1 + +strace_dd if=in.f of=/dev/null bs=1M count=1 iflag=nocache +#fadvise64(0, 0, 1048576, POSIX_FADV_DONTNEED) = 0 +returns_ 1 advised_to_eof || fail=1 + +strace_dd if=in.f of=out.f bs=1M iflag=nocache oflag=nocache,sync +#fadvise64(0, 0, 1048576, POSIX_FADV_DONTNEED) = 0 +#fadvise64(1, 0, 1048576, POSIX_FADV_DONTNEED) = 0 +#fadvise64(0, 1048576, 131072, POSIX_FADV_DONTNEED) = 0 +#fadvise64(1, 1048576, 131072, POSIX_FADV_DONTNEED) = 0 +#fadvise64(0, 1179648, 0, POSIX_FADV_DONTNEED) = 0 +#fadvise64(1, 1179648, 0, POSIX_FADV_DONTNEED) = 0 +advised_to_eof || fail=1 + +# Ensure sub page size offsets are handled. +# I.e., only page aligned offsets are sent to fadvise. +if ! strace -o dd.strace -e fadvise64,fadvise64_64 dd status=none \ + if=in.f of=out.f bs=1M oflag=direct oseek=512B; then + warn_ '512 byte aligned O_DIRECT is not supported on this (file) system' + # The current file system may not support O_DIRECT, + # or older XFS had a page size alignment requirement +else + #The first call is redundant but inconsequential + #fadvise64(1, 1048576, 0, POSIX_FADV_DONTNEED) = 0 + #fadvise64(1, 1048576, 0, POSIX_FADV_DONTNEED) = 0 + advised_to_eof || fail=1 + + strace_dd if=in.f of=out.f bs=1M oflag=direct + #fadvise64(1, 1048576, 0, POSIX_FADV_DONTNEED) = 0 + #fadvise64(1, 1048576, 0, POSIX_FADV_DONTNEED) = 0 + advised_to_eof || fail=1 +fi + +Exit $fail diff --git a/tests/dd/not-rewound.sh b/tests/dd/not-rewound.sh new file mode 100755 index 0000000..60c93c0 --- /dev/null +++ b/tests/dd/not-rewound.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# Make sure dd does the right thing when the input file descriptor +# is not rewound. + +# Copyright (C) 2000-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + + +echo abcde > in +(dd skip=1 count=1 bs=1; dd skip=1 bs=1) < in > out 2> /dev/null || fail=1 +case $(cat out) in + bde) ;; + *) fail=1 ;; +esac + +Exit $fail diff --git a/tests/dd/reblock.sh b/tests/dd/reblock.sh new file mode 100755 index 0000000..ce3716c --- /dev/null +++ b/tests/dd/reblock.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# test dd reblocking vs. bs= + +# Copyright (C) 2008-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +# 2 short reads -> 1 full write + 1 partial write +cat <<\EOF > exp-reblock || framework_failure_ +0+2 records in +1+1 records out +4 bytes copied +EOF + +# 2 short reads -> 2 partial writes +cat <<\EOF > exp-no-reblock || framework_failure_ +0+2 records in +0+2 records out +4 bytes copied +EOF + + +# Use a fifo rather than a pipe in the tests below +# so that the producer (printf subshell) will wait +# until the consumer (dd) opens the fifo therefore +# increasing the chance that dd will read the data +# from each printf separately. +mkfifo_or_skip_ dd.fifo + +dd_reblock_1() +{ + local delay="$1" + + # ensure that dd reblocks when bs= is not specified + dd ibs=3 obs=3 if=dd.fifo > out 2> err& + (printf 'ab'; sleep $delay; printf 'cd') > dd.fifo + wait #for dd to complete + sed 's/,.*//' err > k && mv k err + compare exp-reblock err +} + +retry_delay_ dd_reblock_1 .1 6 || fail=1 + +dd_reblock_2() +{ + local delay="$1" + + # Demonstrate that bs=N supersedes even following ibs= and obs= settings. + dd bs=3 ibs=1 obs=1 if=dd.fifo > out 2> err& + (printf 'ab'; sleep $delay; printf 'cd') > dd.fifo + wait #for dd to complete + sed 's/,.*//' err > k && mv k err + compare exp-no-reblock err +} + +retry_delay_ dd_reblock_2 .1 6 || fail=1 + +Exit $fail diff --git a/tests/dd/skip-seek-past-dev.sh b/tests/dd/skip-seek-past-dev.sh new file mode 100755 index 0000000..55c8741 --- /dev/null +++ b/tests/dd/skip-seek-past-dev.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# test diagnostics are printed immediately when seeking beyond device. + +# Copyright (C) 2008-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +# need write access to local device +# (even though we don't actually write anything) +require_root_ +require_local_dir_ + +get_device_size() { + BLOCKDEV=blockdev + $BLOCKDEV -V >/dev/null 2>&1 || BLOCKDEV=/sbin/blockdev + $BLOCKDEV --getsize64 "$1" +} + + +# Get path to device the current dir is on. +# Note df can only get fs size, not device size. +device=$(df --output=source . | tail -n1) || framework_failure_ + +dev_size=$(get_device_size "$device") || + skip_ "failed to determine size of $device" + +# Don't use shell arithmetic as older versions of dash use longs +DEV_OFLOW=$(expr $dev_size + 1) || framework_failure_ + +timeout 10 dd bs=1 skip=$DEV_OFLOW count=0 status=noxfer < "$device" 2> err +test "$?" = "1" || fail=1 +echo "dd: 'standard input': cannot skip: Invalid argument +0+0 records in +0+0 records out" > err_ok || framework_failure_ +compare err_ok err || fail=1 + +timeout 10 dd bs=1 seek=$DEV_OFLOW count=0 status=noxfer > "$device" 2> err +test "$?" = "1" || fail=1 +echo "dd: 'standard output': cannot seek: Invalid argument +0+0 records in +0+0 records out" > err_ok || framework_failure_ +compare err_ok err || fail=1 + +Exit $fail diff --git a/tests/dd/skip-seek-past-file.sh b/tests/dd/skip-seek-past-file.sh new file mode 100755 index 0000000..e952448 --- /dev/null +++ b/tests/dd/skip-seek-past-file.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# test diagnostics are printed when seeking too far in seekable files. + +# Copyright (C) 2008-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd +require_sparse_support_ # for 'truncate --size=$OFF_T_MAX' +eval $(getlimits) # for OFF_T limits +export LC_ALL=C + +printf "1234" > file || framework_failure_ + +echo "\ +dd: 'standard input': cannot skip to specified offset +0+0 records in +0+0 records out" > skip_err || framework_failure_ + +# skipping beyond number of blocks in file should issue a warning +dd bs=1 skip=5 count=0 status=noxfer < file 2> err || fail=1 +compare skip_err err || fail=1 + +# skipping beyond number of bytes in file should issue a warning +dd bs=3 skip=2 count=0 status=noxfer < file 2> err || fail=1 +compare skip_err err || fail=1 + +# skipping beyond number of blocks in pipe should issue a warning +cat file | dd bs=1 skip=5 count=0 status=noxfer 2> err || fail=1 +compare skip_err err || fail=1 + +# skipping beyond number of bytes in pipe should issue a warning +cat file | dd bs=3 skip=2 count=0 status=noxfer 2> err || fail=1 +compare skip_err err || fail=1 + +# Check seeking beyond file already offset into +# skipping beyond number of blocks in file should issue a warning +(dd bs=1 skip=1 count=0 2>/dev/null && + dd bs=1 skip=4 status=noxfer 2> err) < file || fail=1 +compare skip_err err || fail=1 + +# Check seeking beyond file already offset into +# skipping beyond number of bytes in file should issue a warning +(dd bs=1 skip=1 count=0 2>/dev/null && + dd bs=2 skip=2 status=noxfer 2> err) < file || fail=1 +compare skip_err err || fail=1 + +# seeking beyond end of file is OK +dd bs=1 seek=5 count=0 status=noxfer > file 2> err || fail=1 +echo "0+0 records in +0+0 records out" > err_ok || framework_failure_ +compare err_ok err || fail=1 + +# skipping > OFF_T_MAX should fail immediately +dd bs=1 skip=$OFF_T_OFLOW count=0 status=noxfer < file 2> err && fail=1 +# error message should be "... invalid number: strerror(EOVERFLOW)" +grep "invalid number:" err >/dev/null || fail=1 +dd bs=1 skip=${OFF_T_OFLOW}x$OFF_T_OFLOW count=0 status=noxfer < file 2> err && + fail=1 +grep "invalid number:" err >/dev/null || fail=1 + +# skipping > max file size should fail immediately +if ! truncate --size=$OFF_T_MAX in 2>/dev/null; then + # truncate is to ensure file system doesn't actually support OFF_T_MAX files + dd bs=1 skip=$OFF_T_MAX count=0 status=noxfer < file 2> err \ + && lseek_ok=yes \ + || lseek_ok=no + + if test $lseek_ok = yes; then + # On Solaris 10 at least, lseek(>max file size) succeeds, + # so just check for the skip warning. + compare skip_err err || fail=1 + else + # On Linux kernels at least, lseek(>max file size) fails. + # error message should be "... cannot skip: strerror(EINVAL)" + grep "cannot skip:" err >/dev/null || fail=1 + fi +fi + +Exit $fail diff --git a/tests/dd/skip-seek.pl b/tests/dd/skip-seek.pl new file mode 100755 index 0000000..0fcb1cf --- /dev/null +++ b/tests/dd/skip-seek.pl @@ -0,0 +1,88 @@ +#!/usr/bin/perl +# Test dd's skip and seek options. + +# Copyright (C) 2000-2022 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 <https://www.gnu.org/licenses/>. + +use strict; + +(my $program_name = $0) =~ s|.*/||; + +# Turn off localization of executable's output. +@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; +my $out = 'out'; + +my @Tests = + ( + [ + 'sk-seek1', + qw (bs=1 skip=1 seek=2 conv=notrunc count=3 status=noxfer of=@AUX@ < ), + {IN=> '0123456789abcdef'}, + {AUX=> 'zyxwvutsrqponmlkji'}, + {OUT=> ''}, + {ERR=> "3+0 records in\n3+0 records out\n"}, + {CMP=> ['zy123utsrqponmlkji', {'@AUX@'=> undef}]}, + ], + [ + 'sk-seek2', + qw (bs=5 skip=1 seek=1 conv=notrunc count=1 status=noxfer of=@AUX@ < ), + {IN=> '0123456789abcdef'}, + {AUX=> 'zyxwvutsrqponmlkji'}, + {OUT=> ''}, + {ERR=> "1+0 records in\n1+0 records out\n"}, + {CMP=> ['zyxwv56789ponmlkji', {'@AUX@'=> undef}]}, + ], + [ + 'sk-seek3', + qw (bs=5 skip=1 seek=1 count=1 status=noxfer of=@AUX@ < ), + {IN=> '0123456789abcdef'}, + {AUX=> 'zyxwvutsrqponmlkji'}, + {OUT=> ''}, + {ERR=> "1+0 records in\n1+0 records out\n"}, + {CMP=> ['zyxwv56789', {'@AUX@'=> undef}]}, + ], + [ + # Before fileutils-4.0.45, the last 10 bytes of output + # were these "\0\0\0\0\0\0\0\0 ". + 'block-sync-1', qw(ibs=10 cbs=10 status=noxfer), 'conv=block,sync', '<', + {IN=> "01234567\nabcdefghijkl\n"}, + {OUT=> "01234567 abcdefghij "}, + {ERR=> "2+1 records in\n0+1 records out\n1 truncated record\n"}, + ], + [ + # Before coreutils-5.93, this would output just "c\n". + 'sk-seek4', qw(bs=1 skip=1 status=noxfer), + {IN_PIPE=> "abc\n"}, + {OUT=> "bc\n"}, + {ERR=> "3+0 records in\n3+0 records out\n"}, + ], + [ + # Check that iseek and oseek aliases work too. + 'sk-seek5', + qw (bs=1 iseek=1 oseek=2 conv=notrunc count=3 status=noxfer of=@AUX@ < ), + {IN=> '0123456789abcdef'}, + {AUX=> 'zyxwvutsrqponmlkji'}, + {OUT=> ''}, + {ERR=> "3+0 records in\n3+0 records out\n"}, + {CMP=> ['zy123utsrqponmlkji', {'@AUX@'=> undef}]}, + ], + ); + +my $save_temps = $ENV{DEBUG}; +my $verbose = $ENV{VERBOSE}; + +my $prog = 'dd'; +my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); +exit $fail; diff --git a/tests/dd/skip-seek2.sh b/tests/dd/skip-seek2.sh new file mode 100755 index 0000000..779e1b2 --- /dev/null +++ b/tests/dd/skip-seek2.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# show how to skip an amount that is smaller than the nominal block size. +# There's a more realistic example in the documentation. + +# Copyright (C) 2000-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + + +echo LA:3456789abcdef > in || framework_failure_ +(dd bs=1 skip=3 count=0 && dd bs=5) < in > out 2> /dev/null || fail=1 +case $(cat out) in + 3456789abcdef) ;; + *) fail=1 ;; +esac + +echo LA:3456789abcdef > in || framework_failure_ +(dd bs=1 skip=3 count=0 && dd bs=5 count=2) < in > out 2> /dev/null || fail=1 +case $(cat out) in + 3456789abc) ;; + *) fail=1 ;; +esac + +Exit $fail diff --git a/tests/dd/sparse.sh b/tests/dd/sparse.sh new file mode 100755 index 0000000..87477a0 --- /dev/null +++ b/tests/dd/sparse.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +# Copyright (C) 2012-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd +is_local_dir_ . || very_expensive_ +require_sparse_support_ + +# Ensure basic sparse generation works +truncate -s1M sparse +dd bs=32K if=sparse of=sparse.dd conv=sparse +test $(stat -c %s sparse) = $(stat -c %s sparse.dd) || fail=1 + +# Demonstrate that conv=sparse with oflag=append, +# will do ineffective seeks in the output +printf 'a\000\000b' > file.in +printf 'ab' > exp +dd if=file.in bs=1 conv=sparse oflag=append > out +compare exp out || fail=1 + +# Demonstrate conv=sparse with conv=notrunc, +# where data in file.out is not overwritten with NULs +printf '____' > out +printf 'a__b' > exp +dd if=file.in bs=1 conv=sparse,notrunc of=out +compare exp out || fail=1 + +# Ensure we fall back to write if seek fails +dd if=file.in bs=1 conv=sparse | cat > file.out +cmp file.in file.out || fail=1 + +# Setup for block size tests: create a 3MiB file with a 1MiB +# stretch of NUL bytes in the middle. +rm -f file.in +dd if=/dev/urandom of=file.in bs=1M count=3 iflag=fullblock || fail=1 +dd if=/dev/zero of=file.in bs=1M count=1 seek=1 conv=notrunc || fail=1 + +kb_alloc() { du -k "$1"|cut -f1; } + +# sync out data for async allocators like NFS/BTRFS +# sync file.in || fail=1 + +# If our just-created input file appears to be too small, +# skip the remaining tests. On at least Solaris 10 with NFS, +# file.in is reported to occupy <= 1KiB for about 50 seconds +# after its creation. +if test $(kb_alloc file.in) -gt 3000; then + + # Ensure NUL blocks smaller than the *output* block size are not made sparse. + # Here, with a 2MiB block size, dd's conv=sparse must *not* introduce a hole. + dd if=file.in of=file.out ibs=1M obs=2M conv=sparse || fail=1 + + # Intermittently BTRFS returns 0 allocation for file.out unless synced + sync file.out || framework_failure_ + test 2500 -lt $(kb_alloc file.out) || fail=1 + + # Note we recreate a sparse file first to avoid + # speculative preallocation seen in XFS, where a write() that + # extends a file can preallocate some extra space that + # a subsequent seek will not convert to a hole. + rm -f file.out + truncate --size=3M file.out + + # Ensure that this 1MiB *output* block of NULs *is* converted to a hole. + dd if=file.in of=file.out ibs=2M obs=1M conv=sparse,notrunc + if test $(kb_alloc file.out) -ge 2500; then + # Double check the failure by creating a sparse file in + # the traditional manner for comparison, as we're not guaranteed + # that seek=1M will create a hole. apfs on darwin 19.2.0 for example + # was seen to not to create holes < 16MiB. + dd if=file.in of=manual.out bs=1M count=1 || fail=1 + dd if=file.in of=manual.out bs=1M count=1 seek=2 conv=notrunc || fail=1 + + test $(kb_alloc file.out) -eq $(kb_alloc manual.out) || fail=1 + fi + +fi + +Exit $fail diff --git a/tests/dd/stats.sh b/tests/dd/stats.sh new file mode 100755 index 0000000..94df3bd --- /dev/null +++ b/tests/dd/stats.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# Check stats output for SIG{INFO,USR1} and status=progress + +# Copyright (C) 2014-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd +require_trap_signame_ + +kill -l | grep 'INFO' && SIGINFO='INFO' || SIGINFO='USR1' + +# This to avoid races in the USR1 case +# as the dd process will terminate by default until +# it has its handler enabled. +trap '' $SIGINFO + +mkfifo_or_skip_ fifo + +# Terminate any background processes +cleanup_() +{ + kill $pid 2>/dev/null + kill $pid2 2>/dev/null + wait +} + +for open in '' '1'; do + > err || framework_failure_ + + # Run dd with the fullblock iflag to avoid short reads + # which can be triggered by reception of signals + dd iflag=fullblock if=/dev/zero of=fifo count=50 bs=5000000 2>err & pid=$! + + # Note if we sleep here we give dd a chance to exec and block on open. + # Otherwise we're probably testing SIG_IGN in the forked shell or early dd. + test "$open" && sleep .1 + + # dd will block on open until fifo is opened for reading. + # Timeout in case dd goes away erroneously which we check for below. + timeout 60 sh -c 'wc -c < fifo > nwritten' & pid2=$! + + # Send lots of signals immediately to ensure dd not killed due + # to race setting handler, or blocking on open of fifo. + # Many signals also check that short reads are handled. + until ! kill -s $SIGINFO $pid 2>/dev/null; do + sleep .01 + done + + wait + + # Ensure all data processed and at least last status written + grep '250000000 bytes (250 MB, 238 MiB) copied' err || { cat err; fail=1; } +done + +progress_output() +{ + { sleep $1; echo 1; } | dd bs=1 status=progress of=/dev/null 2>err + # Progress output should be for "byte copied", while final is "bytes ..." + grep 'byte copied' err +} +retry_delay_ progress_output 1 4 || { cat err; fail=1; } + +Exit $fail diff --git a/tests/dd/stderr.sh b/tests/dd/stderr.sh new file mode 100755 index 0000000..93dd5a9 --- /dev/null +++ b/tests/dd/stderr.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# Ensure dd recognizes failure to write to stderr. + +# Copyright (C) 2009-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +p=$abs_top_builddir + + +# Ensure this exits successfully, even though stderr is closed, +# because it generates no stderr output. +dd --help >/dev/null 2>&- || fail=1 + +# If 2>&- works, ensure this fails, because stderr is closed and it +# *does* generate output. 2>&- apparently does not work in HP-UX 11.23. +# This test is ineffective unless /dev/stderr also works. +# This exposes a failure present in 6.11 through 7.5. +if "$p/src/test" -w /dev/stderr 2>/dev/null && + "$p/src/test" ! -w /dev/stderr 2>&-; then + : | returns_ 1 dd 2>&- || fail=1 +fi + +# Likewise for /dev/full, if /dev/full works. +if test -w /dev/full && test -c /dev/full; then + : | returns_ 1 dd 2>/dev/full || fail=1 +fi + +Exit $fail diff --git a/tests/dd/unblock-sync.sh b/tests/dd/unblock-sync.sh new file mode 100755 index 0000000..213dea0 --- /dev/null +++ b/tests/dd/unblock-sync.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# Ensure that dd conv=unblock,sync works. + +# Copyright (C) 2003-2022 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 <https://www.gnu.org/licenses/>. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ dd + +printf 000100020003xx > in || framework_failure_ + + +dd cbs=4 ibs=4 conv=unblock,sync < in > out 2> /dev/null || fail=1 +cat <<\EOF > exp || framework_failure_ +0001 +0002 +0003 +xx +EOF + +compare exp out || fail=1 + +Exit $fail diff --git a/tests/dd/unblock.pl b/tests/dd/unblock.pl new file mode 100755 index 0000000..08701b2 --- /dev/null +++ b/tests/dd/unblock.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# Exercise dd's conv=unblock mode + +# Copyright (C) 2009-2022 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 <https://www.gnu.org/licenses/>. + +use strict; + +(my $program_name = $0) =~ s|.*/||; + +# Turn off localization of executable's output. +@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; +my $out = 'out'; + +my @t = + ( + # An empty test name signals that these are the arguments to use for the + # following tests. + ['', [qw (cbs=3 conv=unblock status=noxfer < )]], + ['0', '', ''], + ['1', "a\n ", "a\n\n\n"], + ['2', "a\n ", "a\n\n"], + ['3', "a ", "a\n"], + ['4', "a \n ", "a \n\n\n"], + ['5', "a \n", "a \n\n"], + ['6', "a ", "a\n\n"], + ['7', "a \n", "a\n\n\n"], + ); + +my @Tests; +my $args; +foreach my $t (@t) + { + $t->[0] eq '' + and $args = $t->[1], next; + + push @Tests, [$t->[0], @$args, {IN=>$t->[1]}, {OUT=>$t->[2]}, + {ERR_SUBST=>'s/^\d+\+\d+ records (?:in|out)$//'}, + {ERR=>"\n\n"}]; + } + +my $save_temps = $ENV{DEBUG}; +my $verbose = $ENV{VERBOSE}; + +my $prog = 'dd'; +my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); +exit $fail; |