summaryrefslogtreecommitdiff
path: root/libnetio
diff options
context:
space:
mode:
Diffstat (limited to 'libnetio')
-rw-r--r--libnetio/CMakeLists.txt13
-rw-r--r--libnetio/include/libnetio/netio.h27
-rw-r--r--libnetio/netio_posix.c238
3 files changed, 0 insertions, 278 deletions
diff --git a/libnetio/CMakeLists.txt b/libnetio/CMakeLists.txt
deleted file mode 100644
index fcfecfd..0000000
--- a/libnetio/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# libnetio/CMakeLists.txt - Build script for libnetio support library
-#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-Licence-Identifier: AGPL-3.0-or-later
-
-add_library(libnetio INTERFACE)
-target_sources(libnetio INTERFACE
- netio_posix.c
-)
-target_link_libraries(libnetio INTERFACE
- libcr_ipc
-)
-target_include_directories(libnetio SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
diff --git a/libnetio/include/libnetio/netio.h b/libnetio/include/libnetio/netio.h
deleted file mode 100644
index 370d2ca..0000000
--- a/libnetio/include/libnetio/netio.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _NETIO_H_
-#define _NETIO_H_
-
-#include <stdbool.h> /* for bool */
-#include <stdint.h> /* for uint16_t */
-#include <stddef.h> /* for size_t */
-#include <sys/types.h> /* for ssize_t */
-
-/** Return socket-fd on success, -errno on error. */
-int netio_listen(uint16_t port);
-/** Return connection-fd on success, -errno on error. */
-int netio_accept(int sock);
-/** Return bytes-read on success, 0 on EOF, -errno on error; a short read is *not* an error. */
-ssize_t netio_read(int conn, void *buf, size_t count);
-/**
- * Return `count` on success, -errno on error; a short write *is* an
- * error.
- *
- * Writes are *not* guaranteed to be atomic (as this would be
- * expensive to implement), so if you have concurrent writers then you
- * should arrange for a mutex to protect the connection.
- */
-ssize_t netio_write(int conn, void *buf, size_t count);
-/** Return 0 on success, -errno on error. */
-int netio_close(int conn, bool rd, bool wr);
-
-#endif /* _NETIO_H_ */
diff --git a/libnetio/netio_posix.c b/libnetio/netio_posix.c
deleted file mode 100644
index f3e9fe0..0000000
--- a/libnetio/netio_posix.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* netio_posix.c - netio implementation for POSIX-ish systems
- * (actually uses a few GNU extensions)
- *
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-Licence-Identifier: AGPL-3.0-or-later
- */
-
-#define _GNU_SOURCE /* for pthread_sigqueue(3gnu) */
-/* misc */
-#include <assert.h> /* for assert() */
-#include <errno.h> /* for errno, EAGAIN, EINVAL */
-#include <error.h> /* for error(3gnu) */
-#include <stdlib.h> /* for abs(), shutdown(), SHUT_RD, SHUT_WR, SHUT_RDWR */
-#include <unistd.h> /* for read(), write() */
-/* net */
-#include <arpa/inet.h> /* for htons(3p) */
-#include <netinet/in.h> /* for struct sockaddr_in */
-#include <sys/socket.h> /* for struct sockaddr, socket(), SOCK_* flags, setsockopt(), SOL_SOCKET, SO_REUSEADDR, bind(), listen(), accept() */
-/* async */
-#include <pthread.h> /* for pthread_* */
-#include <signal.h> /* for siginfo_t, struct sigaction, enum sigval, sigaction(), SIGRTMIN, SIGRTMAX, SA_SIGINFO */
-
-#include <libcr/coroutine.h>
-
-#include <libnetio/netio.h>
-
-/* configuration **************************************************************/
-
-#include "config.h"
-
-#ifndef CONFIG_NETIO_NUM_CONNS
-# error config.h must define CONFIG_NETIO_NUM_CONNS
-#endif
-
-/* common *********************************************************************/
-
-#define UNUSED(name) /* name __attribute__ ((unused)) */
-
-static int sig_io = 0;
-
-static void handle_sig_io(int UNUSED(sig), siginfo_t *info, void *UNUSED(ucontext)) {
- cr_unpause_from_intrhandler((cid_t)info->si_value.sival_int);
-}
-
-static void _netio_init(void) {
- struct sigaction action = {0};
-
- if (sig_io)
- return;
-
- sig_io = SIGRTMIN;
- if (sig_io > SIGRTMAX)
- error(1, 0, "SIGRTMAX exceeded");
-
- action.sa_flags = SA_SIGINFO;
- action.sa_sigaction = handle_sig_io;
- if (sigaction(sig_io, &action, NULL) < 0)
- error(1, errno, "sigaction");
-}
-
-#define WAKE_COROUTINE(args) do { \
- int r; \
- union sigval val = {0}; \
- val.sival_int = (int)((args)->cr_coroutine); \
- do { \
- r = pthread_sigqueue((args)->cr_thread, sig_io, val); \
- assert(r == 0 || r == EAGAIN); \
- } while (r == EAGAIN); \
- } while (0)
-
-#define RUN_PTHREAD(fn, args) do { \
- pthread_t thread; \
- int r; \
- r = pthread_create(&thread, NULL, fn, args); \
- if (r) \
- return -abs(r); \
- cr_pause_and_yield(); \
- r = pthread_join(thread, NULL); \
- if (r) \
- return -abs(r); \
- } while (0)
-
-/* listen() *******************************************************************/
-
-int netio_listen(uint16_t port) {
- int sockfd;
- union {
- struct sockaddr_in in;
- struct sockaddr gen;
- } addr = { 0 };
-
- _netio_init();
-
- addr.in.sin_family = AF_INET;
- addr.in.sin_port = htons(port);
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- error(1, errno, "socket");
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0)
- error(1, errno, "setsockopt");
- if (bind(sockfd, &addr.gen, sizeof addr) < 0)
- error(1, errno, "bind");
- if (listen(sockfd, CONFIG_NETIO_NUM_CONNS) < 0)
- error(1, errno, "listen");
-
- return sockfd;
-}
-
-/* accept() *******************************************************************/
-
-struct _pthread_accept_args {
- pthread_t cr_thread;
- cid_t cr_coroutine;
-
- int sockfd;
-
- int *ret;
-};
-
-void *_pthread_accept(void *_args) {
- struct _pthread_accept_args *args = _args;
- *(args->ret) = accept(args->sockfd, NULL, NULL);
- if (*(args->ret) < 0)
- *(args->ret) = -errno;
- WAKE_COROUTINE(args);
- return NULL;
-};
-
-int netio_accept(int sock) {
- int ret;
- struct _pthread_accept_args args = {
- .cr_thread = pthread_self(),
- .cr_coroutine = cr_getcid(),
- .sockfd = sock,
- .ret = &ret,
- };
- RUN_PTHREAD(_pthread_accept, &args);
- return ret;
-}
-
-/* read() *********************************************************************/
-
-struct _pthread_read_args {
- pthread_t cr_thread;
- cid_t cr_coroutine;
-
- int connfd;
- void *buf;
- size_t count;
-
- ssize_t *ret;
-};
-
-void *_pthread_read(void *_args) {
- struct _pthread_read_args *args = _args;
- *(args->ret) = read(args->connfd, args->buf, args->count);
- if (*(args->ret) < 0)
- *(args->ret) = -errno;
- WAKE_COROUTINE(args);
- return NULL;
-};
-
-ssize_t netio_read(int conn, void *buf, size_t count) {
- ssize_t ret;
- struct _pthread_read_args args = {
- .cr_thread = pthread_self(),
- .cr_coroutine = cr_getcid(),
-
- .connfd = conn,
- .buf = buf,
- .count = count,
-
- .ret = &ret,
- };
- RUN_PTHREAD(_pthread_read, &args);
- return ret;
-}
-
-/* write() ********************************************************************/
-
-struct _pthread_write_args {
- pthread_t cr_thread;
- cid_t cr_coroutine;
-
- int connfd;
- void *buf;
- size_t count;
-
- ssize_t *ret;
-};
-
-void *_pthread_write(void *_args) {
- struct _pthread_read_args *args = _args;
- size_t done = 0;
- while (done < args->count) {
- ssize_t r = write(args->connfd, args->buf, args->count);
- if (r < 0) {
- *(args->ret) = -errno;
- break;
- }
- done += r;
- }
- if (done == args->count)
- *(args->ret) = done;
- WAKE_COROUTINE(args);
- return NULL;
-};
-
-ssize_t netio_write(int conn, void *buf, size_t count) {
- ssize_t ret;
- struct _pthread_write_args args = {
- .cr_thread = pthread_self(),
- .cr_coroutine = cr_getcid(),
-
- .connfd = conn,
- .buf = buf,
- .count = count,
-
- .ret = &ret,
- };
- RUN_PTHREAD(_pthread_write, &args);
- return ret;
-}
-
-/* close() ********************************************************************/
-
-int netio_close(int conn, bool rd, bool wr) {
- int how;
- if (rd && wr)
- how = SHUT_RDWR;
- else if (rd && !wr)
- how = SHUT_RD;
- else if (!rd && wr)
- how = SHUT_WR;
- else
- return -EINVAL;
- return shutdown(conn, how) ? -errno : 0;
-}