diff options
author | turret <turret@duck.com> | 2024-03-30 16:04:45 -0500 |
---|---|---|
committer | turret <turret@duck.com> | 2024-03-30 16:04:45 -0500 |
commit | 80a67b7d20393a29aa5d2cb92197f3381be7fd96 (patch) | |
tree | f0c313da5ef509e79e5067972edd91976513ce0e /init/subsys.c | |
parent | f01745a2ee84f11b8cc54e37c5f7f596184ab785 (diff) | |
download | discord-bot-skeleton-80a67b7d20393a29aa5d2cb92197f3381be7fd96.tar.gz discord-bot-skeleton-80a67b7d20393a29aa5d2cb92197f3381be7fd96.tar.bz2 discord-bot-skeleton-80a67b7d20393a29aa5d2cb92197f3381be7fd96.zip |
*: directory changes
since this project is a skeleton and not meant to clutter up the code
that will actually consume the bot, i've opted to consolidate the
majority of files under a single directory and minimise extra files
*: move code to util/
*: move include files to include/dbs/
net: consolidate net functions into single file
config: remove config
Diffstat (limited to 'init/subsys.c')
-rw-r--r-- | init/subsys.c | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/init/subsys.c b/init/subsys.c deleted file mode 100644 index 704678f..0000000 --- a/init/subsys.c +++ /dev/null @@ -1,180 +0,0 @@ -#include <errno.h> -#include <sched.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/prctl.h> -#include <sys/syscall.h> -#include <sys/mman.h> -#include <unistd.h> - -#include <config.h> -#include <log.h> -#include <util.h> - -#define MAX_SUBSYSTEMS 32 -#define MAX_RESPAWN 3 - -struct subsystem_info { - char *fn_name; - int (*fn)(void); - int pid; - void *stack; - char mode; - int respawn_count; -}; - -extern long stack_size; -extern int mainpid; -static struct subsystem_info *subsystems[MAX_SUBSYSTEMS + 1]; -int subsystem_count = 0; - -static int __subsystem_entry(struct subsystem_info *info) -{ - /* entry point from clone(). we setup the process name so we know - what we are looking at from a glance in a ps view or htop or - whatever. */ - char *name = malloc(16 * sizeof(char)); - snprintf(name, 16, NAME_SHORTHAND ": %s", info->fn_name); - name[15] = '\0'; - prctl(PR_SET_NAME, name); - free(name); - - /* clear signal handlers so SIGTERM is no longer caught */ - static sigset_t set; - sigprocmask(SIG_SETMASK, &set, NULL); - - int ret = info->fn(); - - return ret; -} - -char *subsystem_get_name(int pid) -{ - for(int i = 0; i < MAX_SUBSYSTEMS; ++i) { - struct subsystem_info *subsystem = subsystems[i]; - if(!subsystem || subsystem->pid != pid) - continue; - - return subsystem->fn_name; - } - return 0; -} - -int subsystem_change_mode(int pid, char mode) -{ - for(int i = 0; i < MAX_SUBSYSTEMS; ++i) { - struct subsystem_info *subsystem = subsystems[i]; - if(!subsystem || subsystem->pid != pid) - continue; - - subsystem->mode = mode; - return 0; - } - - return 1; -} - -int subsystem_handle_term(int pid) -{ - for(int i = 0; i < MAX_SUBSYSTEMS; ++i) { - struct subsystem_info *subsystem = subsystems[i]; - if(!subsystem || subsystem->pid != pid) - continue; - - if(subsystem->mode == PANICMODE_RESPAWN - && subsystem->respawn_count < MAX_RESPAWN) { - ++(subsystem->respawn_count); - - int pid = clone((int (*)(void *))__subsystem_entry, - (void *)((long)(subsystem->stack) + stack_size), - CLONE_FILES | CLONE_VM | SIGCHLD, subsystem); - subsystem->pid = pid; - if(pid < 0) { - print(LOG_CRIT "subsys: cannot re-start subsystem %s: " - "clone failed (errno %d)", subsystem->fn_name, errno); - if(munmap(subsystem->stack, stack_size) < 0) - print(LOG_CRIT "subsys: failed to deallocate " - "stack for subsystem %s (%d) (errno %d)", - subsystem->fn_name, pid, errno); - free(subsystem); - return 0; - } - - subsystem->mode = 'o'; - return 0; - } else if(subsystem->mode == PANICMODE_RESPAWN) { - panic("subsys: exceeded maximum respawn count for subsystem " - "%s (%d)", subsystem->fn_name, subsystem->pid); - } - - if(munmap(subsystem->stack, stack_size) < 0) - print(LOG_CRIT "subsys: failed to deallocate stack " - "for subsystem %s (%d) (errno %d)", - subsystem->fn_name, pid, errno); - subsystems[i] = 0; - --subsystem_count; - free(subsystem); - - return 0; - } - - return 1; -} - -int __impl_start_subsystem(char *fn_name, int (*fn)(void)) -{ - if(getpid() != mainpid) { - print(LOG_CRIT "subsys: cannot perform subsystem inception " - "(attempted from %d)", getpid()); - return 1; - } - if(subsystem_count >= MAX_SUBSYSTEMS) { - print(LOG_CRIT "subsys: cannot start subsystem %s: " - "reached maximum number of subsystems", fn_name); - return 1; - } - - /* because CLONE_VM is being set, our stack is not duplicated and - therefore we need to map a stack */ - void *stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK | MAP_PRIVATE, -1, 0); - if((long)stack <= 0) { - print(LOG_CRIT "subsys: cannot start subsystem %s: " - "failed to allocate stack (errno %d)", fn_name, errno); - return 1; - } - - /* the libc gods have graced us with the ability to pass one (1) arg - to the function. struct required. the absence of a free is not a - memory leak because we free it above. */ - struct subsystem_info *info = malloc(sizeof(struct subsystem_info)); - info->fn_name = fn_name; - info->fn = fn; - info->stack = stack; - info->mode = 'o'; - info->respawn_count = 0; - - int pid = clone((int (*)(void *))__subsystem_entry, - (void *)((long)stack + stack_size), - CLONE_FILES | CLONE_VM | SIGCHLD, info); - info->pid = pid; - if(pid < 0) { - print(LOG_CRIT "subsys: cannot start subsystem %s: " - "clone failed (errno %d)", fn_name, errno); - munmap(stack, stack_size); - free(info); - return 1; - } - - for(int i = 0; i < MAX_SUBSYSTEMS; ++i) { - if(!subsystems[i]) { - subsystems[i] = info; - ++subsystem_count; - break; - } - } - - return 0; -} |