From 2b649cb63378220f2d4e06777dbdac61a7f5bb2e Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Thu, 23 Nov 2017 17:36:03 +0100 Subject: [PATCH] libc: handle socket_fs special cases - catch inaccessible file on bind() - support UDP ENETDOWN and TCP EAGAIN on sendto() --- .../libports/src/lib/libc/socket_fs_plugin.cc | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/repos/libports/src/lib/libc/socket_fs_plugin.cc b/repos/libports/src/lib/libc/socket_fs_plugin.cc index 29c17bdea5..8bf0246117 100644 --- a/repos/libports/src/lib/libc/socket_fs_plugin.cc +++ b/repos/libports/src/lib/libc/socket_fs_plugin.cc @@ -499,12 +499,15 @@ extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrl Sockaddr_string addr_string(host_string(*(sockaddr_in *)addr), port_string(*(sockaddr_in *)addr)); - int const len = strlen(addr_string.base()); - int const n = write(context->bind_fd(), addr_string.base(), len); - if (n != len) return Errno(EACCES); - fsync(context->bind_fd()); - - return 0; + try { + int const len = strlen(addr_string.base()); + int const n = write(context->bind_fd(), addr_string.base(), len); + if (n != len) return Errno(EACCES); + fsync(context->bind_fd()); + return 0; + } catch (Socket_fs::Context::Inaccessible) { + return Errno(EINVAL); + } } @@ -620,18 +623,24 @@ static ssize_t do_sendto(Libc::File_descriptor *fd, /* TODO ENOTCONN, EISCONN, EDESTADDRREQ */ /* TODO ECONNRESET */ - if (dest_addr) { - Sockaddr_string addr_string(host_string(*(sockaddr_in const *)dest_addr), - port_string(*(sockaddr_in const *)dest_addr)); - - int const len = strlen(addr_string.base()); - int const n = write(context->remote_fd(), addr_string.base(), len); - if (n != len) return Errno(EIO); - } - try { + if (dest_addr) { + Sockaddr_string addr_string(host_string(*(sockaddr_in const *)dest_addr), + port_string(*(sockaddr_in const *)dest_addr)); + + int const len = strlen(addr_string.base()); + int const n = write(context->remote_fd(), addr_string.base(), len); + if (n != len) return Errno(EIO); + } + lseek(context->data_fd(), 0, 0); ssize_t out_len = write(context->data_fd(), buf, len); + if (out_len == 0) { + switch (context->proto()) { + case Socket_fs::Context::Proto::UDP: return Errno(ENETDOWN); + case Socket_fs::Context::Proto::TCP: return Errno(EAGAIN); + } + } return out_len; } catch (Socket_fs::Context::Inaccessible) { return Errno(EINVAL);