mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
Noux: add recvfrom()
Add SYSTEMCALL_RECVFROM to noux/net and the corresponding libc function. Fixes #290.
This commit is contained in:
parent
d28465cb3a
commit
7e26c79455
@ -66,6 +66,7 @@ namespace Noux {
|
||||
SYSCALL_SEND,
|
||||
SYSCALL_SENDTO,
|
||||
SYSCALL_RECV,
|
||||
SYSCALL_RECVFROM,
|
||||
SYSCALL_GETPEERNAME,
|
||||
SYSCALL_SHUTDOWN,
|
||||
SYSCALL_CONNECT,
|
||||
@ -108,6 +109,7 @@ namespace Noux {
|
||||
NOUX_DECL_SYSCALL_NAME(SEND)
|
||||
NOUX_DECL_SYSCALL_NAME(SENDTO)
|
||||
NOUX_DECL_SYSCALL_NAME(RECV)
|
||||
NOUX_DECL_SYSCALL_NAME(RECVFROM)
|
||||
NOUX_DECL_SYSCALL_NAME(GETPEERNAME)
|
||||
NOUX_DECL_SYSCALL_NAME(SHUTDOWN)
|
||||
NOUX_DECL_SYSCALL_NAME(CONNECT)
|
||||
|
@ -380,6 +380,10 @@ namespace Noux {
|
||||
SYSIO_DECL(recv, { int fd; Chunk buf; size_t len; int flags; },
|
||||
{ size_t len; });
|
||||
|
||||
SYSIO_DECL(recvfrom, { int fd; Chunk buf; size_t len; int flags;
|
||||
struct sockaddr src_addr; socklen_t addrlen; },
|
||||
{ size_t len; });
|
||||
|
||||
SYSIO_DECL(shutdown, { int fd; int how; }, { });
|
||||
|
||||
SYSIO_DECL(connect, { int fd; struct sockaddr addr; socklen_t addrlen; },
|
||||
|
@ -583,6 +583,8 @@ namespace {
|
||||
ssize_t sendto(Libc::File_descriptor *, const void *, size_t, int,
|
||||
const struct sockaddr *, socklen_t);
|
||||
ssize_t recv(Libc::File_descriptor *, void *, ::size_t, int);
|
||||
ssize_t recvfrom(Libc::File_descriptor *, void *, ::size_t, int,
|
||||
struct sockaddr *, socklen_t*);
|
||||
int getsockopt(Libc::File_descriptor *, int, int, void *,
|
||||
socklen_t *);
|
||||
int setsockopt(Libc::File_descriptor *, int , int , const void *,
|
||||
@ -1324,9 +1326,9 @@ namespace {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::memcpy(buf, sysio()->recv_in.buf, sysio()->recv_in.len);
|
||||
Genode::memcpy(buf, sysio()->recv_in.buf, sysio()->recv_out.len);
|
||||
|
||||
sum_recv_count += sysio()->recv_in.len;
|
||||
sum_recv_count += sysio()->recv_out.len;
|
||||
|
||||
if (sysio()->recv_out.len < sysio()->recv_in.len)
|
||||
break;
|
||||
@ -1341,6 +1343,50 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::recvfrom(Libc::File_descriptor *fd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen)
|
||||
{
|
||||
Genode::size_t sum_recvfrom_count = 0;
|
||||
|
||||
|
||||
while (len) {
|
||||
Genode::size_t curr_len = Genode::min(len, sizeof(sysio()->recvfrom_in.buf));
|
||||
|
||||
sysio()->recv_in.fd = noux_fd(fd->context);
|
||||
sysio()->recv_in.len = curr_len;
|
||||
|
||||
if (addrlen == NULL)
|
||||
sysio()->recvfrom_in.addrlen = 0;
|
||||
else
|
||||
sysio()->recvfrom_in.addrlen = *addrlen;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_RECVFROM)) {
|
||||
/* XXX set errno */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src_addr != NULL && addrlen != NULL)
|
||||
Genode::memcpy(src_addr, &sysio()->recvfrom_in.src_addr,
|
||||
sysio()->recvfrom_in.addrlen);
|
||||
|
||||
|
||||
Genode::memcpy(buf, sysio()->recvfrom_in.buf, sysio()->recvfrom_out.len);
|
||||
|
||||
sum_recvfrom_count += sysio()->recvfrom_out.len;
|
||||
|
||||
if (sysio()->recvfrom_out.len < sysio()->recvfrom_in.len)
|
||||
break;
|
||||
|
||||
if (sysio()->recvfrom_out.len <= len)
|
||||
len -= sysio()->recvfrom_out.len;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return sum_recvfrom_count;
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::send(Libc::File_descriptor *fd, const void *buf, ::size_t len, int flags)
|
||||
{
|
||||
/* remember original len for the return value */
|
||||
|
@ -483,6 +483,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
case SYSCALL_SEND:
|
||||
case SYSCALL_SENDTO:
|
||||
case SYSCALL_RECV:
|
||||
case SYSCALL_RECVFROM:
|
||||
case SYSCALL_GETPEERNAME:
|
||||
case SYSCALL_SHUTDOWN:
|
||||
case SYSCALL_CONNECT:
|
||||
|
@ -267,6 +267,19 @@ bool Noux::Child::_syscall_net(Noux::Session::Syscall sc)
|
||||
|
||||
_sysio->recv_out.len = len;
|
||||
|
||||
return true;
|
||||
}
|
||||
case SYSCALL_RECVFROM:
|
||||
{
|
||||
GET_SOCKET_IO_CHANNEL(_sysio->recvfrom_in.fd, socket_io_channel)
|
||||
|
||||
ssize_t len = socket_io_channel->recvfrom(_sysio);
|
||||
|
||||
if (len == -1)
|
||||
return false;
|
||||
|
||||
_sysio->recvfrom_out.len = len;
|
||||
|
||||
return true;
|
||||
}
|
||||
case SYSCALL_GETPEERNAME:
|
||||
|
@ -241,6 +241,15 @@ namespace Noux {
|
||||
sysio->recv_in.flags);
|
||||
}
|
||||
|
||||
ssize_t recvfrom(Sysio *sysio)
|
||||
{
|
||||
ssize_t result = ::recvfrom(_socket, sysio->recv_in.buf, sysio->recv_in.len,
|
||||
sysio->recv_in.flags, (struct sockaddr *)&sysio->recvfrom_in.src_addr,
|
||||
&sysio->recvfrom_in.addrlen);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t send(Sysio *sysio)
|
||||
{
|
||||
return ::send(_socket, sysio->send_in.buf, sysio->send_in.len,
|
||||
|
Loading…
x
Reference in New Issue
Block a user