It’s in net/socket.c
, line 1747 of v3.10-rc7.
/*
* Send a datagram to a given address. We move the address into kernel
* space and check the user space data area is readable before invoking
* the protocol.
*/
SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
unsigned int, flags, struct sockaddr __user *, addr,
int, addr_len)
{
struct socket *sock;
struct sockaddr_storage address;
...
The SYSCALL_DEFINE6
macro is the macro for defining syscalls that take six arguments. It’s defined in include/linux/syscalls.h
. It’s pretty complicated, so let’s start by looking at what happens in the no-argument version:
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
asmlinkage long sys_##sname(void)
A system call like getuid()
, defined in kernel/sys.c
, is coded like this:
SYSCALL_DEFINE0(getuid)
{
/* Only we change this so SMP safe */
return from_kuid_munged(current_user_ns(), current_uid());
}
The macro expands out to
SYSCALL_METADATA(_##sname, 0);
asmlinkage long sys_getuid(void)
{
/* Only we change this so SMP safe */
return from_kuid_munged(current_user_ns(), current_uid());
}
Which is a straightforward definition of the function sys_getuid
.
The metadata is optionally compiled into the kernel for tracing. See the source in syscalls.h
for the details.