/*
 * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/net/socket.h>
#include <zephyr/posix/fcntl.h>
#include <zephyr/syscall_handler.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/fdtable.h>

#include "sockets_internal.h"

enum {
	SPAIR_SIG_CANCEL, /**< operation has been canceled */
	SPAIR_SIG_DATA,   /**< @ref spair.recv_q has been updated */
};

enum {
	SPAIR_FLAG_NONBLOCK = (1 << 0), /**< socket is non-blocking */
};

#define SPAIR_FLAGS_DEFAULT 0

/**
 * Socketpair endpoint structure
 *
 * This structure represents one half of a socketpair (an 'endpoint').
 *
 * The implementation strives for compatibility with socketpair(2).
 *
 * Resources contained within this structure are said to be 'local', while
 * resources contained within the other half of the socketpair (or other
 * endpoint) are said to be 'remote'.
 *
 * Theory of operation:
 * - each end of a socketpair owns a @a recv_q
 * - since there is no write queue, data is either written or not
 * - read and write operations may return partial transfers
 * - read operations may block if the local @a recv_q is empty
 * - write operations may block if the remote @a recv_q is full
 * - each endpoint may be blocking or non-blocking
 */
__net_socket struct spair {
	int remote; /**< the remote endpoint file descriptor */
	uint32_t flags; /**< status and option bits */
	struct k_sem sem; /**< semaphore for exclusive structure access */
	struct k_pipe recv_q; /**< receive queue of local endpoint */
	/** indicates local @a recv_q isn't empty */
	struct k_poll_signal readable;
	/** indicates local @a recv_q isn't full */
	struct k_poll_signal writeable;
	/** buffer for @a recv_q recv_q */
	uint8_t buf[CONFIG_NET_SOCKETPAIR_BUFFER_SIZE];
};

#ifdef CONFIG_NET_SOCKETPAIR_STATIC
K_MEM_SLAB_DEFINE_STATIC(spair_slab, sizeof(struct spair), CONFIG_NET_SOCKETPAIR_MAX * 2,
			 __alignof__(struct spair));
#endif /* CONFIG_NET_SOCKETPAIR_STATIC */

/* forward declaration */
static const struct socket_op_vtable spair_fd_op_vtable;

#undef sock_is_nonblock
/** Determine if a @ref spair is in non-blocking mode */
static inline bool sock_is_nonblock(const struct spair *spair)
{
	return !!(spair->flags & SPAIR_FLAG_NONBLOCK);
}

/** Determine if a @ref spair is connected */
static inline bool sock_is_connected(const struct spair *spair)
{
	const struct spair *remote = z_get_fd_obj(spair->remote,
		(const struct fd_op_vtable *)&spair_fd_op_vtable, 0);

	if (remote == NULL) {
		return false;
	}

	return true;
}

#undef sock_is_eof
/** Determine if a @ref spair has encountered end-of-file */
static inline bool sock_is_eof(const struct spair *spair)
{
	return !sock_is_connected(spair);
}

/**
 * Determine bytes available to write
 *
 * Specifically, this function calculates the number of bytes that may be
 * written to a given @ref spair without blocking.
 */
static inline size_t spair_write_avail(struct spair *spair)
{
	struct spair *const remote = z_get_fd_obj(spair->remote,
		(const struct fd_op_vtable *)&spair_fd_op_vtable, 0);

	if (remote == NULL) {
		return 0;
	}

	return k_pipe_write_avail(&remote->recv_q);
}

/**
 * Determine bytes available to read
 *
 * Specifically, this function calculates the number of bytes that may be
 * read from a given @ref spair without blocking.
 */
static inline size_t spair_read_avail(struct spair *spair)
{
	return k_pipe_read_avail(&spair->recv_q);
}

/** Swap two 32-bit integers */
static inline void swap32(uint32_t *a, uint32_t *b)
{
	uint32_t c;

	c = *b;
	*b = *a;
	*a = c;
}

