From c57844b08bced71778f38f2346464c3e0836287c Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 1 Nov 2019 22:06:40 +0100 Subject: Add some functions and add functions with _failed suffix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- recv.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 recv.c (limited to 'recv.c') diff --git a/recv.c b/recv.c new file mode 100644 index 0000000..03985ba --- /dev/null +++ b/recv.c @@ -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; +} -- cgit v1.2.3-70-g09d2