toaruos/apps/init.c

101 lines
2.2 KiB
C
Raw Normal View History

2018-08-12 10:36:56 +03:00
#include <dirent.h>
2018-02-25 08:13:54 +03:00
#include <errno.h>
2018-08-12 10:36:56 +03:00
#include <stdio.h>
#include <stdlib.h>
2018-03-04 16:50:53 +03:00
#include <string.h>
2018-08-12 10:36:56 +03:00
#include <syscall.h>
2018-08-01 21:40:43 +03:00
#include <unistd.h>
2018-08-12 10:36:56 +03:00
#include <wait.h>
#include <sys/wait.h>
#define INITD_PATH "/etc/startup.d"
2018-02-25 08:13:54 +03:00
2018-08-01 21:40:43 +03:00
void set_console(void) {
int _stdin = syscall_open("/dev/ttyS0", 0, 0);
2018-02-25 08:13:54 +03:00
int _stdout = syscall_open("/dev/ttyS0", 1, 0);
int _stderr = syscall_open("/dev/ttyS0", 1, 0);
if (_stdout < 0) {
_stdout = syscall_open("/dev/null", 1, 0);
_stderr = syscall_open("/dev/null", 1, 0);
}
2018-04-25 08:03:29 +03:00
(void)_stderr;
(void)_stdin;
2018-02-25 08:13:54 +03:00
}
int start_options(char * args[]) {
int cpid = syscall_fork();
if (!cpid) {
2018-02-25 08:13:54 +03:00
char * _envp[] = {
2018-06-25 10:46:13 +03:00
"LD_LIBRARY_PATH=/lib:/usr/lib",
"PATH=/bin:/usr/bin",
2018-02-25 08:13:54 +03:00
"USER=root",
"HOME=/home/root",
2018-02-25 08:13:54 +03:00
NULL,
};
2018-04-25 08:03:29 +03:00
syscall_execve(args[0], args, _envp);
2018-02-25 08:13:54 +03:00
syscall_exit(0);
}
2018-08-12 10:36:56 +03:00
int pid = 0;
do {
pid = waitpid(-1, NULL, WNOKERN);
if (pid == -1 && errno == ECHILD) {
break;
}
if (pid == cpid) {
break;
}
} while ((pid > 0) || (pid == -1 && errno == EINTR));
2018-08-12 10:36:56 +03:00
return cpid;
2018-02-25 08:13:54 +03:00
}
int main(int argc, char * argv[]) {
2018-08-12 10:36:56 +03:00
/* Initialize stdin/out/err */
2018-02-25 08:13:54 +03:00
set_console();
2018-03-04 16:50:53 +03:00
/* Get directory listing for /etc/startup.d */
2018-08-12 10:36:56 +03:00
int initd_dir = syscall_open(INITD_PATH, 0, 0);
if (initd_dir < 0) {
/* No init scripts; try to start getty as a fallback */
start_options((char *[]){"/bin/getty",NULL});
} else {
int count = 0, i = 0, ret = 0;
/* Figure out how many entries we have with a dry run */
do {
struct dirent ent;
ret = syscall_readdir(initd_dir, ++count, &ent);
} while (ret > 0);
/* Read each directory entry */
struct dirent entries[count];
do {
syscall_readdir(initd_dir, i, &entries[i]);
i++;
} while (i < count);
/* Sort the directory entries */
int comparator(const void * c1, const void * c2) {
const struct dirent * d1 = c1;
const struct dirent * d2 = c2;
return strcmp(d1->d_name, d2->d_name);
}
qsort(entries, count, sizeof(struct dirent), comparator);
/* Run scripts */
for (int i = 0; i < count; ++i) {
if (entries[i].d_name[0] != '.') {
char path[256];
sprintf(path, "/etc/startup.d/%s", entries[i].d_name);
2018-08-12 10:36:56 +03:00
start_options((char *[]){path, NULL});
}
2018-03-04 16:50:53 +03:00
}
}
2018-08-12 10:36:56 +03:00
syscall_reboot();
return 0;
2018-02-25 08:13:54 +03:00
}