diff options
Diffstat (limited to 'libmisc')
-rw-r--r-- | libmisc/CMakeLists.txt | 8 | ||||
-rw-r--r-- | libmisc/include/libmisc/net.h | 64 | ||||
-rw-r--r-- | libmisc/include/libmisc/vcall.h | 27 |
3 files changed, 99 insertions, 0 deletions
diff --git a/libmisc/CMakeLists.txt b/libmisc/CMakeLists.txt new file mode 100644 index 0000000..f42f36f --- /dev/null +++ b/libmisc/CMakeLists.txt @@ -0,0 +1,8 @@ +# libmisc/CMakeLists.txt - A simple Go-ish object system built on GCC -fplan9-extensions +# +# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-Licence-Identifier: AGPL-3.0-or-later + +add_library(libmisc INTERFACE) +target_include_directories(libmisc SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_options(libmisc INTERFACE "$<$<COMPILE_LANGUAGE:C>:-fplan9-extensions>") diff --git a/libmisc/include/libmisc/net.h b/libmisc/include/libmisc/net.h new file mode 100644 index 0000000..bb5999b --- /dev/null +++ b/libmisc/include/libmisc/net.h @@ -0,0 +1,64 @@ +/* libmisc/net.h - Base definitions for network interfaces + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_NET_H_ +#define _LIBMISC_NET_H_ + +#include <stdbool.h> /* for bool */ +#include <stddef.h> /* for size_t */ +#include <sys/types.h> /* for ssize_t */ + +struct net_ip4_addr { + unsigned char octets[4]; +}; + +struct net_eth_addr { + unsigned char octets[6]; +}; + +struct net_conn; +struct net_listener; + +struct net_listener_vtable { + /** + * It is invalid to accept() a new connection if an existing + * connection is still open. + */ + struct net_conn *(*accept)(struct net_listener *self); +}; + +struct net_conn_vtable { + /** + * Return bytes-read on success, 0 on EOF, -errno on error; a + * short read is *not* an error. + */ + ssize_t (*read)(struct net_conn *self, 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 (*write)(struct net_conn *self, void *buf, size_t count); + + /** + * Return 0 on success, -errno on error. + */ + int (*close)(struct net_conn *self, bool rd, bool wr); +}; + +typedef struct net_listener { + struct net_listener_vtable *vtable; +} implements_net_listener; + +typedef struct net_conn { + struct net_conn_vtable *vtable; +} implements_net_conn; + +#endif /* _LIBMISC_NET_H_ */ diff --git a/libmisc/include/libmisc/vcall.h b/libmisc/include/libmisc/vcall.h new file mode 100644 index 0000000..c3562ee --- /dev/null +++ b/libmisc/include/libmisc/vcall.h @@ -0,0 +1,27 @@ +/* libmisc/vcall.h - A simple Go-ish object system built on GCC -fplan9-extensions + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_VCALL_H_ +#define _LIBMISC_VCALL_H_ + +#include <assert.h> /* for assert() and static_assert() */ +#include <stddef.h> /* for offsetof() */ + +#define VCALL(o, m, ...) \ + ({ \ + assert(o); \ + (o)->vtable->m(o __VA_OPT__(,) __VA_ARGS__); \ + }) + +#define VCALL_SELF(obj_typ, iface_typ, iface_ptr) \ + ({ \ + static_assert(_Generic(iface_ptr, iface_typ *: 1, default: 0), \ + "typeof("#iface_ptr") != "#iface_typ); \ + assert(iface_ptr); \ + ((obj_typ*)(((void*)iface_ptr)-offsetof(obj_typ,iface_typ))); \ + }) + +#endif /* _LIBMISC_VCALL_H_ */ |