mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
103 lines
4.6 KiB
Text
103 lines
4.6 KiB
Text
CLIte Internals:
|
|
|
|
CLite's aim is not just to create a functional unix-like terminal in a
|
|
web page, but also to have that built on top of a unix-like operating
|
|
system written in javascript and which runs in a web page.
|
|
|
|
CLIte follows the common programming methodology of creating in three
|
|
steps:
|
|
|
|
First, make it work.
|
|
Second, make it work right.
|
|
Third, make it work well.
|
|
|
|
This means that some areas are still very much a work in progress, but
|
|
are gradually being improved.
|
|
|
|
At its core, CLIte is made up of the follow parts:
|
|
|
|
The Core:
|
|
Effectively CLIte's 'kernel', this consists of functions needed to do
|
|
basic tasks, such as loading files, loading scripts, safely running
|
|
code, downloading files, rebooting the system, and system initialisation.
|
|
Most of this is either abstracted away to higher level functions, or
|
|
otherwise need never be used by user-level programs.
|
|
|
|
The Terminal:
|
|
The terminal handles user input, and displays program output. Most of
|
|
which is abstracted away to standard io calls on /dev/tty, and even
|
|
further abstracted to standard io calls on the standard input, output,
|
|
and error filedescriptors that every program has. Additionally the
|
|
term library offers some advanced functionality which is subject to
|
|
change.
|
|
|
|
The VFS: (Virtual File Sytem)
|
|
CLIte's virtual file system bares no relation to the file system of the
|
|
server it is run on (thus /etc/passwd is not the server's /etc/passwd
|
|
file!).
|
|
During system initialisation, the root filesystem is mounted by creating
|
|
the VFS, with physical server-side files then mapped into the VFS using
|
|
a plain-text config file which is stored in /dev/wfs (web file system,
|
|
for lack of a better name). The content of files are then loaded in as
|
|
needed when the VFS file is accessed.
|
|
However other files in the VFS are created dynamically as needed during
|
|
system initialisation. For instance, commands are loaded in directly
|
|
from javascript functions, which creates both the executable file in
|
|
/bin/<name> as well as the source file in /usr/src/<name>.js. Thus two
|
|
VFS files are created from each command, with many commands being held
|
|
in a single server-side file. Libraries are loaded in similarly, to
|
|
both /lib/<name>.so and /usr/src/libs/<name>.js
|
|
Additionally, configuration files in /etc, and various default devices
|
|
in /dev are also created programatically. As is the system log file
|
|
in /var/logs.
|
|
Most VFS functions are abstracted away to stdio functions.
|
|
|
|
The Process Manager:
|
|
CLIte's process manager keeps track of running programs as processes and
|
|
process groups, in a typical unix-like manner. It also wraps each
|
|
process in its own try/catch block to ensure errors are handled
|
|
correctly, and that failed processes aren't left 'hanging'.
|
|
It also manages callbacks for functions such as wait() so that processes
|
|
can monitor and act upon each other as needed.
|
|
|
|
The User Manager:
|
|
The user manager controls the user logins, and dynamically generates a
|
|
guest session as needed.
|
|
|
|
The Logger:
|
|
The Logger manages the system logs, printing them to the terminal during
|
|
system initialisation and shutdown, as well as writing them to the
|
|
system log at /var/logs
|
|
|
|
The Lifecycle of a Process:
|
|
|
|
1. fork() is called with the environment and io data passed to it.
|
|
This adds a new process to the process manager, which assigns it
|
|
a process id (pid) and also creates a file in /proc/<pid> for
|
|
storing data about the process.
|
|
Both the environment and io data are then cloned, and the new
|
|
process is called asynchronously, forking it from the current
|
|
process.
|
|
The process id of the new process is returned to the parent.
|
|
2. exec() is called, again the environment and io data is passed to it,
|
|
along with the file path and arguments for a new program.
|
|
This checks the file both exists and is executable by the current
|
|
user.
|
|
Then updated details of the program are sent to the process manager.
|
|
The current program is then overwritten with a call to the new
|
|
program.
|
|
3. The program then runs as intended, and exits normally, or fails and
|
|
is caught by a try/catch which exits the program.
|
|
4. exit() is called with an integer 'exit state':
|
|
zero for no error.
|
|
less than zero for internal error
|
|
greater than zero for the program's own use
|
|
This ends the program, and notifies the process manager that the
|
|
process has exit.
|
|
The process manager will then remove the process from the process
|
|
list, delete the process' data file in /proc/<pid>, then handle
|
|
any wait() calls that have been queued for the process exit.
|
|
|
|
Typically, this is when the shell's waitpid() on the process causes the
|
|
shell to once again show a prompt, awaiting the user's next command
|
|
input.
|