1#!/bin/sh 2# Ensure we handle i/o errors correctly in csplit 3 4# Copyright (C) 2015-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_ csplit 21require_gcc_shared_ 22 23if ! test -w /dev/full || ! test -c /dev/full; then 24 skip_ '/dev/full is required' 25fi 26 27# Ensure error messages are in English 28LC_ALL=C 29export LC_ALL 30 31# Replace fwrite and ferror, always returning an error 32cat > k.c <<'EOF' || framework_failure_ 33#include <stdio.h> 34#include <errno.h> 35 36#undef fwrite 37#undef fwrite_unlocked 38 39size_t 40fwrite (const void *ptr, size_t size, size_t nitems, FILE *stream) 41{ 42 if (stream == stderr) 43 { 44 /* Perform the normal operation of fwrite. */ 45 const char *p = ptr; 46 size_t count = size * nitems; 47 size_t i; 48 for (i = 0; i < count; i++) 49 if (putc ((unsigned char) *p++, stream) == EOF) 50 break; 51 return i / size; 52 } 53 else 54 { 55 fclose (fopen ("preloaded","w")); /* marker for preloaded interception */ 56 errno = ENOSPC; 57 return 0; 58 } 59} 60 61size_t 62fwrite_unlocked (const void *ptr, size_t size, size_t nitems, FILE *stream) 63{ 64 return fwrite (ptr, size, nitems, stream); 65} 66EOF 67 68# Get the wording of the OS-dependent ENOSPC message 69returns_ 1 seq 1 >/dev/full 2>msgt || framework_failure_ 70sed 's/seq: write error: //' msgt > msg || framework_failure_ 71 72# Create the expected error message 73{ printf "%s" "csplit: write error for 'xx01': " ; cat msg ; } > exp \ 74 || framework_failure_ 75 76# compile/link the interception shared library: 77gcc_shared_ k.c k.so \ 78 || skip_ 'failed to build forced-fwrite-failure shared library' 79 80# Split the input, and force fwrite() failure - 81# the 'csplit' command should fail with exit code 1 82# (checked with 'returns_ 1 ... || fail=1') 83seq 10 | 84(export LD_PRELOAD=$LD_PRELOAD:./k.so 85 returns_ 1 csplit - 1 4 2>out) || fail=1 86 87test -e preloaded || skip_ 'LD_PRELOAD interception failed' 88 89# Ensure we got the expected error message 90compare exp out || fail=1 91 92Exit $fail 93