From: Michael D. Lowis Date: Thu, 3 Nov 2022 17:06:54 +0000 (-0400) Subject: implemented skeleton of mbusd. Next step is message parsing and handling X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4fec5b606511f1e07e63f4aa1bcb6f3acfc7c7f8;p=proto%2Faos.git implemented skeleton of mbusd. Next step is message parsing and handling --- diff --git a/.gitignore b/.gitignore index 12d18d3..05b361e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ build/ build.bin tags -rules.mk temp diff --git a/Makefile b/Makefile index d2c79de..582845d 100644 --- a/Makefile +++ b/Makefile @@ -3,17 +3,16 @@ all: libs bins clean: - rm -r build/ rules.mk + rm -rf $(OUTDIR) rules.mk bins: libs -include config.mk - rules: ./mkrules $(OUTDIR) rules.mk: ./mkrules $(OUTDIR) +include config.mk include rules.mk include bin/rules.mk diff --git a/bin/mbusd.c b/bin/mbusd.c index 3ee86cd..84d7369 100644 --- a/bin/mbusd.c +++ b/bin/mbusd.c @@ -1,19 +1,81 @@ +#include #include +#include +#include -#define MAX_CONNS 1024 +#define BITS_PER_SLOT ((long)sizeof(long) * 8u) -char* Usage = "mbusd DIALSTR"; +typedef enum { + STATE_DISCONNECTED = 0, + STATE_AUTHORIZING = 1, + STATE_CONNECTED = 2, +} ClientState_T; + +typedef struct { + ClientState_T state; + Int fd; +} Client_T; +char* Usage = "mbusd DIALSTR"; Thread_T MessagingThread; Mutex_T Lock; -long ConnectionMap[MAX_CONNS / sizeof(long)] = {0}; +size_t MaxClients; +long* ClientMap; +struct pollfd* PollItems; +Client_T* Clients; + +size_t UpdateMaxFileDescriptorCount(void) +{ + struct rlimit rlim = {0}; + if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) + { + fatal("getrlimit:"); + } + rlim.rlim_cur = rlim.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) + { + fatal("setrlimit:"); + } + return rlim.rlim_cur; +} void RegisterNewClient(Int cfd) { + long slot_pos = cfd / BITS_PER_SLOT; + long bit_pos = cfd % BITS_PER_SLOT; Mutex_Lock(&Lock); - // Add fd to connection map + Clients[cfd].fd = cfd; + Clients[cfd].state = STATE_DISCONNECTED; + ClientMap[slot_pos] |= ((long)1 << bit_pos); Mutex_Unlock(&Lock); - (void)cfd; +} + +size_t PollClients(void) +{ + size_t fd_count = 0; + size_t num_slots = MaxClients / BITS_PER_SLOT; + Mutex_Lock(&Lock); + for (size_t i = 0; i < num_slots; i++) + { + long slot = ClientMap[i]; + for (int bit = 0; slot && bit < BITS_PER_SLOT; bit++) + { + if (slot & ((long)1 << bit)) + { + PollItems[fd_count].fd = slot + bit; + PollItems[fd_count].events = POLLIN; + PollItems[fd_count].revents = 0; + fd_count++; + } + } + } + Mutex_Unlock(&Lock); + errno = 0; + if ((poll(PollItems, fd_count, 10) < 0) && (errno != EINTR)) + { + fatal("poll():"); + } + return fd_count; } Int ProcessMessages(void* arg) @@ -21,20 +83,27 @@ Int ProcessMessages(void* arg) (void)arg; for (;;) { - Mutex_Lock(&Lock); - // for each FD in set - // Setup poll struct - Mutex_Unlock(&Lock); - // poll() for input - // for each poll struct - // if closed + size_t fd_count = PollClients(); + for (size_t i = 0; i < fd_count; i++) + { + if (PollItems[i].revents & POLLIN) + { + // Read the message + // publish the message + } + else /* POLLERR | POLLHUP */ + { + int cfd = PollItems[i].fd; + long slot_pos = cfd / BITS_PER_SLOT; + long bit_pos = cfd % BITS_PER_SLOT; Mutex_Lock(&Lock); - // clear it from map - // close fd + Clients[cfd].fd = cfd; + Clients[cfd].state = STATE_DISCONNECTED; + ClientMap[slot_pos] &= ~((long)1 << bit_pos); Mutex_Unlock(&Lock); - // else if data available - // read message - // publish message to subscribing clients + close(cfd); + } + } } return 0; @@ -42,13 +111,21 @@ Int ProcessMessages(void* arg) int main(int argc, char** argv) { + /* check the arguments for validity */ if (argc != 1) { Options_PrintHelp(); return 1; } + /* initialize the global state */ Mutex_Init(&Lock); + MaxClients = UpdateMaxFileDescriptorCount(); + Clients = calloc(MaxClients, sizeof(Client_T)); + ClientMap = calloc(MaxClients, sizeof(Client_T)); + PollItems = calloc(MaxClients, sizeof(struct pollfd)); + + /* now start the client thread and server */ Thread_Create(&MessagingThread, ProcessMessages, NULL); Net_Serve(argv[0], RegisterNewClient); diff --git a/mkrules b/mkrules index 56fd522..2fe8e69 100755 --- a/mkrules +++ b/mkrules @@ -31,7 +31,7 @@ libs="" libname="$(basename "$lib")" libs="$libs \$(OUTDIR)/$libdir/lib$libname.a" - find "$lib" -name '*.c' | ObjectRules "\$(OUTDIR)/$libdir/lib$libname.a" + find "$lib" -name '*.c' | ObjectRules "\$(OUTDIR)/$libdir/lib$libname.a" puts "\$(OUTDIR)/$libdir/lib$libname.a:" printf "\t\$(ARCHIVE)\n" puts "libs: \$(OUTDIR)/$libdir/lib$libname.a" diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..cd6fb9e --- /dev/null +++ b/rules.mk @@ -0,0 +1,218 @@ +$(OUTDIR)/obj/lib/a/UTF8.o: lib/a/UTF8.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/UTF8.o +-include $(OUTDIR)/obj/lib/a/UTF8.d +$(OUTDIR)/obj/lib/a/stdlib/erealloc.o: lib/a/stdlib/erealloc.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/erealloc.o +-include $(OUTDIR)/obj/lib/a/stdlib/erealloc.d +$(OUTDIR)/obj/lib/a/stdlib/forkexec.o: lib/a/stdlib/forkexec.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/forkexec.o +-include $(OUTDIR)/obj/lib/a/stdlib/forkexec.d +$(OUTDIR)/obj/lib/a/stdlib/efreadline.o: lib/a/stdlib/efreadline.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/efreadline.o +-include $(OUTDIR)/obj/lib/a/stdlib/efreadline.d +$(OUTDIR)/obj/lib/a/stdlib/esignal.o: lib/a/stdlib/esignal.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/esignal.o +-include $(OUTDIR)/obj/lib/a/stdlib/esignal.d +$(OUTDIR)/obj/lib/a/stdlib/estrdup.o: lib/a/stdlib/estrdup.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/estrdup.o +-include $(OUTDIR)/obj/lib/a/stdlib/estrdup.d +$(OUTDIR)/obj/lib/a/stdlib/eraise.o: lib/a/stdlib/eraise.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/eraise.o +-include $(OUTDIR)/obj/lib/a/stdlib/eraise.d +$(OUTDIR)/obj/lib/a/stdlib/strmcat.o: lib/a/stdlib/strmcat.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/strmcat.o +-include $(OUTDIR)/obj/lib/a/stdlib/strmcat.d +$(OUTDIR)/obj/lib/a/stdlib/efopen.o: lib/a/stdlib/efopen.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/efopen.o +-include $(OUTDIR)/obj/lib/a/stdlib/efopen.d +$(OUTDIR)/obj/lib/a/stdlib/ecalloc.o: lib/a/stdlib/ecalloc.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/ecalloc.o +-include $(OUTDIR)/obj/lib/a/stdlib/ecalloc.d +$(OUTDIR)/obj/lib/a/stdlib/smprintf.o: lib/a/stdlib/smprintf.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/smprintf.o +-include $(OUTDIR)/obj/lib/a/stdlib/smprintf.d +$(OUTDIR)/obj/lib/a/stdlib/warn.o: lib/a/stdlib/warn.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/warn.o +-include $(OUTDIR)/obj/lib/a/stdlib/warn.d +$(OUTDIR)/obj/lib/a/stdlib/emalloc.o: lib/a/stdlib/emalloc.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/emalloc.o +-include $(OUTDIR)/obj/lib/a/stdlib/emalloc.d +$(OUTDIR)/obj/lib/a/stdlib/fatal.o: lib/a/stdlib/fatal.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/stdlib/fatal.o +-include $(OUTDIR)/obj/lib/a/stdlib/fatal.d +$(OUTDIR)/obj/lib/a/Mutex.o: lib/a/Mutex.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/Mutex.o +-include $(OUTDIR)/obj/lib/a/Mutex.d +$(OUTDIR)/obj/lib/a/Thread.o: lib/a/Thread.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/Thread.o +-include $(OUTDIR)/obj/lib/a/Thread.d +$(OUTDIR)/obj/lib/a/defaults/argv0.o: lib/a/defaults/argv0.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/defaults/argv0.o +-include $(OUTDIR)/obj/lib/a/defaults/argv0.d +$(OUTDIR)/obj/lib/a/defaults/set_option.o: lib/a/defaults/set_option.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/defaults/set_option.o +-include $(OUTDIR)/obj/lib/a/defaults/set_option.d +$(OUTDIR)/obj/lib/a/defaults/options.o: lib/a/defaults/options.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/defaults/options.o +-include $(OUTDIR)/obj/lib/a/defaults/options.d +$(OUTDIR)/obj/lib/a/defaults/usage.o: lib/a/defaults/usage.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/defaults/usage.o +-include $(OUTDIR)/obj/lib/a/defaults/usage.d +$(OUTDIR)/obj/lib/a/GC.o: lib/a/GC.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/GC.o +-include $(OUTDIR)/obj/lib/a/GC.d +$(OUTDIR)/obj/lib/a/Net.o: lib/a/Net.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/Net.o +-include $(OUTDIR)/obj/lib/a/Net.d +$(OUTDIR)/obj/lib/a/Options.o: lib/a/Options.c config.mk + $(OBJECT) +$(OUTDIR)/lib/liba.a: $(OUTDIR)/obj/lib/a/Options.o +-include $(OUTDIR)/obj/lib/a/Options.d +$(OUTDIR)/lib/liba.a: + $(ARCHIVE) +libs: $(OUTDIR)/lib/liba.a +$(OUTDIR)/obj/lib/ui/window_hide.o: lib/ui/window_hide.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/window_hide.o +-include $(OUTDIR)/obj/lib/ui/window_hide.d +$(OUTDIR)/obj/lib/ui/window_show.o: lib/ui/window_show.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/window_show.o +-include $(OUTDIR)/obj/lib/ui/window_show.d +$(OUTDIR)/obj/lib/ui/font_close.o: lib/ui/font_close.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/font_close.o +-include $(OUTDIR)/obj/lib/ui/font_close.d +$(OUTDIR)/obj/lib/ui/font_load.o: lib/ui/font_load.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/font_load.o +-include $(OUTDIR)/obj/lib/ui/font_load.d +$(OUTDIR)/obj/lib/ui/window_create.o: lib/ui/window_create.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/window_create.o +-include $(OUTDIR)/obj/lib/ui/window_create.d +$(OUTDIR)/obj/lib/ui/ui_begin.o: lib/ui/ui_begin.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/ui_begin.o +-include $(OUTDIR)/obj/lib/ui/ui_begin.d +$(OUTDIR)/obj/lib/ui/window_delete.o: lib/ui/window_delete.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/window_delete.o +-include $(OUTDIR)/obj/lib/ui/window_delete.d +$(OUTDIR)/obj/lib/ui/ui_end.o: lib/ui/ui_end.c config.mk + $(OBJECT) +$(OUTDIR)/lib/libui.a: $(OUTDIR)/obj/lib/ui/ui_end.o +-include $(OUTDIR)/obj/lib/ui/ui_end.d +$(OUTDIR)/lib/libui.a: + $(ARCHIVE) +libs: $(OUTDIR)/lib/libui.a +libs = $(OUTDIR)/lib/liba.a $(OUTDIR)/lib/libui.a +$(OUTDIR)/obj/bin/dial.o: bin/dial.c + $(OBJECT) +$(OUTDIR)/bin/dial: | $(libs) +$(OUTDIR)/bin/dial: $(OUTDIR)/obj/bin/dial.o + $(BINARY) +bins: $(OUTDIR)/bin/dial +$(OUTDIR)/obj/bin/edit.o: bin/edit.c + $(OBJECT) +$(OUTDIR)/bin/edit: | $(libs) +$(OUTDIR)/bin/edit: $(OUTDIR)/obj/bin/edit.o + $(BINARY) +bins: $(OUTDIR)/bin/edit +$(OUTDIR)/obj/bin/init.o: bin/init.c + $(OBJECT) +$(OUTDIR)/bin/init: | $(libs) +$(OUTDIR)/bin/init: $(OUTDIR)/obj/bin/init.o + $(BINARY) +bins: $(OUTDIR)/bin/init +$(OUTDIR)/obj/bin/listen.o: bin/listen.c + $(OBJECT) +$(OUTDIR)/bin/listen: | $(libs) +$(OUTDIR)/bin/listen: $(OUTDIR)/obj/bin/listen.o + $(BINARY) +bins: $(OUTDIR)/bin/listen +$(OUTDIR)/obj/bin/mbusd.o: bin/mbusd.c + $(OBJECT) +$(OUTDIR)/bin/mbusd: | $(libs) +$(OUTDIR)/bin/mbusd: $(OUTDIR)/obj/bin/mbusd.o + $(BINARY) +bins: $(OUTDIR)/bin/mbusd +$(OUTDIR)/obj/bin/pick.o: bin/pick.c + $(OBJECT) +$(OUTDIR)/bin/pick: | $(libs) +$(OUTDIR)/bin/pick: $(OUTDIR)/obj/bin/pick.o + $(BINARY) +bins: $(OUTDIR)/bin/pick +$(OUTDIR)/obj/bin/screenlock.o: bin/screenlock.c + $(OBJECT) +$(OUTDIR)/bin/screenlock: | $(libs) +$(OUTDIR)/bin/screenlock: $(OUTDIR)/obj/bin/screenlock.o + $(BINARY) +bins: $(OUTDIR)/bin/screenlock +$(OUTDIR)/obj/bin/shell.o: bin/shell.c + $(OBJECT) +$(OUTDIR)/bin/shell: | $(libs) +$(OUTDIR)/bin/shell: $(OUTDIR)/obj/bin/shell.o + $(BINARY) +bins: $(OUTDIR)/bin/shell +$(OUTDIR)/obj/bin/winmgr/keys.o: bin/winmgr/keys.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/keys.o +-include $(OUTDIR)/obj/bin/winmgr/keys.d +$(OUTDIR)/obj/bin/winmgr/mons.o: bin/winmgr/mons.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/mons.o +-include $(OUTDIR)/obj/bin/winmgr/mons.d +$(OUTDIR)/obj/bin/winmgr/tile.o: bin/winmgr/tile.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/tile.o +-include $(OUTDIR)/obj/bin/winmgr/tile.d +$(OUTDIR)/obj/bin/winmgr/error.o: bin/winmgr/error.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/error.o +-include $(OUTDIR)/obj/bin/winmgr/error.d +$(OUTDIR)/obj/bin/winmgr/client.o: bin/winmgr/client.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/client.o +-include $(OUTDIR)/obj/bin/winmgr/client.d +$(OUTDIR)/obj/bin/winmgr/winmgr.o: bin/winmgr/winmgr.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/winmgr.o +-include $(OUTDIR)/obj/bin/winmgr/winmgr.d +$(OUTDIR)/obj/bin/winmgr/mouse.o: bin/winmgr/mouse.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/mouse.o +-include $(OUTDIR)/obj/bin/winmgr/mouse.d +$(OUTDIR)/obj/bin/winmgr/util.o: bin/winmgr/util.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/util.o +-include $(OUTDIR)/obj/bin/winmgr/util.d +$(OUTDIR)/obj/bin/winmgr/list.o: bin/winmgr/list.c config.mk + $(OBJECT) +$(OUTDIR)/bin/winmgr: $(OUTDIR)/obj/bin/winmgr/list.o +-include $(OUTDIR)/obj/bin/winmgr/list.d +$(OUTDIR)/bin/winmgr: | $(libs) + $(BINARY) +bins: $(OUTDIR)/bin/winmgr