xref: /linux/tools/testing/selftests/proc/proc-net-dev-lseek.c (revision b1e34412998d628dfa8ba3da042bb60dee232b6c)
1*b1e34412SAlexey Dobriyan /*
2*b1e34412SAlexey Dobriyan  * Copyright (c) 2025 Alexey Dobriyan <adobriyan@gmail.com>
3*b1e34412SAlexey Dobriyan  *
4*b1e34412SAlexey Dobriyan  * Permission to use, copy, modify, and distribute this software for any
5*b1e34412SAlexey Dobriyan  * purpose with or without fee is hereby granted, provided that the above
6*b1e34412SAlexey Dobriyan  * copyright notice and this permission notice appear in all copies.
7*b1e34412SAlexey Dobriyan  *
8*b1e34412SAlexey Dobriyan  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*b1e34412SAlexey Dobriyan  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*b1e34412SAlexey Dobriyan  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*b1e34412SAlexey Dobriyan  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*b1e34412SAlexey Dobriyan  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*b1e34412SAlexey Dobriyan  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*b1e34412SAlexey Dobriyan  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*b1e34412SAlexey Dobriyan  */
16*b1e34412SAlexey Dobriyan #undef _GNU_SOURCE
17*b1e34412SAlexey Dobriyan #define _GNU_SOURCE
18*b1e34412SAlexey Dobriyan #undef NDEBUG
19*b1e34412SAlexey Dobriyan #include <assert.h>
20*b1e34412SAlexey Dobriyan #include <errno.h>
21*b1e34412SAlexey Dobriyan #include <fcntl.h>
22*b1e34412SAlexey Dobriyan #include <string.h>
23*b1e34412SAlexey Dobriyan #include <unistd.h>
24*b1e34412SAlexey Dobriyan #include <sched.h>
25*b1e34412SAlexey Dobriyan /*
26*b1e34412SAlexey Dobriyan  * Test that lseek("/proc/net/dev/", 0, SEEK_SET)
27*b1e34412SAlexey Dobriyan  * a) works,
28*b1e34412SAlexey Dobriyan  * b) does what you think it does.
29*b1e34412SAlexey Dobriyan  */
30*b1e34412SAlexey Dobriyan int main(void)
31*b1e34412SAlexey Dobriyan {
32*b1e34412SAlexey Dobriyan 	/* /proc/net/dev output is deterministic in fresh netns only. */
33*b1e34412SAlexey Dobriyan 	if (unshare(CLONE_NEWNET) == -1) {
34*b1e34412SAlexey Dobriyan 		if (errno == ENOSYS || errno == EPERM) {
35*b1e34412SAlexey Dobriyan 			return 4;
36*b1e34412SAlexey Dobriyan 		}
37*b1e34412SAlexey Dobriyan 		return 1;
38*b1e34412SAlexey Dobriyan 	}
39*b1e34412SAlexey Dobriyan 
40*b1e34412SAlexey Dobriyan 	const int fd = open("/proc/net/dev", O_RDONLY);
41*b1e34412SAlexey Dobriyan 	assert(fd >= 0);
42*b1e34412SAlexey Dobriyan 
43*b1e34412SAlexey Dobriyan 	char buf1[4096];
44*b1e34412SAlexey Dobriyan 	const ssize_t rv1 = read(fd, buf1, sizeof(buf1));
45*b1e34412SAlexey Dobriyan 	/*
46*b1e34412SAlexey Dobriyan 	 * Not "<=", this file can't be empty:
47*b1e34412SAlexey Dobriyan 	 * there is header, "lo" interface with some zeroes.
48*b1e34412SAlexey Dobriyan 	 */
49*b1e34412SAlexey Dobriyan 	assert(0 < rv1);
50*b1e34412SAlexey Dobriyan 	assert(rv1 <= sizeof(buf1));
51*b1e34412SAlexey Dobriyan 
52*b1e34412SAlexey Dobriyan 	/* Believe it or not, this line broke one day. */
53*b1e34412SAlexey Dobriyan 	assert(lseek(fd, 0, SEEK_SET) == 0);
54*b1e34412SAlexey Dobriyan 
55*b1e34412SAlexey Dobriyan 	char buf2[4096];
56*b1e34412SAlexey Dobriyan 	const ssize_t rv2 = read(fd, buf2, sizeof(buf2));
57*b1e34412SAlexey Dobriyan 	/* Not "<=", see above. */
58*b1e34412SAlexey Dobriyan 	assert(0 < rv2);
59*b1e34412SAlexey Dobriyan 	assert(rv2 <= sizeof(buf2));
60*b1e34412SAlexey Dobriyan 
61*b1e34412SAlexey Dobriyan 	/* Test that lseek rewinds to the beginning of the file. */
62*b1e34412SAlexey Dobriyan 	assert(rv1 == rv2);
63*b1e34412SAlexey Dobriyan 	assert(memcmp(buf1, buf2, rv1) == 0);
64*b1e34412SAlexey Dobriyan 
65*b1e34412SAlexey Dobriyan 	/* Contents of the file is not validated: this test is about lseek(). */
66*b1e34412SAlexey Dobriyan 
67*b1e34412SAlexey Dobriyan 	return 0;
68*b1e34412SAlexey Dobriyan }
69