/**
 * Delete @param spair
 *
 * This function deletes one endpoint of a socketpair.
 *
 * Theory of operation:
 * - we have a socketpair with two endpoints: A and B
 * - we have two threads: T1 and T2
 * - T1 operates on endpoint A
 * - T2 operates on endpoint B
 *
 * There are two possible cases where a blocking operation must be notified
 * when one endpoint is closed:
 * -# T1 is blocked reading from A and T2 closes B
 *    T1 waits on A's write signal. T2 triggers the remote
 *    @ref spair.readable
 * -# T1 is blocked writing to A and T2 closes B
 *    T1 is waits on B's read signal. T2 triggers the local
 *    @ref spair.writeable.
 *
 * If the remote endpoint is already closed, the former operation does not
 * take place. Otherwise, the @ref spair.remote of the local endpoint is
 * set to -1.
 *
 * If no threads are blocking on A, then the signals have no effect.
 *
 * The memory associated with the local endpoint is cleared and freed.
 */
static void spair_delete(struct spair *spair)
{
	int res;
	struct spair *remote = NULL;
	bool have_remote_sem = false;

	if (spair == NULL) {
		return;
	}

	if (spair->remote != -1) {
		remote = z_get_fd_obj(spair->remote,
			(const struct fd_op_vtable *)&spair_fd_op_vtable, 0);

		if (remote != NULL) {
			res = k_sem_take(&remote->sem, K_FOREVER);
			if (res == 0) {
				have_remote_sem = true;
				remote->remote = -1;
				res = k_poll_signal_raise(&remote->readable,
					SPAIR_SIG_CANCEL);
				__ASSERT(res == 0,
					"k_poll_signal_raise() failed: %d",
					res);
			}
		}
	}

	spair->remote = -1;

	res = k_poll_signal_raise(&spair->writeable, SPAIR_SIG_CANCEL);
	__ASSERT(res == 0, "k_poll_signal_raise() failed: %d", res);

	if (remote != NULL && have_remote_sem) {
		k_sem_give(&remote->sem);
	}

	/* ensure no private information is released to the memory pool */
	memset(spair, 0, sizeof(*spair));
#ifdef CONFIG_NET_SOCKETPAIR_STATIC
	k_mem_slab_free(&spair_slab, (void *)spair);
#elif CONFIG_USERSPACE
	k_object_free(spair);
#else
	k_free(spair);
#endif
}

/**
 * Create a @ref spair (1/2 of a socketpair)
 *
 * The idea is to call this twice, but store the "local" side in the
 * @ref spair.remote field initially.
 *
 * If both allocations are successful, then swap the @ref spair.remote
 * fields in the two @ref spair instances.
 */
static struct spair *spair_new(void)
{
	struct spair *spair;
	int res;

#ifdef CONFIG_NET_SOCKETPAIR_STATIC

	res = k_mem_slab_alloc(&spair_slab, (void **) &spair, K_NO_WAIT);
	if (res != 0) {
		spair = NULL;
	}

#elif CONFIG_USERSPACE
	struct z_object *zo = z_dynamic_object_create(sizeof(*spair));

	if (zo == NULL) {
		spair = NULL;
	} else {
		spair = zo->name;
		zo->type = K_OBJ_NET_SOCKET;
	}
#else
	spair = k_malloc(sizeof(*spair));
#endif
	if (spair == NULL) {
		errno = ENOMEM;
		goto out;
	}
	memset(spair, 0, sizeof(*spair));

	/* initialize any non-zero default values */
	spair->remote = -1;
	spair->flags = SPAIR_FLAGS_DEFAULT;

	k_sem_init(&spair->sem, 1, 1);
	k_pipe_init(&spair->recv_q, spair->buf, sizeof(spair->buf));
	k_poll_signal_init(&spair->readable);
	k_poll_signal_init(&spair->writeable);

	/* A new socket is always writeable after creation */
	res = k_poll_signal_raise(&spair->writeable, SPAIR_SIG_DATA);
	__ASSERT(res == 0, "k_poll_signal_raise() failed: %d", res);

