mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
Noux: add proper errno handling to network funcs
Programs use the errno value to check which error exactly occured. It is mandatory for non-blocking I/O, e.g. connect() gets the current state of the connection by looking at the returned errno values. Fixes #337.
This commit is contained in:
parent
aae3ce348e
commit
9cff243f42
@ -299,6 +299,42 @@ namespace Noux {
|
||||
MKDIR_ERR_NO_SPACE, MKDIR_ERR_NO_PERM,
|
||||
MKDIR_ERR_NAME_TOO_LONG};
|
||||
|
||||
enum Read_error { READ_ERR_AGAIN, READ_ERR_WOULD_BLOCK,
|
||||
READ_ERR_INVALID, READ_ERR_IO };
|
||||
|
||||
enum Write_error { WRITE_ERR_AGAIN, WRITE_ERR_WOULD_BLOCK,
|
||||
WRITE_ERR_INVALID, WRITE_ERR_IO };
|
||||
|
||||
/**
|
||||
* Socket related errors
|
||||
*/
|
||||
enum Accept_error { ACCEPT_ERR_AGAIN, ACCEPT_ERR_WOULD_BLOCK,
|
||||
ACCEPT_ERR_INVALID, ACCEPT_ERR_NO_MEMORY,
|
||||
ACCEPT_ERR_NOT_SUPPORTED };
|
||||
|
||||
enum Bind_error { BIND_ERR_ACCESS, BIND_ERR_ADDR_IN_USE,
|
||||
BIND_ERR_INVALID, BIND_ERR_NO_MEMORY };
|
||||
|
||||
enum Connect_error { CONNECT_ERR_ACCESS, CONNECT_ERR_AGAIN,
|
||||
CONNECT_ERR_ALREADY, CONNECT_ERR_CONN_REFUSED,
|
||||
CONNECT_ERR_NO_PERM, CONNECT_ERR_ADDR_IN_USE,
|
||||
CONNECT_ERR_IN_PROGRESS, CONNECT_ERR_IS_CONNECTED };
|
||||
|
||||
enum Listen_error { LISTEN_ERR_ADDR_IN_USE, LISTEN_ERR_NOT_SUPPORTED };
|
||||
|
||||
enum Recv_error { RECV_ERR_AGAIN, RECV_ERR_WOULD_BLOCK,
|
||||
RECV_ERR_CONN_REFUSED, RECV_ERR_INVALID,
|
||||
RECV_ERR_NOT_CONNECTED, RECV_ERR_NO_MEMORY };
|
||||
|
||||
enum Send_error { SEND_ERR_AGAIN, SEND_ERR_WOULD_BLOCK,
|
||||
SEND_ERR_CONNECTION_RESET, SEND_ERR_INVALID,
|
||||
SEND_ERR_IS_CONNECTED, SEND_ERR_NO_MEMORY };
|
||||
|
||||
enum Shutdown_error { SHUTDOWN_ERR_NOT_CONNECTED };
|
||||
|
||||
enum Socket_error { SOCKET_ERR_ACCESS, SOCKET_ERR_NO_AF_SUPPORT,
|
||||
SOCKET_ERR_INVALID, SOCKET_ERR_NO_MEMORY };
|
||||
|
||||
union {
|
||||
General_error general;
|
||||
Stat_error stat;
|
||||
@ -310,6 +346,16 @@ namespace Noux {
|
||||
Unlink_error unlink;
|
||||
Rename_error rename;
|
||||
Mkdir_error mkdir;
|
||||
Read_error read;
|
||||
Write_error write;
|
||||
Accept_error accept;
|
||||
Bind_error bind;
|
||||
Connect_error connect;
|
||||
Listen_error listen;
|
||||
Recv_error recv;
|
||||
Send_error send;
|
||||
Shutdown_error shutdown;
|
||||
Socket_error socket;
|
||||
} error;
|
||||
|
||||
union {
|
||||
|
@ -774,7 +774,18 @@ namespace {
|
||||
Genode::memcpy(sysio()->write_in.chunk, src, curr_count);
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_WRITE)) {
|
||||
PERR("write error %d (fd %d)", sysio()->error.general, noux_fd(fd->context));
|
||||
switch (sysio()->error.write) {
|
||||
case Noux::Sysio::WRITE_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::WRITE_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
case Noux::Sysio::WRITE_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::WRITE_ERR_IO: errno = EIO; break;
|
||||
default:
|
||||
if (sysio()->error.general == Noux::Sysio::ERR_FD_INVALID)
|
||||
errno = EBADF;
|
||||
else
|
||||
errno = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
count -= curr_count;
|
||||
@ -797,8 +808,18 @@ namespace {
|
||||
sysio()->read_in.count = curr_count;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_READ)) {
|
||||
PERR("read error");
|
||||
/* XXX set errno */
|
||||
switch (sysio()->error.read) {
|
||||
case Noux::Sysio::READ_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::READ_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
case Noux::Sysio::READ_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::READ_ERR_IO: errno = EIO; break;
|
||||
default:
|
||||
if (sysio()->error.general == Noux::Sysio::ERR_FD_INVALID)
|
||||
errno = EBADF;
|
||||
else
|
||||
errno = 0;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1321,6 +1342,15 @@ namespace {
|
||||
}
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_ACCEPT)) {
|
||||
switch (sysio()->error.accept) {
|
||||
case Noux::Sysio::ACCEPT_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::ACCEPT_ERR_NO_MEMORY: errno = ENOMEM; break;
|
||||
case Noux::Sysio::ACCEPT_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::ACCEPT_ERR_NOT_SUPPORTED: errno = EOPNOTSUPP; break;
|
||||
case Noux::Sysio::ACCEPT_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1330,7 +1360,6 @@ namespace {
|
||||
Libc::Plugin_context *context = noux_context(sysio()->accept_out.fd);
|
||||
return Libc::file_descriptor_allocator()->alloc(this, context,
|
||||
sysio()->accept_out.fd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1343,7 +1372,13 @@ namespace {
|
||||
sysio()->bind_in.addrlen = addrlen;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_BIND)) {
|
||||
errno = EACCES;
|
||||
switch (sysio()->error.bind) {
|
||||
case Noux::Sysio::BIND_ERR_ACCESS: errno = EACCES; break;
|
||||
case Noux::Sysio::BIND_ERR_ADDR_IN_USE: errno = EADDRINUSE; break;
|
||||
case Noux::Sysio::BIND_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::BIND_ERR_NO_MEMORY: errno = ENOMEM; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1360,7 +1395,14 @@ namespace {
|
||||
sysio()->connect_in.addrlen = addrlen;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_CONNECT)) {
|
||||
/* XXX errno */
|
||||
switch (sysio()->error.connect) {
|
||||
case Noux::Sysio::CONNECT_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::CONNECT_ERR_ALREADY: errno = EALREADY; break;
|
||||
case Noux::Sysio::CONNECT_ERR_ADDR_IN_USE: errno = EADDRINUSE; break;
|
||||
case Noux::Sysio::CONNECT_ERR_IN_PROGRESS: errno = EINPROGRESS; break;
|
||||
case Noux::Sysio::CONNECT_ERR_IS_CONNECTED: errno = EISCONN; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1393,7 +1435,11 @@ namespace {
|
||||
sysio()->listen_in.backlog = backlog;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_LISTEN)) {
|
||||
/* errno = EACCES; */
|
||||
switch (sysio()->error.listen) {
|
||||
case Noux::Sysio::LISTEN_ERR_ADDR_IN_USE: errno = EADDRINUSE; break;
|
||||
case Noux::Sysio::LISTEN_ERR_NOT_SUPPORTED: errno = EOPNOTSUPP; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1413,7 +1459,13 @@ namespace {
|
||||
sysio()->recv_in.len = curr_len;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_RECV)) {
|
||||
/* XXX set errno */
|
||||
switch (sysio()->error.recv) {
|
||||
case Noux::Sysio::RECV_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::RECV_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
case Noux::Sysio::RECV_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::RECV_ERR_NOT_CONNECTED: errno = ENOTCONN; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1452,7 +1504,13 @@ namespace {
|
||||
sysio()->recvfrom_in.addrlen = *addrlen;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_RECVFROM)) {
|
||||
/* XXX set errno */
|
||||
switch (sysio()->error.recv) {
|
||||
case Noux::Sysio::RECV_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::RECV_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
case Noux::Sysio::RECV_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::RECV_ERR_NOT_CONNECTED: errno = ENOTCONN; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1495,6 +1553,16 @@ namespace {
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_SEND)) {
|
||||
PERR("write error %d", sysio()->error.general);
|
||||
switch (sysio()->error.send) {
|
||||
case Noux::Sysio::SEND_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::SEND_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
case Noux::Sysio::SEND_ERR_CONNECTION_RESET: errno = ECONNRESET; break;
|
||||
case Noux::Sysio::SEND_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::SEND_ERR_IS_CONNECTED: errno = EISCONN; break;
|
||||
case Noux::Sysio::SEND_ERR_NO_MEMORY: errno = ENOMEM; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
/* return foo */
|
||||
}
|
||||
|
||||
len -= curr_len;
|
||||
@ -1510,7 +1578,7 @@ namespace {
|
||||
int const orig_count = len;
|
||||
|
||||
if (addrlen > sizeof (sysio()->sendto_in.dest_addr)) {
|
||||
/* XXX errno */
|
||||
errno = 0; /* XXX */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1535,6 +1603,15 @@ namespace {
|
||||
}
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_SENDTO)) {
|
||||
switch (sysio()->error.send) {
|
||||
case Noux::Sysio::SEND_ERR_AGAIN: errno = EAGAIN; break;
|
||||
case Noux::Sysio::SEND_ERR_WOULD_BLOCK: errno = EWOULDBLOCK; break;
|
||||
case Noux::Sysio::SEND_ERR_CONNECTION_RESET: errno = ECONNRESET; break;
|
||||
case Noux::Sysio::SEND_ERR_INVALID: errno = EINVAL; break;
|
||||
case Noux::Sysio::SEND_ERR_IS_CONNECTED: errno = EISCONN; break;
|
||||
case Noux::Sysio::SEND_ERR_NO_MEMORY: errno = ENOMEM; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1552,6 +1629,10 @@ namespace {
|
||||
sysio()->shutdown_in.how = how;
|
||||
|
||||
if (!noux()->syscall(Noux::Session::SYSCALL_SHUTDOWN)) {
|
||||
switch (sysio()->error.shutdown) {
|
||||
case Noux::Sysio::SHUTDOWN_ERR_NOT_CONNECTED: errno = ENOTCONN; break;
|
||||
default: errno = 0; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
namespace Noux {
|
||||
@ -119,7 +120,7 @@ namespace Noux {
|
||||
|
||||
bool write(Sysio *sysio, size_t &count)
|
||||
{
|
||||
size_t result = ::write(_socket, sysio->write_in.chunk,
|
||||
ssize_t result = ::write(_socket, sysio->write_in.chunk,
|
||||
sysio->write_in.count);
|
||||
|
||||
if (result > -1) {
|
||||
@ -129,6 +130,15 @@ namespace Noux {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (errno) {
|
||||
/* case EAGAIN: sysio->error.read = Sysio::READ_ERR_AGAIN; break; */
|
||||
case EWOULDBLOCK: sysio->error.read = Sysio::READ_ERR_WOULD_BLOCK; break;
|
||||
case EINVAL: sysio->error.read = Sysio::READ_ERR_INVALID; break;
|
||||
case EIO: sysio->error.read = Sysio::READ_ERR_IO; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -138,10 +148,23 @@ namespace Noux {
|
||||
Genode::min(sysio->read_in.count,
|
||||
sizeof(sysio->read_out.chunk));
|
||||
|
||||
sysio->read_out.count = ::read(_socket, sysio->read_out.chunk,
|
||||
max_count);
|
||||
ssize_t result = ::read(_socket, sysio->read_out.chunk, max_count);
|
||||
|
||||
return true;
|
||||
if (result > -1) {
|
||||
sysio->read_out.count = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (errno) {
|
||||
/* case EAGAIN: sysio->error.read = Sysio::READ_ERR_AGAIN; break; */
|
||||
case EWOULDBLOCK: sysio->error.read = Sysio::READ_ERR_WOULD_BLOCK; break;
|
||||
case EINVAL: sysio->error.read = Sysio::READ_ERR_INVALID; break;
|
||||
case EIO: sysio->error.read = Sysio::READ_ERR_IO; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool socket(Sysio *sysio)
|
||||
@ -200,19 +223,58 @@ namespace Noux {
|
||||
&sysio->accept_in.addrlen);
|
||||
}
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
/* case EAGAIN: sysio->error.accept = Sysio::ACCEPT_ERR_AGAIN; break; */
|
||||
case ENOMEM: sysio->error.accept = Sysio::ACCEPT_ERR_NO_MEMORY; break;
|
||||
case EINVAL: sysio->error.accept = Sysio::ACCEPT_ERR_INVALID; break;
|
||||
case EOPNOTSUPP: sysio->error.accept = Sysio::ACCEPT_ERR_NOT_SUPPORTED; break;
|
||||
case EWOULDBLOCK: sysio->error.accept = Sysio::ACCEPT_ERR_WOULD_BLOCK; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int bind(Sysio *sysio)
|
||||
{
|
||||
return ::bind(_socket, (const struct sockaddr *)&sysio->bind_in.addr,
|
||||
sysio->bind_in.addrlen);
|
||||
int result = ::bind(_socket, (const struct sockaddr *)&sysio->bind_in.addr,
|
||||
sysio->bind_in.addrlen);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
case EACCES: sysio->error.bind = Sysio::BIND_ERR_ACCESS; break;
|
||||
case EADDRINUSE: sysio->error.bind = Sysio::BIND_ERR_ADDR_IN_USE; break;
|
||||
case EINVAL: sysio->error.bind = Sysio::BIND_ERR_INVALID; break;
|
||||
case ENOMEM: sysio->error.bind = Sysio::BIND_ERR_NO_MEMORY; break;
|
||||
default:
|
||||
PERR("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int connect(Sysio *sysio)
|
||||
{
|
||||
return ::connect(_socket, (struct sockaddr *)&sysio->connect_in.addr,
|
||||
sysio->connect_in.addrlen);
|
||||
int result = ::connect(_socket, (struct sockaddr *)&sysio->connect_in.addr,
|
||||
sysio->connect_in.addrlen);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN: sysio->error.connect = Sysio::CONNECT_ERR_AGAIN; break;
|
||||
case EALREADY: sysio->error.connect = Sysio::CONNECT_ERR_ALREADY; break;
|
||||
case EADDRINUSE: sysio->error.connect = Sysio::CONNECT_ERR_ADDR_IN_USE; break;
|
||||
case EINPROGRESS: sysio->error.connect = Sysio::CONNECT_ERR_IN_PROGRESS; break;
|
||||
case EISCONN: sysio->error.connect = Sysio::CONNECT_ERR_IS_CONNECTED; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int getpeername(Sysio *sysio)
|
||||
@ -230,13 +292,36 @@ namespace Noux {
|
||||
|
||||
int listen(Sysio *sysio)
|
||||
{
|
||||
return ::listen(_socket, sysio->listen_in.backlog);
|
||||
int result = ::listen(_socket, sysio->listen_in.backlog);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
case EADDRINUSE: sysio->error.listen = Sysio::LISTEN_ERR_ADDR_IN_USE; break;
|
||||
case EOPNOTSUPP: sysio->error.listen = Sysio::LISTEN_ERR_NOT_SUPPORTED; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t recv(Sysio *sysio)
|
||||
{
|
||||
return ::recv(_socket, sysio->recv_in.buf, sysio->recv_in.len,
|
||||
sysio->recv_in.flags);
|
||||
ssize_t result = ::recv(_socket, sysio->recv_in.buf, sysio->recv_in.len, sysio->recv_in.flags);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
/*case EAGAIN: sysio->error.recv = Sysio::RECV_ERR_AGAIN; break; */
|
||||
case EWOULDBLOCK: sysio->error.recv = Sysio::RECV_ERR_WOULD_BLOCK; break;
|
||||
case EINVAL: sysio->error.recv = Sysio::RECV_ERR_INVALID; break;
|
||||
case ENOTCONN: sysio->error.recv = Sysio::RECV_ERR_NOT_CONNECTED; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t recvfrom(Sysio *sysio)
|
||||
@ -245,13 +330,39 @@ namespace Noux {
|
||||
sysio->recv_in.flags, (struct sockaddr *)&sysio->recvfrom_in.src_addr,
|
||||
&sysio->recvfrom_in.addrlen);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
/*case EAGAIN: sysio->error.recv = Sysio::RECV_ERR_AGAIN; break; */
|
||||
case EWOULDBLOCK: sysio->error.recv = Sysio::RECV_ERR_WOULD_BLOCK; break;
|
||||
case EINVAL: sysio->error.recv = Sysio::RECV_ERR_INVALID; break;
|
||||
case ENOTCONN: sysio->error.recv = Sysio::RECV_ERR_NOT_CONNECTED; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t send(Sysio *sysio)
|
||||
{
|
||||
return ::send(_socket, sysio->send_in.buf, sysio->send_in.len,
|
||||
sysio->send_in.flags);
|
||||
ssize_t result = ::send(_socket, sysio->send_in.buf, sysio->send_in.len,
|
||||
sysio->send_in.flags);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
/*case EAGAIN: sysio->error.send = Sysio::SEND_ERR_AGAIN; break; */
|
||||
case EWOULDBLOCK: sysio->error.send = Sysio::SEND_ERR_WOULD_BLOCK; break;
|
||||
case ECONNRESET: sysio->error.send = Sysio::SEND_ERR_CONNECTION_RESET; break;
|
||||
case EINVAL: sysio->error.send = Sysio::SEND_ERR_INVALID; break;
|
||||
case EISCONN: sysio->error.send = Sysio::SEND_ERR_IS_CONNECTED; break;
|
||||
case ENOMEM: sysio->error.send = Sysio::SEND_ERR_NO_MEMORY; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ssize_t sendto(Sysio *sysio)
|
||||
@ -261,12 +372,35 @@ namespace Noux {
|
||||
(const struct sockaddr *) &sysio->sendto_in.dest_addr,
|
||||
sysio->sendto_in.addrlen);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
/*case EAGAIN: sysio->error.send = Sysio::SEND_ERR_AGAIN; break; */
|
||||
case EWOULDBLOCK: sysio->error.send = Sysio::SEND_ERR_WOULD_BLOCK; break;
|
||||
case ECONNRESET: sysio->error.send = Sysio::SEND_ERR_CONNECTION_RESET; break;
|
||||
case EINVAL: sysio->error.send = Sysio::SEND_ERR_INVALID; break;
|
||||
case EISCONN: sysio->error.send = Sysio::SEND_ERR_IS_CONNECTED; break;
|
||||
case ENOMEM: sysio->error.send = Sysio::SEND_ERR_NO_MEMORY; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int shutdown(Sysio *sysio)
|
||||
{
|
||||
return ::shutdown(_socket, sysio->shutdown_in.how);
|
||||
int result = ::shutdown(_socket, sysio->shutdown_in.how);
|
||||
|
||||
if (result == -1) {
|
||||
switch (errno) {
|
||||
case ENOTCONN: sysio->error.shutdown = Sysio::SHUTDOWN_ERR_NOT_CONNECTED; break;
|
||||
default:
|
||||
PDBG("unhandled errno: %d", errno); break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user