summaryrefslogtreecommitdiff
path: root/tools/testing/selftests
diff options
context:
space:
mode:
authorThomas Weißschuh <linux@weissschuh.net>2026-09-27 10:49:16 +0200
committerThomas Weißschuh <linux@weissschuh.net>2026-09-27 11:32:20 +0200
commitda27722051fdf0775d8c5b3e33dc21bcf605dbd4 (patch)
treeece4fa7a1d6d9a4808f332627ad3926eebd492a6 /tools/testing/selftests
parentabafa291e52ac95c46ba0744b64e4d0d3adae4b7 (diff)
downloadlinux-next-da27722051fdf0775d8c5b3e33dc21bcf605dbd4.tar.gz
linux-next-da27722051fdf0775d8c5b3e33dc21bcf605dbd4.zip
tools/nolibc: add support for pread() and pwrite()
These are standard function to interact with a file descriptor without touching its internal file offset. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Reviewed-by: Willy Tarreau <w@1wt.eu> Link: https://patch.msgid.link/20260927-nolibc-pread-v1-5-e9af6e47b37a@weissschuh.net
Diffstat (limited to 'tools/testing/selftests')
-rw-r--r--tools/testing/selftests/nolibc/nolibc-test.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index c344675ad0c9..f3d0d27cdbe1 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1369,6 +1369,51 @@ int test_pipe(void)
return !!memcmp(buf, msg, len);
}
+int test_pwrite_pread(void)
+{
+ const off_t offset = (0x12ULL << 32) | 0x34;
+ ssize_t ret;
+ char buf[2];
+ int fd, err;
+ off_t offs;
+
+ fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
+ if (fd == -1)
+ return __LINE__;
+
+ /* Write into the middle of the file. */
+ ret = pwrite(fd, "abc", 3, offset);
+ if (ret != 3) {
+ err = __LINE__;
+ goto out;
+ }
+
+ /* Make sure the file offset points somewhere else before pread(). */
+ offs = lseek(fd, 0, SEEK_END);
+ if (offs != offset + 3) {
+ err = __LINE__;
+ goto out;
+ }
+
+ ret = pread(fd, buf, 2, offset + 1);
+ if (ret != 2) {
+ err = __LINE__;
+ goto out;
+ }
+
+ if (buf[0] != 'b' || buf[1] != 'c') {
+ err = __LINE__;
+ goto out;
+ }
+
+ err = 0;
+
+out:
+ close(fd);
+
+ return err;
+}
+
int test_rlimit(void)
{
struct rlimit rlim = {
@@ -1746,6 +1791,7 @@ int run_syscall(int min, int max)
CASE_TEST(poll_stdout); EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;
CASE_TEST(poll_fault); EXPECT_SYSER(1, poll(NULL, 1, 0), -1, EFAULT); break;
CASE_TEST(prctl); EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;
+ CASE_TEST(pwrite_pread); EXPECT_SYSZR(has_working_64bit_syscall_arg, test_pwrite_pread()); break;
CASE_TEST(read_badf); EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;
CASE_TEST(rlimit); EXPECT_SYSZR(1, test_rlimit()); break;
CASE_TEST(rmdir_blah); EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break;