	spair->remote = z_reserve_fd();
	if (spair->remote == -1) {
		errno = ENFILE;
		goto cleanup;
	}

	z_finalize_fd(spair->remote, spair,
		      (const struct fd_op_vtable *)&spair_fd_op_vtable);

	goto out;

cleanup:
	spair_delete(spair);
	spair = NULL;

out:
	return spair;
}

int z_impl_zsock_socketpair(int family, int type, int proto, int *sv)
{
	int res;
	size_t i;
	struct spair *obj[2] = {};

	if (family != AF_UNIX) {
		errno = EAFNOSUPPORT;
		res = -1;
		goto errout;
	}

	if (type != SOCK_STREAM) {
		errno = EPROTOTYPE;
		res = -1;
		goto errout;
	}

	if (proto != 0) {
		errno = EPROTONOSUPPORT;
		res = -1;
		goto errout;
	}

	if (sv == NULL) {
		/* not listed in normative spec, but mimics Linux behaviour */
		errno = EFAULT;
		res = -1;
		goto errout;
	}

	for (i = 0; i < 2; ++i) {
		obj[i] = spair_new();
		if (!obj[i]) {
			res = -1;
			goto cleanup;
		}
	}

	/* connect the two endpoints */
	swap32(&obj[0]->remote, &obj[1]->remote);

	for (i = 0; i < 2; ++i) {
		sv[i] = obj[i]->remote;
		k_sem_give(&obj[0]->sem);
	}

	return 0;

cleanup:
	for (i = 0; i < 2; ++i) {
		spair_delete(obj[i]);
	}

errout:
	return res;
}

#ifdef CONFIG_USERSPACE
int z_vrfy_zsock_socketpair(int family, int type, int proto, int *sv)
{
	int ret;
	int tmp[2];

	if (!sv || Z_SYSCALL_MEMORY_WRITE(sv, sizeof(tmp)) != 0) {
		/* not listed in normative spec, but mimics linux behaviour */
		errno = EFAULT;
		ret = -1;
		goto out;
	}

	ret = z_impl_zsock_socketpair(family, type, proto, tmp);
	if (ret == 0) {
		Z_OOPS(z_user_to_copy(sv, tmp, sizeof(tmp)));
	}

out:
	return ret;
}

#include <syscalls/zsock_socketpair_mrsh.c>
#endif /* CONFIG_USERSPACE */

/**
 * Write data to one end of a @ref spair
 *
 * Data written on one file descriptor of a socketpair can be read at the
 * other end using common POSIX calls such as read(2) or recv(2).
 *
 * If the underlying file descriptor has the @ref O_NONBLOCK flag set then
 * this function will return immediately. If no data was written on a
 * non-blocking file descriptor, then -1 will be returned and @ref errno will
 * be set to @ref EAGAIN.
 *
 * Blocking write operations occur when the @ref O_NONBLOCK flag is @em not
 * set and there is insufficient space in the @em remote @ref spair.pipe.
 *
 * Such a blocking write will suspend execution of the current thread until
 * one of two possible results is received on the @em remote
 * @ref spair.writeable:
 *
 * 1) @ref SPAIR_SIG_DATA - data has been read from the @em remote
 *    @ref spair.pipe. Thus, allowing more data to be written.
 *
 * 2) @ref SPAIR_SIG_CANCEL - the @em remote socketpair endpoint was closed
 *    Receipt of this result is analogous to SIGPIPE from POSIX
 *    ("Write on a pipe with no one to read it."). In this case, the function
 *    will return -1 and set @ref errno to @ref EPIPE.
 *
 * @param obj the address of an @ref spair object cast to `void *`
 * @param buffer the buffer to write
 * @param count the number of bytes to write from @p buffer
 *
 * @return on success, a number > 0 representing the number of bytes written
 * @return -1 on error, with @ref errno set appropriately.
 */
