| /* | |
| * Copyright (c) 2025 Alexey Dobriyan <adobriyan@gmail.com> | |
| * | |
| * Permission to use, copy, modify, and distribute this software for any | |
| * purpose with or without fee is hereby granted, provided that the above | |
| * copyright notice and this permission notice appear in all copies. | |
| * | |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
| * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
| * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
| * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
| * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| */ | |
| #undef _GNU_SOURCE | |
| #define _GNU_SOURCE | |
| #undef NDEBUG | |
| #include <assert.h> | |
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <sched.h> | |
| /* | |
| * Test that lseek("/proc/net/dev/", 0, SEEK_SET) | |
| * a) works, | |
| * b) does what you think it does. | |
| */ | |
| int main(void) | |
| { | |
| /* /proc/net/dev output is deterministic in fresh netns only. */ | |
| if (unshare(CLONE_NEWNET) == -1) { | |
| if (errno == ENOSYS || errno == EPERM) { | |
| return 4; | |
| } | |
| return 1; | |
| } | |
| const int fd = open("/proc/net/dev", O_RDONLY); | |
| assert(fd >= 0); | |
| char buf1[4096]; | |
| const ssize_t rv1 = read(fd, buf1, sizeof(buf1)); | |
| /* | |
| * Not "<=", this file can't be empty: | |
| * there is header, "lo" interface with some zeroes. | |
| */ | |
| assert(0 < rv1); | |
| assert(rv1 <= sizeof(buf1)); | |
| /* Believe it or not, this line broke one day. */ | |
| assert(lseek(fd, 0, SEEK_SET) == 0); | |
| char buf2[4096]; | |
| const ssize_t rv2 = read(fd, buf2, sizeof(buf2)); | |
| /* Not "<=", see above. */ | |
| assert(0 < rv2); | |
| assert(rv2 <= sizeof(buf2)); | |
| /* Test that lseek rewinds to the beginning of the file. */ | |
| assert(rv1 == rv2); | |
| assert(memcmp(buf1, buf2, rv1) == 0); | |
| /* Contents of the file is not validated: this test is about lseek(). */ | |
| return 0; | |
| } |