Files
rosetta/services/herdd/main.c
T

136 lines
3.0 KiB
C

#include "log.h"
#include "queue.h"
#include "runlevel.h"
#include "service.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fx/ds/string.h>
#include <mango/log.h>
#include <mango/task.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/remote.h>
#include <sys/types.h>
#include <unistd.h>
#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;
}