Commit 53fcfafa authored by Thomas Weißschuh's avatar Thomas Weißschuh Committed by Paul E. McKenney
Browse files

tools/nolibc/unistd: add syscall()



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: default avatarThomas Weißschuh <linux@weissschuh.net>
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent c22c7c81
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -56,6 +56,21 @@ int tcsetpgrp(int fd, pid_t pid)
	return ioctl(fd, TIOCSPGRP, &pid);
}

#define _syscall(N, ...)                                                      \
({                                                                            \
	long _ret = my_syscall##N(__VA_ARGS__);                               \
	if (_ret < 0) {                                                       \
		SET_ERRNO(-_ret);                                             \
		_ret = -1;                                                    \
	}                                                                     \
	_ret;                                                                 \
})

#define _syscall_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(_syscall_narg(__VA_ARGS__), ##__VA_ARGS__)

/* make sure to include all global symbols */
#include "nolibc.h"

+2 −0
Original line number Diff line number Diff line
@@ -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 */