1#!/bin/sh 2# make sure that dd doesn't allocate memory unnecessarily 3 4# Copyright (C) 2013-2023 Free Software Foundation, Inc. 5 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <https://www.gnu.org/licenses/>. 18 19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 20print_ver_ dd 21 22# Determine basic amount of memory needed. 23echo . > f || framework_failure_ 24vm=$(get_min_ulimit_v_ timeout 10 dd if=f of=f2 status=none) \ 25 || skip_ "this shell lacks ulimit support" 26rm f f2 || framework_failure_ 27 28# count and skip are zero, we don't need to allocate memory 29(ulimit -v $vm && dd bs=30M count=0) || fail=1 30(ulimit -v $vm && dd ibs=30M count=0) || fail=1 31(ulimit -v $vm && dd obs=30M count=0) || fail=1 32 33check_dd_seek_alloc() { 34 local file="$1" 35 local buf="$2" 36 test "$file" = 'in' && { dd_file=if; dd_op=skip; } 37 test "$file" = 'out' && { dd_file=of; dd_op=seek; } 38 test "$buf" = 'in' && { dd_buf=ibs; } 39 test "$buf" = 'out' && { dd_buf=obs; } 40 test "$buf" = 'both' && { dd_buf=bs; } 41 42 # Provide input to the "tape" 43 timeout 10 dd count=1 if=/dev/zero of=tape& 44 45 # Allocate buffer and read from the "tape" 46 (ulimit -v $vm \ 47 && timeout 10 dd $dd_buf=30M $dd_op=1 count=0 $dd_file=tape) 48 local ret=$? 49 50 # Be defensive in case the tape reader is blocked for some reason 51 test $ret = 124 && framework_failure_ 52 53 # This should happen without delay, 54 # and is used to ensure we've not multiple writers to the "tape" 55 wait 56 57 # We want the "tape" reader to fail iff allocating 58 # a large buffer corresponding to the file being read 59 case "$file$buf" in 60 inout|outin) test $ret = 0;; 61 *) test $ret != 0;; 62 esac 63} 64 65# Use a fifo for which seek fails, but read does not. 66# For non seekable output we need to allocate a buffer 67# when simulating seeking with a read. 68if mkfifo tape; then 69 for file in 'in' 'out'; do 70 for buf in 'both' 'in' 'out'; do 71 check_dd_seek_alloc "$file" "$buf" || fail=1 72 done 73 done 74fi 75 76Exit $fail 77