1#!/bin/sh 2# Test whether sort avoids opening more file descriptors than it is 3# allowed when merging files. 4 5# Copyright (C) 2009-2023 Free Software Foundation, Inc. 6 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <https://www.gnu.org/licenses/>. 19 20. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 21print_ver_ sort 22 23mkdir in err || framework_failure_ 24 25 26for i in $(seq 17); do 27 echo $i >in/$i 28done 29seq 17 >some-data 30 31# When these tests are run inside the automated testing framework, they 32# have one less available file descriptor than when run outside the 33# automated testing framework. If a test with a batch size of b fails 34# inside the ATF, then the same test with batch size b+1 may pass outside 35# the ATF but fail inside it. 36 37# The default batch size (nmerge) is 16. 38(ulimit -n 19 \ 39 && sort -m --batch-size=16 in/* 2>err/merge-default-err \ 40 || ! grep "open failed" err/merge-default-err) || fail=1 41 42# If sort opens a file to sort by random hashes of keys, 43# it needs to consider this file against its limit on open file 44# descriptors. Test once with the default random source 45# and once with an explicit source. 46for randsource in '' --random-source=some-data; do 47 (ulimit -n 20 \ 48 && sort -mR $randsource --batch-size=16 in/* 2>err/merge-random-err \ 49 || ! grep "open failed" err/merge-random-err) || fail=1 50done 51 52# 'sort -m' should work in a limited file descriptor 53# environment when the output is repeatedly one of its inputs. 54# In coreutils 8.7 and earlier, 'sort' would dump core on this test. 55# 56# This test uses 'exec' to redirect file descriptors rather than 57# ordinary redirection on the 'sort' command. This is intended to 58# work around bugs in OpenBSD /bin/sh, and some other sh variants, 59# that squirrel away file descriptors before closing them; see 60# <https://lists.gnu.org/r/bug-tar/2010-10/msg00075.html>. 61# This test finds the bug only with shells that do not close FDs on 62# exec, and will miss the bug (if present) on other shells, but it's 63# not easy to fix this without running afoul of the OpenBSD-like sh bugs. 64# 65# This script uses 'ulimit -n 10' with 7, 8 and 9 open 66# to limit 'sort' to at most 7 open files: 67# stdin, stdout, stderr, two input and one output files when merging, 68# and an extra. The extra is for old-fashioned platforms like Solaris 10 69# where opening a temp file also requires opening /dev/urandom to 70# calculate the temp file's name. 71(seq 6 && echo 6) >exp || framework_failure_ 72echo 6 >out || framework_failure_ 73(exec 3<&- 4<&- 5<&- 6<&- 7</dev/null 8<&7 9<&7 && 74 ulimit -n 10 && 75 sort -n -m --batch-size=7 -o out out in/1 in/2 in/3 in/4 in/5 out 76) && 77compare exp out || fail=1 78 79Exit $fail 80