]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/nolibc: add the _syscall() macro
authorThomas Weißschuh <linux@weissschuh.net>
Sun, 5 Apr 2026 09:06:25 +0000 (11:06 +0200)
committerThomas Weißschuh <linux@weissschuh.net>
Tue, 7 Apr 2026 07:27:07 +0000 (09:27 +0200)
The standard syscall() function or macro uses the libc return value
convention. Errors returned from the kernel as negative values are
stored in errno and -1 is returned. Users who want to avoid using
errno don't have a way to call raw syscalls and check the returned
error.

Add a new macro _syscall() which works like the standard syscall()
but passes through the return value from the kernel unchanged.
The naming scheme and return values match the named _sys_foo()
system call wrappers already part of nolibc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260405-nolibc-syscall-v1-3-e5b12bc63211@weissschuh.net
tools/include/nolibc/sys/syscall.h
tools/testing/selftests/nolibc/nolibc-test.c

index 3f43fac3d7b899a14af474a5873dd65f705db03c..7f06314fcf0d5853d2ba049840f0f1abed44c707 100644 (file)
@@ -14,6 +14,7 @@
 #define __nolibc_syscall_narg(...) ___nolibc_syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
 #define __nolibc_syscall(N, ...) __nolibc_syscall##N(__VA_ARGS__)
 #define __nolibc_syscall_n(N, ...) __nolibc_syscall(N, __VA_ARGS__)
-#define syscall(...) __sysret(__nolibc_syscall_n(__nolibc_syscall_narg(__VA_ARGS__), ##__VA_ARGS__))
+#define _syscall(...) __nolibc_syscall_n(__nolibc_syscall_narg(__VA_ARGS__), ##__VA_ARGS__)
+#define syscall(...) __sysret(_syscall(__VA_ARGS__))
 
 #endif /* _NOLIBC_SYS_SYSCALL_H */
index dd10402267ee872181e72c86d719452fc9135bc7..4bcf4686760369a9c815ea7bb4fbc608f642d922 100644 (file)
@@ -95,6 +95,8 @@ static const int is_glibc =
 /* readdir_r() is likely to be marked deprecated */
 #undef readdir_r
 #define readdir_r(dir, dirent, result) ((errno = EINVAL), -1)
+
+#define _syscall(...) 0
 #endif
 
 /* definition of a series of tests */
@@ -1507,6 +1509,8 @@ int run_syscall(int min, int max)
                CASE_TEST(ptrace);            EXPECT_SYSER(1, ptrace(PTRACE_CONT, getpid(), NULL, NULL), -1, ESRCH); break;
                CASE_TEST(syscall_noargs);    EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break;
                CASE_TEST(syscall_args);      EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break;
+               CASE_TEST(_syscall_noargs);   EXPECT_SYSEQ(is_nolibc, _syscall(__NR_getpid), getpid()); break;
+               CASE_TEST(_syscall_args);     EXPECT_SYSEQ(is_nolibc, _syscall(__NR_statx, 0, NULL, 0, 0, NULL), -EFAULT); break;
                CASE_TEST(namespace);         EXPECT_SYSZR(euid0 && proc, test_namespace()); break;
                case __LINE__:
                        return ret; /* must be last */