static ssize_t spair_write(void *obj, const void *buffer, size_t count)
{
	int res;
	size_t avail;
	bool is_nonblock;
	size_t bytes_written;
	bool have_local_sem = false;
	bool have_remote_sem = false;
	bool will_block = false;
	struct spair *const spair = (struct spair *)obj;
	struct spair *remote = NULL;

	if (obj == NULL || buffer == NULL || count == 0) {
		errno = EINVAL;
		res = -1;
		goto out;
	}

	res = k_sem_take(&spair->sem, K_NO_WAIT);
	is_nonblock = sock_is_nonblock(spair);
	if (res < 0) {
		if (is_nonblock) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}

		res = k_sem_take(&spair->sem, K_FOREVER);
		if (res < 0) {
			errno = -res;
			res = -1;
			goto out;
		}
		is_nonblock = sock_is_nonblock(spair);
	}

	have_local_sem = true;

	remote = z_get_fd_obj(spair->remote,
		(const struct fd_op_vtable *)&spair_fd_op_vtable, 0);

	if (remote == NULL) {
		errno = EPIPE;
		res = -1;
		goto out;
	}

	res = k_sem_take(&remote->sem, K_NO_WAIT);
	if (res < 0) {
		if (is_nonblock) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}
		res = k_sem_take(&remote->sem, K_FOREVER);
		if (res < 0) {
			errno = -res;
			res = -1;
			goto out;
		}
	}

	have_remote_sem = true;

	avail = spair_write_avail(spair);

	if (avail == 0) {
		if (is_nonblock) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}
		will_block = true;
	}

	if (will_block) {
		if (k_is_in_isr()) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}

		for (int signaled = false, result = -1; !signaled;
			result = -1) {

			struct k_poll_event events[] = {
				K_POLL_EVENT_INITIALIZER(
					K_POLL_TYPE_SIGNAL,
					K_POLL_MODE_NOTIFY_ONLY,
					&remote->writeable),
			};

			k_sem_give(&remote->sem);
			have_remote_sem = false;

			res = k_poll(events, ARRAY_SIZE(events), K_FOREVER);
			if (res < 0) {
				errno = -res;
				res = -1;
				goto out;
			}

			remote = z_get_fd_obj(spair->remote,
				(const struct fd_op_vtable *)
				&spair_fd_op_vtable, 0);

			if (remote == NULL) {
				errno = EPIPE;
				res = -1;
				goto out;
			}

			res = k_sem_take(&remote->sem, K_FOREVER);
			if (res < 0) {
				errno = -res;
				res = -1;
				goto out;
			}

			have_remote_sem = true;

			k_poll_signal_check(&remote->writeable, &signaled,
					    &result);
			if (!signaled) {
				continue;
			}

			switch (result) {
				case SPAIR_SIG_DATA: {
					break;
				}

				case SPAIR_SIG_CANCEL: {
					errno = EPIPE;
					res = -1;
					goto out;
				}

				default: {
					__ASSERT(false,
						"unrecognized result: %d",
						result);
					continue;
				}
			}

			/* SPAIR_SIG_DATA was received */
			break;
		}
	}

	res = k_pipe_put(&remote->recv_q, (void *)buffer, count,
			 &bytes_written, 1, K_NO_WAIT);
	__ASSERT(res == 0, "k_pipe_put() failed: %d", res);

	if (spair_write_avail(spair) == 0) {
		k_poll_signal_reset(&remote->writeable);
	}

	res = k_poll_signal_raise(&remote->readable, SPAIR_SIG_DATA);
	__ASSERT(res == 0, "k_poll_signal_raise() failed: %d", res);

	res = bytes_written;

out:

	if (remote != NULL && have_remote_sem) {
		k_sem_give(&remote->sem);
	}
	if (spair != NULL && have_local_sem) {
		k_sem_give(&spair->sem);
	}

	return res;
}

