// SPDX-License-Identifier: GPL-2.0-or-later /* PASST - Plug A Simple Socket Transport * for qemu/UNIX domain socket mode * * PASTA - Pack A Subtle Tap Abstraction * for network namespace/tap device mode * * PESTO - Programmable Extensible Socket Translation Orchestrator * front-end for passt(1) and pasta(1) forwarding configuration * * serialise.c - Serialisation of data structures over bytestreams * * Copyright Red Hat * Author: David Gibson */ #include #include #include #include #include #include "serialise.h" /** * seread_buf() - Fill a whole buffer from a file descriptor * @fd: File descriptor * @buf: Pointer to base of buffer * @len: Length of buffer * * Return: 0 on success, -1 on error (with errno set) * * #syscalls read */ int seread_buf(int fd, void *buf, size_t len) { size_t left = len; char *p = buf; while (left) { ssize_t rc; assert(left <= len); do rc = read(fd, p, left); while ((rc < 0) && errno == EINTR); if (rc < 0) return -1; if (rc == 0) { errno = ENODATA; return -1; } p += rc; left -= rc; } return 0; } /** * sewrite_buf() - write all of a buffer to an fd * @fd: File descriptor * @buf: Pointer to base of buffer * @len: Length of buffer * * Return: 0 on success, -1 on error (with errno set) * * #syscalls write */ int sewrite_buf(int fd, const void *buf, size_t len) { const char *p = buf; size_t left = len; while (left) { ssize_t rc; do rc = write(fd, p, left); while ((rc < 0) && errno == EINTR); if (rc < 0) return -1; p += rc; left -= rc; } return 0; } /** * seread_uXXX() - Receive a uXXX value from an fd * @fd: File descriptor to read from * @valp: Pointer to variable to update with read value * * Return: 0 on success, -1 on error */ /** * sewrite_uXXX() - Send a uXXX value to an fd * @fd: File descriptor to write to * @val: Value to send * * Return: 0 on success, -1 on error */ #define SERIALISE_UINT(bits) \ int seread_u##bits(int fd, uint##bits##_t *val) \ { \ uint##bits##_t beval; \ if (seread_var(fd, &beval) < 0) \ return -1; \ *val = be##bits##toh(beval); \ return 0; \ } \ int sewrite_u##bits(int fd, uint##bits##_t val) \ { \ uint##bits##_t beval = htobe##bits(val); \ return sewrite_var(fd, &beval); \ } SERIALISE_UINT(32) #undef SERIALISE_UNIT