aboutsummaryrefslogtreecommitdiffstats
path: root/init/subsys.c
diff options
context:
space:
mode:
authorturret <turret@duck.com>2024-03-30 16:04:45 -0500
committerturret <turret@duck.com>2024-03-30 16:04:45 -0500
commit80a67b7d20393a29aa5d2cb92197f3381be7fd96 (patch)
treef0c313da5ef509e79e5067972edd91976513ce0e /init/subsys.c
parentf01745a2ee84f11b8cc54e37c5f7f596184ab785 (diff)
downloaddiscord-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.c180
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;
-}