syscall() is used by "normal" libcs to allow users to directly call syscalls. By having the same syntax inside nolibc users can more easily write code that works with different libcs.
The macro logic is adapted from systemtaps STAP_PROBEV() macro that is released in the public domain / CC0.
Signed-off-by: Thomas Weißschuh linux@weissschuh.net --- tools/include/nolibc/unistd.h | 15 +++++++++++++++ tools/testing/selftests/nolibc/nolibc-test.c | 2 ++ 2 files changed, 17 insertions(+)
diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h index ac7d53d986cd..6773e83c16a0 100644 --- a/tools/include/nolibc/unistd.h +++ b/tools/include/nolibc/unistd.h @@ -56,6 +56,21 @@ int tcsetpgrp(int fd, pid_t pid) return ioctl(fd, TIOCSPGRP, &pid); }
+#define _syscall(N, ...) \ +({ \ + int _ret = my_syscall##N(__VA_ARGS__); \ + if (_ret < 0) { \ + SET_ERRNO(-_ret); \ + _ret = -1; \ + } \ + _ret; \ +}) + +#define _sycall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) +#define __syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N +#define _syscall_n(N, ...) _syscall(N, __VA_ARGS__) +#define syscall(...) _syscall_n(_sycall_narg(__VA_ARGS__), ##__VA_ARGS__) + /* make sure to include all global symbols */ #include "nolibc.h"
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index f042a6436b6b..54bf91847af3 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -588,6 +588,8 @@ int run_syscall(int min, int max) CASE_TEST(waitpid_child); EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break; CASE_TEST(write_badf); EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break; CASE_TEST(write_zero); EXPECT_SYSZR(1, write(1, &tmp, 0)); break; + CASE_TEST(syscall_noargs); EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break; + CASE_TEST(syscall_args); EXPECT_SYSER(1, syscall(__NR_fstat, 0, NULL), -1, EFAULT); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */
--- base-commit: 063dcc53b416ae1e89f767330feab3d0842943ed change-id: 20230517-nolibc-syscall-bd13da6468c6
Best regards,
On Sat, May 20, 2023 at 09:58:57AM +0200, Thomas Weißschuh wrote:
syscall() is used by "normal" libcs to allow users to directly call syscalls. By having the same syntax inside nolibc users can more easily write code that works with different libcs.
The macro logic is adapted from systemtaps STAP_PROBEV() macro that is released in the public domain / CC0.
Well done! And now queued, thanks Thomas! Willy
linux-kselftest-mirror@lists.linaro.org