Commit 2eb64b93 authored by Thomas Weißschuh's avatar Thomas Weißschuh
Browse files

tools/nolibc: add the _syscall() macro



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: default avatarThomas Weißschuh <linux@weissschuh.net>
Acked-by: default avatarWilly Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260405-nolibc-syscall-v1-3-e5b12bc63211@weissschuh.net
parent 022bbb5a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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 */
+4 −0
Original line number Diff line number Diff line
@@ -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 */