/**
 * Read data from one end of a @ref spair
 *
 * Data written on one file descriptor of a socketpair (with e.g. write(2) or
 * send(2)) can be read at the other end using common POSIX calls such as
 * read(2) or recv(2).
 *
 * If the underlying file descriptor has the @ref O_NONBLOCK flag set then
 * this function will return immediately. If no data was read from a
 * non-blocking file descriptor, then -1 will be returned and @ref errno will
 * be set to @ref EAGAIN.
 *
 * Blocking read operations occur when the @ref O_NONBLOCK flag is @em not set
 * and there are no bytes to read in the @em local @ref spair.pipe.
 *
 * Such a blocking read will suspend execution of the current thread until
 * one of two possible results is received on the @em local
 * @ref spair.readable:
 *
 * -# @ref SPAIR_SIG_DATA - data has been written to the @em local
 *    @ref spair.pipe. Thus, allowing more data to be read.
 *
 * -# @ref SPAIR_SIG_CANCEL - read of the the @em local @spair.pipe
 *    must be cancelled for some reason (e.g. the file descriptor will be
 *    closed imminently). In this case, the function will return -1 and set
 *    @ref errno to @ref EINTR.
 *
 * @param obj the address of an @ref spair object cast to `void *`
 * @param buffer the buffer in which to read
 * @param count the number of bytes to read
 *
 * @return on success, a number > 0 representing the number of bytes written
 * @return -1 on error, with @ref errno set appropriately.
 */
static ssize_t spair_read(void *obj, void *buffer, size_t count)
{
	int res;
	bool is_connected;
	size_t avail;
	bool is_nonblock;
	size_t bytes_read;
	bool have_local_sem = false;
	bool will_block = false;
	struct spair *const spair = (struct spair *)obj;

	if (obj == NULL || buffer == NULL || count == 0) {
		errno = EINVAL;
		res = -1;
		goto out;
	}

	res = k_sem_take(&spair->sem, K_NO_WAIT);
	is_nonblock = sock_is_nonblock(spair);
	if (res < 0) {
		if (is_nonblock) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}

		res = k_sem_take(&spair->sem, K_FOREVER);
		if (res < 0) {
			errno = -res;
			res = -1;
			goto out;
		}
		is_nonblock = sock_is_nonblock(spair);
	}

	have_local_sem = true;

	is_connected = sock_is_connected(spair);
	avail = spair_read_avail(spair);

	if (avail == 0) {
		if (!is_connected) {
			/* signal EOF */
			res = 0;
			goto out;
		}

		if (is_nonblock) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}

		will_block = true;
	}

	if (will_block) {
		if (k_is_in_isr()) {
			errno = EAGAIN;
			res = -1;
			goto out;
		}

		for (int signaled = false, result = -1; !signaled;
			result = -1) {

			struct k_poll_event events[] = {
				K_POLL_EVENT_INITIALIZER(
					K_POLL_TYPE_SIGNAL,
					K_POLL_MODE_NOTIFY_ONLY,
					&spair->readable
				),
			};

			k_sem_give(&spair->sem);
			have_local_sem = false;

			res = k_poll(events, ARRAY_SIZE(events), K_FOREVER);
			__ASSERT(res == 0, "k_poll() failed: %d", res);

			res = k_sem_take(&spair->sem, K_FOREVER);
			__ASSERT(res == 0, "failed to take local sem: %d", res);

			have_local_sem = true;

			k_poll_signal_check(&spair->readable, &signaled,
					    &result);
			if (!signaled) {
				continue;
			}

			switch (result) {
				case SPAIR_SIG_DATA: {
					break;
				}

				case SPAIR_SIG_CANCEL: {
					errno = EPIPE;
					res = -1;
					goto out;
				}

				default: {
					__ASSERT(false,
						"unrecognized result: %d",
						result);
					continue;
				}
			}

			/* SPAIR_SIG_DATA was received */
			break;
		}
	}

	res = k_pipe_get(&spair->recv_q, (void *)buffer, count, &bytes_read,
			 1, K_NO_WAIT);
	__ASSERT(res == 0, "k_pipe_get() failed: %d", res);

	if (spair_read_avail(spair) == 0 && !sock_is_eof(spair)) {
		k_poll_signal_reset(&spair->readable);
	}

	if (is_connected) {
		res = k_poll_signal_raise(&spair->writeable, SPAIR_SIG_DATA);
		__ASSERT(res == 0, "k_poll_signal_raise() failed: %d", res);
	}

	res = bytes_read;

