summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/splice/short_splice_read.sh
blob: 22b6c8910b182fd987402189add117ebc967b5e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Test for mishandling of splice() on pseudofilesystems, which should catch
# bugs like 11990a5bd7e5 ("module: Correctly truncate sysfs sections output")
#
# Since splice fallback was removed as part of the set_fs() rework, many of these
# tests expect to fail now. See https://lore.kernel.org/lkml/202009181443.C2179FB@keescook/
set -e

DIR=$(dirname "$0")

ret=0

expect_success()
{
	title="$1"
	shift

	echo "" >&2
	echo "$title ..." >&2

	set +e
	"$@"
	rc=$?
	set -e

	case "$rc" in
	0)
		echo "ok: $title succeeded" >&2
		;;
	1)
		echo "FAIL: $title should work" >&2
		ret=$(( ret + 1 ))
		;;
	*)
		echo "FAIL: something else went wrong" >&2
		ret=$(( ret + 1 ))
		;;
	esac
}

expect_failure()
{
	title="$1"
	shift

	echo "" >&2
	echo "$title ..." >&2

	set +e
	"$@"
	rc=$?
	set -e

	case "$rc" in
	0)
		echo "FAIL: $title unexpectedly worked" >&2
		ret=$(( ret + 1 ))
		;;
	1)
		echo "ok: $title correctly failed" >&2
		;;
	*)
		echo "FAIL: something else went wrong" >&2
		ret=$(( ret + 1 ))
		;;
	esac
}

do_splice()
{
	filename="$1"
	bytes="$2"
	expected="$3"
	report="$4"

	out=$("$DIR"/splice_read "$filename" "$bytes" | cat)
	if [ "$out" = "$expected" ] ; then
		echo "      matched $report" >&2
		return 0
	else
		echo "      no match: '$out' vs $report" >&2
		return 1
	fi
}

test_splice()
{
	filename="$1"

	echo "  checking $filename ..." >&2

	full=$(cat "$filename")
	rc=$?
	if [ $rc -ne 0 ] ; then
		return 2
	fi

	two=$(echo "$full" | grep -m1 . | cut -c-2)

	# Make sure full splice has the same contents as a standard read.
	echo "    splicing 4096 bytes ..." >&2
	if ! do_splice "$filename" 4096 "$full" "full read" ; then
		return 1
	fi

	# Make sure a partial splice see the first two characters.
	echo "    splicing 2 bytes ..." >&2
	if ! do_splice "$filename" 2 "$two" "'$two'" ; then
		return 1
	fi

	return 0
}

### /proc/$pid/ has no splice interface; these should all fail.
expect_failure "proc_single_open(), seq_read() splice" test_splice /proc/$$/limits
expect_failure "special open(), seq_read() splice" test_splice /proc/$$/comm

### /proc/sys/ has a splice interface; these should all succeed.
expect_success "proc_handler: proc_dointvec_minmax() splice" test_splice /proc/sys/fs/nr_open
expect_success "proc_handler: proc_dostring() splice" test_splice /proc/sys/kernel/modprobe
expect_success "proc_handler: special read splice" test_splice /proc/sys/kernel/version

### /sys/ has no splice interface; these should all fail.
if ! [ -d /sys/module/test_module/sections ] ; then
	expect_success "test_module kernel module load" modprobe test_module
fi
expect_failure "kernfs attr splice" test_splice /sys/module/test_module/coresize
expect_failure "kernfs binattr splice" test_splice /sys/module/test_module/sections/.init.text

exit $ret