diff options
author | Mattias Andrée <maandree@kth.se> | 2019-11-01 22:06:40 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2019-11-01 22:06:40 +0100 |
commit | c57844b08bced71778f38f2346464c3e0836287c (patch) | |
tree | e3733b4c99818ee6c77ed3d4d37becf30f92268f /recv.c | |
parent | Use installed liberror (diff) | |
download | liberror-libc-c57844b08bced71778f38f2346464c3e0836287c.tar.gz liberror-libc-c57844b08bced71778f38f2346464c3e0836287c.tar.bz2 liberror-libc-c57844b08bced71778f38f2346464c3e0836287c.tar.xz |
Add some functions and add functions with _failed suffix
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | recv.c | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -0,0 +1,124 @@ +/* See LICENSE file for copyright and license details. */ +#include "internal.h" + + +void +liberror_recv_failed(int fd, void *buf, size_t n, int flags, const char *fname) +{ + const char *desc; + int saved_errno, val; + struct timeval tv; + switch (errno) { +#if defined(EAGAIN) + case EAGAIN: +#endif +#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EAGAIN != EWOULDBLOCK) + case EWOULDBLOCK: +#endif +#if defined(EAGAIN) || defined(EWOULDBLOCK) + saved_errno = errno; + if (flags & MSG_OOB) { + desc = "Attempting to receive in nonblocking mode but the operation would block, " + "attempting to receive with time out and the operation timed out " + "or the socket does not support blocking to await out-of-band data"; + if (flags & MSG_DONTWAIT) { + msg_oob_nonblocking: + desc = "Attempting to receive in nonblocking mode but the operation would block or" + " the socket does not support blocking to await out-of-band data"; + } else if ((val = fcntl(fd, F_GETFL)) < 0) { + /* Do nothing */ + } else if (val & O_NONBLOCK) { + goto msg_oob_nonblocking; + } else if (getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &(socklen_t){(socklen_t)sizeof(tv)}) || + tv.tv_sec || tv.tv_usec) { + desc = "Attempting to receive with time out and the operation timed out or" + " the socket does not support blocking to await out-of-band data"; + } else { + desc = "The socket does not support blocking to await out-of-band data"; + } + } else { + desc = "Attempting to receive in nonblocking mode but the operation would block " + "or attempting to receive with time out and the operation timed out"; + if (flags & MSG_DONTWAIT) { + no_msg_oob_nonblocking: + desc = "Attempting to receive in nonblocking mode but the operation would block"; + } else if ((val = fcntl(fd, F_GETFL)) < 0) { + /* Do nothing */ + } else if (val & O_NONBLOCK) { + goto no_msg_oob_nonblocking; + } else if (!getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &(socklen_t){(socklen_t)sizeof(tv)}) && + !tv.tv_sec && !tv.tv_usec) { + desc = "Attempting to receive with time out and the operation timed out"; + } + } + errno = saved_errno; + break; +#endif + case EBADF: + if (fd < 0) + desc = "Negative file descriptor number specified"; + else + desc = "Unassigned file descriptor number specified"; + break; + case ECONNREFUSED: + desc = "The remote host refused to allow the network connection"; + break; + case ECONNRESET: + desc = "The connection was forcibly closed by a peer"; + break; + case EFAULT: + desc = "Invalid user space address specified in the second argument"; + break; + case EINTR: + desc = "System call was interrupted by a signal or machine suspension"; + break; + case EINVAL: + if (fd < 0) + desc = "Negative file descriptor number specified"; + else if ((flags & ~(MSG_PEEK | MSG_WAITALL)) == MSG_OOB) + desc = "No out-of-band data is available"; + else if (flags & MSG_OOB) + desc = "No out-of-band data is available or non-existing flag is specified"; + else + desc = "Non-existing flag is specified"; + break; + case EIO: + desc = "An I/O error occurred while reading from or writing to the file system"; + break; + case ENOBUFS: + desc = "Insufficient resource available in the system to perform the operation"; + break; + case ENOMEM: + desc = "Out of memory"; + break; + case ENOTCONN: + desc = "The socket is not connected"; + break; + case ENOTSOCK: + desc = "The file descriptor refer to a non-socket file"; + break; + case EOPNOTSUPP: + desc = "A flag that is not supported for the socket protocol is specified"; + break; + case ETIMEDOUT: + desc = "The connection timed out during connection establishment, " + "or due to a transmission timeout on active connection"; + break; + default: + desc = ""; + break; + } + liberror_libc_set_error_one_file(desc, "recv", "Socket file", fd, fname); +} + + +ssize_t +liberror_recv(int fd, void *buf, size_t n, int flags, const char *fname) +{ + ssize_t r = recv(fd, buf, n, flags); + if (r >= 0) + return r; + liberror_save_backtrace(NULL); + liberror_recv_failed(fd, buf, n, flags, fname); + return -1; +} |