out:

	if (spair != NULL && have_local_sem) {
		k_sem_give(&spair->sem);
	}

	return res;
}

static int zsock_poll_prepare_ctx(struct spair *const spair,
				  struct zsock_pollfd *const pfd,
				  struct k_poll_event **pev,
				  struct k_poll_event *pev_end)
{
	int res;

	struct spair *remote = NULL;
	bool have_remote_sem = false;

	if (pfd->events & ZSOCK_POLLIN) {

		/* Tell poll() to short-circuit wait */
		if (sock_is_eof(spair)) {
			res = -EALREADY;
			goto out;
		}

		if (*pev == pev_end) {
			res = -ENOMEM;
			goto out;
		}

		/* Wait until data has been written to the local end */
		(*pev)->obj = &spair->readable;
	}

	if (pfd->events & ZSOCK_POLLOUT) {

		/* Tell poll() to short-circuit wait */
		if (!sock_is_connected(spair)) {
			res = -EALREADY;
			goto out;
		}

		if (*pev == pev_end) {
			res = -ENOMEM;
			goto out;
		}

		remote = z_get_fd_obj(spair->remote,
			(const struct fd_op_vtable *)
			&spair_fd_op_vtable, 0);

		__ASSERT(remote != NULL, "remote is NULL");

		res = k_sem_take(&remote->sem, K_FOREVER);
		if (res < 0) {
			goto out;
		}

		have_remote_sem = true;

		/* Wait until the recv queue on the remote end is no longer full */
		(*pev)->obj = &remote->writeable;
	}

	(*pev)->type = K_POLL_TYPE_SIGNAL;
	(*pev)->mode = K_POLL_MODE_NOTIFY_ONLY;
	(*pev)->state = K_POLL_STATE_NOT_READY;

	(*pev)++;

	res = 0;

out:

	if (remote != NULL && have_remote_sem) {
		k_sem_give(&remote->sem);
	}

	return res;
}

static int zsock_poll_update_ctx(struct spair *const spair,
				 struct zsock_pollfd *const pfd,
				 struct k_poll_event **pev)
{
	int res;
	int signaled;
	int result;
	struct spair *remote = NULL;
	bool have_remote_sem = false;

	if (pfd->events & ZSOCK_POLLOUT) {
		if (!sock_is_connected(spair)) {
			pfd->revents |= ZSOCK_POLLHUP;
			goto pollout_done;
		}

		remote = z_get_fd_obj(spair->remote,
			(const struct fd_op_vtable *) &spair_fd_op_vtable, 0);

		__ASSERT(remote != NULL, "remote is NULL");

		res = k_sem_take(&remote->sem, K_FOREVER);
		if (res < 0) {
			/* if other end is deleted, this might occur */
			goto pollout_done;
		}

		have_remote_sem = true;

		if (spair_write_avail(spair) > 0) {
			pfd->revents |= ZSOCK_POLLOUT;
			goto pollout_done;
		}

		/* check to see if op was canceled */
		signaled = false;
		k_poll_signal_check(&remote->writeable, &signaled, &result);
		if (signaled) {
			/* Cannot be SPAIR_SIG_DATA, because
			 * spair_write_avail() would have
			 * returned 0
			 */
			__ASSERT(result == SPAIR_SIG_CANCEL,
				"invalid result %d", result);
			pfd->revents |= ZSOCK_POLLHUP;
		}
	}

pollout_done:

	if (pfd->events & ZSOCK_POLLIN) {
		if (sock_is_eof(spair)) {
			pfd->revents |= ZSOCK_POLLIN;
			goto pollin_done;
		}

		if (spair_read_avail(spair) > 0) {
			pfd->revents |= ZSOCK_POLLIN;
			goto pollin_done;
		}

		/* check to see if op was canceled */
		signaled = false;
		k_poll_signal_check(&spair->readable, &signaled, &result);
		if (signaled) {
			/* Cannot be SPAIR_SIG_DATA, because
			 * spair_read_avail() would have
			 * returned 0
			 */
			__ASSERT(result == SPAIR_SIG_CANCEL,
					 "invalid result %d", result);
			pfd->revents |= ZSOCK_POLLIN;
		}
	}

pollin_done:
	res = 0;

