1#!/bin/sh
2# Test use of compression subprocesses by sort
3
4# Copyright (C) 2010-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_ sort
21expensive_
22
23# Terminate any background processes
24cleanup_() { kill $pid 2>/dev/null && wait $pid; }
25
26SORT_FAILURE=2
27
28seq -w 2000 > exp || fail=1
29tac exp > in || fail=1
30insize=$(stat -c %s - <in) || fail=1
31
32# This compressor's behavior is adjustable via environment variables.
33export PRE_COMPRESS=
34export POST_COMPRESS=
35
36printf '%s\n' '#!'"$SHELL" >compress || framework_failure_
37cat <<\EOF >>compress || framework_failure_
38eval "$PRE_COMPRESS"
39tr 41 14 || exit
40eval "$POST_COMPRESS"
41EOF
42
43chmod +x compress
44
45# "Impatient exit" tests
46#
47# In these test cases, the biggest compressor (or decompressor) exits
48# with nonzero status, after sleeping a bit.  Until coreutils 8.7
49# 'sort' impatiently exited without waiting for its decompression
50# subprocesses in these cases.  Check compression too, while we're here.
51#
52for compress_arg in '' '-d'
53do
54  POST_COMPRESS='
55    test "X$1" != "X'$compress_arg'" || {
56      test "X$1" = "X" && exec <&1
57      size=$(stat -c %s -)
58      exec >/dev/null 2>&1 <&1 || exit
59      expr $size "<" '"$insize"' / 2 || { sleep 1; exit 1; }
60    }
61  ' sort --compress-program=./compress -S 1k --batch-size=2 in > out
62  test $? -eq $SORT_FAILURE || fail=1
63done
64
65# "Pre-exec child" test
66#
67# Ignore a random child process created before 'sort' was exec'ed.
68# This bug was also present in coreutils 8.7.
69#
70( (sleep 1; exec false) & pid=$!
71  PRE_COMPRESS='test -f ok || sleep 2'
72  POST_COMPRESS='touch ok'
73  exec sort --compress-program=./compress -S 1k in >out
74) || fail=1
75compare exp out || fail=1
76test -f ok || fail=1
77rm -f ok
78
79rm -f compress
80
81# If $TMPDIR is relative, give subprocesses time to react when 'sort' exits.
82# Otherwise, under NFS, when 'sort' unlinks the temp files and they
83# are renamed to .nfsXXXX instead of being removed, the parent cleanup
84# of this directory will fail because the files are still open.
85case $TMPDIR in
86/*) ;;
87*) sleep 1;;
88esac
89
90Exit $fail
91