#include "log.h" #include "queue.h" #include "runlevel.h" #include "service.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef TRACE #define tracef(...) printf(__VA_ARGS__) #else #define tracef(...) #endif static void *thread_func(void *arg) { tracef("started thread with arg %p\n", arg); errno = 100; tracef("thread done"); return (void *)0xdeadbeef; } static int load_services(const char *dir, struct queue *out) { DIR *d = opendir(dir); if (!d) { printf("cannot open '%s': %s\n", dir, strerror(errno)); return -1; } struct dirent *dent = NULL; while ((dent = readdir(d))) { char filepath[4096]; snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name); tracef(" - %s\n", dent->d_name); struct service *s = NULL; int err = service_load(filepath, &s); if (err != SUCCESS) { printf("failed to load %s (%s)\n", filepath, strerror(errno)); } else { queue_push_back(out, &s->s_entry); } } closedir(d); return SUCCESS; } static int load_runlevels(const char *dir, struct queue *out) { DIR *d = opendir(dir); if (!d) { printf("cannot open '%s': %s\n", dir, strerror(errno)); return -1; } struct dirent *dent = NULL; while ((dent = readdir(d))) { char filepath[4096]; snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name); tracef(" - %s\n", dent->d_name); struct runlevel *rl = NULL; int err = runlevel_load(filepath, &rl); if (err != SUCCESS) { printf("failed to load %s (%s)\n", filepath, strerror(errno)); continue; } tracef("runlevel: %s\n", rl->rl_description); for (size_t i = 0; i < rl->rl_requires_count; i++) { tracef(" requires: %s\n", rl->rl_requires[i]); } queue_push_back(out, &rl->rl_entry); } closedir(d); return SUCCESS; } int main(int argc, const char *argv[], const char *envp[]) { sys_remote_set(SYS_REMOTE_NSD, 0, 0); struct queue *runlevels = global_runlevels(); struct queue *services = global_services(); int err = load_runlevels("/etc/herdd/runlevels", runlevels); err = load_services("/etc/herdd/services", services); struct runlevel *rl = runlevel_find("single-user"); if (!rl) { log_fail("Cannot find runlevel single-user."); return -1; } runlevel_activate(rl); kern_handle_t new_task = 123, new_space = 456; kern_status_t status = task_duplicate(&new_task, &new_space); kern_logf( " task_duplicate returned %d (%x/%x)", status, new_task, new_space); if (new_task == KERN_HANDLE_INVALID) { kern_log("this is the child"); long r = printf("hello\n"); kern_logf("printf returned %ld (%d)", r, (errno)); } else { kern_log("this is the parent"); long r = printf("goodbye\n"); kern_logf("printf returned %ld (%d)", r, (errno)); } kern_logf("exiting (%s)", strerror(EFTYPE)); return 0; }