	(*pev)++;

	if (remote != NULL && have_remote_sem) {
		k_sem_give(&remote->sem);
	}

	return res;
}

static int spair_ioctl(void *obj, unsigned int request, va_list args)
{
	int res;
	struct zsock_pollfd *pfd;
	struct k_poll_event **pev;
	struct k_poll_event *pev_end;
	int flags = 0;
	bool have_local_sem = false;
	struct spair *const spair = (struct spair *)obj;

	if (spair == NULL) {
		errno = EINVAL;
		res = -1;
		goto out;
	}

	/* The local sem is always taken in this function. If a subsequent
	 * function call requires the remote sem, it must acquire and free the
	 * remote sem.
	 */
	res = k_sem_take(&spair->sem, K_FOREVER);
	__ASSERT(res == 0, "failed to take local sem: %d", res);

	have_local_sem = true;

	switch (request) {
		case F_GETFL: {
			if (sock_is_nonblock(spair)) {
				flags |= O_NONBLOCK;
			}

			res = flags;
			goto out;
		}

		case F_SETFL: {
			flags = va_arg(args, int);

			if (flags & O_NONBLOCK) {
				spair->flags |= SPAIR_FLAG_NONBLOCK;
			} else {
				spair->flags &= ~SPAIR_FLAG_NONBLOCK;
			}

			res = 0;
			goto out;
		}

		case ZFD_IOCTL_FIONBIO: {
			spair->flags |= SPAIR_FLAG_NONBLOCK;
			res = 0;
			goto out;
		}

		case ZFD_IOCTL_FIONREAD: {
			int *nbytes;

			nbytes = va_arg(args, int *);
			*nbytes = spair_read_avail(spair);

			res = 0;
			goto out;
		}

		case ZFD_IOCTL_POLL_PREPARE: {
			pfd = va_arg(args, struct zsock_pollfd *);
			pev = va_arg(args, struct k_poll_event **);
			pev_end = va_arg(args, struct k_poll_event *);

			res = zsock_poll_prepare_ctx(obj, pfd, pev, pev_end);
			goto out;
		}

		case ZFD_IOCTL_POLL_UPDATE: {
			pfd = va_arg(args, struct zsock_pollfd *);
			pev = va_arg(args, struct k_poll_event **);

			res = zsock_poll_update_ctx(obj, pfd, pev);
			goto out;
		}

		default: {
			errno = EOPNOTSUPP;
			res = -1;
			goto out;
		}
	}

out:
	if (spair != NULL && have_local_sem) {
		k_sem_give(&spair->sem);
	}

	return res;
}

static int spair_bind(void *obj, const struct sockaddr *addr,
		      socklen_t addrlen)
{
	ARG_UNUSED(obj);
	ARG_UNUSED(addr);
	ARG_UNUSED(addrlen);

	errno = EISCONN;
	return -1;
}

static int spair_connect(void *obj, const struct sockaddr *addr,
			 socklen_t addrlen)
{
	ARG_UNUSED(obj);
	ARG_UNUSED(addr);
	ARG_UNUSED(addrlen);

	errno = EISCONN;
	return -1;
}

static int spair_listen(void *obj, int backlog)
{
	ARG_UNUSED(obj);
	ARG_UNUSED(backlog);

	errno = EINVAL;
	return -1;
}

static int spair_accept(void *obj, struct sockaddr *addr,
			socklen_t *addrlen)
{
	ARG_UNUSED(obj);
	ARG_UNUSED(addr);
	ARG_UNUSED(addrlen);

	errno = EOPNOTSUPP;
	return -1;
}

static ssize_t spair_sendto(void *obj, const void *buf, size_t len,
			    int flags, const struct sockaddr *dest_addr,
				 socklen_t addrlen)
{
	ARG_UNUSED(flags);
	ARG_UNUSED(dest_addr);
	ARG_UNUSED(addrlen);

	return spair_write(obj, buf, len);
}

