Cleanup init
This commit is contained in:
parent
64ae8d07bd
commit
2d231a97af
82
apps/init.c
82
apps/init.c
@ -1,3 +1,35 @@
|
||||
/* vim: ts=4 sw=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2018 K. Lange
|
||||
*
|
||||
* init - First process.
|
||||
*
|
||||
* `init` calls startup scripts and then waits for them to complete.
|
||||
* It also waits for orphaned proceses so they can be collected.
|
||||
*
|
||||
* `init` itself is statically-linked, so minimizing libc dependencies
|
||||
* is worthwhile as it reduces to the total size of init itself, which
|
||||
* remains in memory throughout the entire lifetime of the OS.
|
||||
*
|
||||
* Startup scripts for init are stored in /etc/startup.d and are run
|
||||
* in sorted alphabetical order. It is generally recommended that these
|
||||
* startup scripts be named with numbers at the front to ensure easy
|
||||
* ordering. This system of running a set of scripts on startup is
|
||||
* somewhat similar to how sysvinit worked, but no claims of
|
||||
* compatibility are made.
|
||||
*
|
||||
* Startup scripts can be any executable binary. Shell scripts are
|
||||
* generally used to allow easy editing, but you could also use
|
||||
* a binary (even a dynamically linked one) as a startup script.
|
||||
* `init` will wait for each startup script (that is, it will wait for
|
||||
* the original process it started to exit) before running the next one.
|
||||
* So if you wish to run daemons, be sure to fork them off and then
|
||||
* exit so that the rest of the startup process can continue.
|
||||
*
|
||||
* When the last startup script finishes, `init` will reboot the system.
|
||||
*/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@ -10,43 +42,56 @@
|
||||
|
||||
#define INITD_PATH "/etc/startup.d"
|
||||
|
||||
/* Initialize fd 0, 1, 2 */
|
||||
void set_console(void) {
|
||||
/* default to /dev/ttyS0 (serial COM1) */
|
||||
int _stdin = syscall_open("/dev/ttyS0", 0, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
(void)_stderr;
|
||||
(void)_stdin;
|
||||
if (_stdin < 0) {
|
||||
/* if /dev/ttyS0 failed to open, fall back to /dev/null */
|
||||
syscall_open("/dev/null", 0, 0);
|
||||
syscall_open("/dev/null", 1, 0);
|
||||
syscall_open("/dev/null", 1, 0);
|
||||
} else {
|
||||
/* otherwise also use /dev/ttyS0 for stdout, stderr */
|
||||
syscall_open("/dev/ttyS0", 1, 0);
|
||||
syscall_open("/dev/ttyS0", 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Run a startup script and wait for it to finish */
|
||||
int start_options(char * args[]) {
|
||||
|
||||
/* Fork child to run script */
|
||||
int cpid = syscall_fork();
|
||||
|
||||
/* Child process... */
|
||||
if (!cpid) {
|
||||
char * _envp[] = {
|
||||
"LD_LIBRARY_PATH=/lib:/usr/lib",
|
||||
"PATH=/bin:/usr/bin",
|
||||
"USER=root",
|
||||
"HOME=/home/root",
|
||||
NULL,
|
||||
};
|
||||
syscall_execve(args[0], args, _envp);
|
||||
/* Pass environment from init to child */
|
||||
syscall_execve(args[0], args, environ);
|
||||
/* exec failed, exit this subprocess */
|
||||
syscall_exit(0);
|
||||
}
|
||||
|
||||
/* Wait for the child process to finish */
|
||||
int pid = 0;
|
||||
do {
|
||||
/*
|
||||
* Wait, ignoring kernel threads
|
||||
* (which also end up as children to init)
|
||||
*/
|
||||
pid = waitpid(-1, NULL, WNOKERN);
|
||||
|
||||
if (pid == -1 && errno == ECHILD) {
|
||||
/* There are no more children */
|
||||
break;
|
||||
}
|
||||
|
||||
if (pid == cpid) {
|
||||
/* The child process finished */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Continue while no error (or error was "interrupted") */
|
||||
} while ((pid > 0) || (pid == -1 && errno == EINTR));
|
||||
|
||||
return cpid;
|
||||
@ -95,6 +140,7 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Self-explanatory */
|
||||
syscall_reboot();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user