From 0da4d843003e9d38624e19c24c7fb670f1bb4749 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 13 Dec 2010 23:23:17 -0800 Subject: sort: fix some --compress reaper bugs * src/sort.c (uintptr): New type. (enum procstate, struct procnode, update_proc): Remove. (proctab_hasher, proctab_comparator, register_proc, wait_proc): (reap_some): The proctab is now simply a hash of process-IDs rather than of pointers to objects with reference counts and states; this is smaller and faster and easier to understand. (nprocs): Now pid_t, not size_t, since one cannot have more than PID_MAX children. (reap): If the argument is -1, wait; if 0 (a new value), do not. Delete pid from proctab as needed. Ignore children that are not in proctab, as they are from the program that exec'ed us and are irrelevant to our success or failure. (delete_proc, reap_all): New functions. (open_temp): Register the child. (sort): Clean up all children afterwards; without this patch, 'sort' sometimes missed failures in children due to race conditions. * tests/Makefile.am (TESTS): Add misc/sort-compress-proc. * tests/misc/sort-compress-proc: New file, to test for the bugs fixed above. --- tests/Makefile.am | 1 + tests/misc/sort-compress-proc | 87 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100755 tests/misc/sort-compress-proc (limited to 'tests') diff --git a/tests/Makefile.am b/tests/Makefile.am index f7a8af8ae..de0670485 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -228,6 +228,7 @@ TESTS = \ misc/sort \ misc/sort-benchmark-random \ misc/sort-compress \ + misc/sort-compress-proc \ misc/sort-continue \ misc/sort-debug-keys \ misc/sort-debug-warn \ diff --git a/tests/misc/sort-compress-proc b/tests/misc/sort-compress-proc new file mode 100755 index 000000000..8d0094f13 --- /dev/null +++ b/tests/misc/sort-compress-proc @@ -0,0 +1,87 @@ +#!/bin/sh +# Test use of compression subprocesses by sort + +# Copyright (C) 2010 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 . + +. "${srcdir=.}/init.sh"; path_prepend_ ../src +print_ver_ sort +expensive_ + +# Ensure that $TMPDIR is valid. +if test -d /tmp && test -w /tmp +then TMPDIR=/tmp +else TMPDIR=. +fi +export TMPDIR + +seq -w 2000 > exp || fail=1 +tac exp > in || fail=1 +insize=$(stat -c %s - compress || framework_failure +#!/bin/sh +eval "$PRE_COMPRESS" +tr 41 14 || exit +eval "$POST_COMPRESS" +EOF + +chmod +x compress + +# "Impatient exit" tests +# +# In these test cases, the biggest compressor (or decompressor) exits +# with nonzero status, after sleeping a bit. Until coreutils 8.7 +# 'sort' impatiently exited without waiting for its decompression +# subprocesses in these cases. Check compression too, while we're here. +# +for compress_arg in '' '-d' +do + POST_COMPRESS=' + test "X$1" != "X'$compress_arg'" || { + test "X$1" = "X" && exec <&1 + size=$(stat -c %s -) + exec >/dev/null 2>&1 <&1 || exit + expr $size "<" '"$insize"' / 2 || { sleep 1; exit 1; } + } + ' sort --compress-program=./compress -S 1k --batch-size=2 in > out && fail=1 +done + +# "Pre-exec child" test +# +# Ignore a random child process created before 'sort' was exec'ed. +# This bug was also present in coreutils 8.7. +# +( (sleep 1; exec false) & + PRE_COMPRESS='test -f ok || sleep 2' + POST_COMPRESS='touch ok' + exec sort --compress-program=./compress -S 1k in >out +) || fail=1 +compare exp out || fail=1 +test -f ok || fail=1 +rm -f ok + +rm -f compress + +# Give compression subprocesses time to react when 'sort' exits. +# Otherwise, under NFS, when 'sort' unlinks the temp files and they +# are renamed to .nfsXXXX instead of being removed, the parent cleanup +# of this directory will fail because the files are still open. +sleep 1 + +Exit $fail -- cgit v1.2.3-54-g00ecf