static ssize_t spair_sendmsg(void *obj, const struct msghdr *msg,
			     int flags)
{
	ARG_UNUSED(flags);

	int res;
	size_t len = 0;
	bool is_connected;
	size_t avail;
	bool is_nonblock;
	struct spair *const spair = (struct spair *)obj;

	if (spair == NULL || msg == NULL) {
		errno = EINVAL;
		res = -1;
		goto out;
	}

	is_connected = sock_is_connected(spair);
	avail = is_connected ? spair_write_avail(spair) : 0;
	is_nonblock = sock_is_nonblock(spair);

	for (size_t i = 0; i < msg->msg_iovlen; ++i) {
		/* check & msg->msg_iov[i]? */
		/* check & msg->msg_iov[i].iov_base? */
		len += msg->msg_iov[i].iov_len;
	}

	if (!is_connected) {
		errno = EPIPE;
		res = -1;
		goto out;
	}

	if (len == 0) {
		res = 0;
		goto out;
	}

	if (len > avail && is_nonblock) {
		errno = EMSGSIZE;
		res = -1;
		goto out;
	}

	for (size_t i = 0; i < msg->msg_iovlen; ++i) {
		res = spair_write(spair, msg->msg_iov[i].iov_base,
			msg->msg_iov[i].iov_len);
		if (res == -1) {
			goto out;
		}
	}

	res = len;

out:
	return res;
}

static ssize_t spair_recvfrom(void *obj, void *buf, size_t max_len,
			      int flags, struct sockaddr *src_addr,
				   socklen_t *addrlen)
{
	(void)flags;
	(void)src_addr;
	(void)addrlen;

	if (addrlen != NULL) {
		/* Protocol (PF_UNIX) does not support addressing with connected
		 * sockets and, therefore, it is unspecified behaviour to modify
		 * src_addr. However, it would be ambiguous to leave addrlen
		 * untouched if the user expects it to be updated. It is not
		 * mentioned that modifying addrlen is unspecified. Therefore
		 * we choose to eliminate ambiguity.
		 *
		 * Setting it to zero mimics Linux's behaviour.
		 */
		*addrlen = 0;
	}

	return spair_read(obj, buf, max_len);
}

static int spair_getsockopt(void *obj, int level, int optname,
			    void *optval, socklen_t *optlen)
{
	ARG_UNUSED(obj);
	ARG_UNUSED(level);
	ARG_UNUSED(optname);
	ARG_UNUSED(optval);
	ARG_UNUSED(optlen);

	errno = ENOPROTOOPT;
	return -1;
}

static int spair_setsockopt(void *obj, int level, int optname,
			    const void *optval, socklen_t optlen)
{
	ARG_UNUSED(obj);
	ARG_UNUSED(level);
	ARG_UNUSED(optname);
	ARG_UNUSED(optval);
	ARG_UNUSED(optlen);

	errno = ENOPROTOOPT;
	return -1;
}

static int spair_close(void *obj)
{
	struct spair *const spair = (struct spair *)obj;
	int res;

	res = k_sem_take(&spair->sem, K_FOREVER);
	__ASSERT(res == 0, "failed to take local sem: %d", res);

	/* disconnect the remote endpoint */
	spair_delete(spair);

	/* Note that the semaphore released already so need to do it here */

	return 0;
}

static const struct socket_op_vtable spair_fd_op_vtable = {
	.fd_vtable = {
		.read = spair_read,
		.write = spair_write,
		.close = spair_close,
		.ioctl = spair_ioctl,
	},
	.bind = spair_bind,
	.connect = spair_connect,
	.listen = spair_listen,
	.accept = spair_accept,
	.sendto = spair_sendto,
	.sendmsg = spair_sendmsg,
	.recvfrom = spair_recvfrom,
	.getsockopt = spair_getsockopt,
	.setsockopt = spair_setsockopt,
};
