update documents and bump version

This commit is contained in:
Lisa Milne 2023-11-27 20:37:45 +10:00
parent 1f2c8d85f3
commit dc048f20cc
6 changed files with 558 additions and 444 deletions

View file

@ -1,6 +1,6 @@
var clite = {
state:{
version:'0.2-2',
version:'0.2-3',
isinit:false
},
core:{
@ -1318,6 +1318,7 @@ clite.vfs = {
vfsdata.api.mkDir('/usr/clite/web');
vfsdata.api.mkDir('/usr/home');
vfsdata.api.mkDir('/usr/share');
vfsdata.api.mkDir('/usr/share/docs');
vfsdata.api.mkDir('/usr/share/site');
vfsdata.api.mkDir('/usr/src');
vfsdata.api.mkDir('/usr/src/libs');

View file

@ -14,4 +14,7 @@ clite/core.css:/usr/clite/web/core.css:0:0:-rw-r-----
data/intro.txt:/usr/share/introduction:0:0:-rw-rw-r--
data/about.txt:/usr/share/site/about:0:0:-rw-rw-r--
data/lipsum.txt:/usr/share/site/lipsum:0:0:-rw-rw-r--
readme.txt:/usr/clite/readme.txt:0:0:-rw-r--r--
readme.txt:/usr/share/docs/readme.txt:0:0:-rw-r--r--
readme-libs.txt:/usr/share/docs/readme-libs.txt:0:0:-rw-r--r--
readme-programs.txt:/usr/share/docs/readme-programs.txt:0:0:-rw-r--r--
readme-internals.txt:/usr/share/docs/readme-internals.txt:0:0:-rw-r--r--

103
readme-internals.txt Normal file
View file

@ -0,0 +1,103 @@
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.

323
readme-libs.txt Normal file
View file

@ -0,0 +1,323 @@
CLIte libraries:
System libraries may be loaded into a program for use of their API using the
io.include() function:
var stdio = io.include('stdio');
This returns a reference to the library which can be stored in a variable as
seen above. Calls to library functions can then be made using that reference:
stdio.open('/path/to/file');
There is no need to name the variable the same as the library name, however
this is considered good practice.
A library's 'header' name, as used in include() is not the same as its
file name /lib/lib*.so. For instance for the standard io library, you
would include 'stdio' but the filename is libio.so
The libraries, and their API functions are listed below:
stdlib (libstd.so): io.include('stdlib')
Provides a growing standard unix-like library.
basename('path')
returns the base name of a file path:
'/usr/home/guest/file.txt' -> 'file.txt'
dirname('path')
returns the directory name of a file path:
'/usr/home/guest/file.txt' -> '/usr/home/guest'
uname()
returns an object containing system information:
{
sysname:'CLIte', // system name, always 'CLIte'
nodename:'localhost', // network hostname
release:'0.1...', // contains the current CLIte version as stored in clite.state.version
version:'0.1...', // same as release
machine:navigator.userAgent // contains the browser user agent string
}
nodename is either the website domain, or 'localhost' if loaded
without a webserver. This allows programs to test if the system
is running locally or not (example is `cat -l' which does not
print unloaded files if running without a webserver).
fork(env,io,call)
Creates a new process, with environment and io data passed to it.
Returns the pid of the new process, or 0 on failure.
call should be a function that accepts the env and io as
arguments, this is where the new process begins.
function newProc(env,io) {
io.write('this is a new process!');
io.exit(0);
}
var pid = fork(env,io,newProc);
exec(path,args,env,io)
Executes a new program, replacing the current one.
Returns 0 on success, non-zero on failure.
Unlike typical unix exec(), this always returns. On success the
original program should do nothing more, including not exiting.
path is the fully resolved file path of the program to be
executed, such as '/bin/ls'.
args is the argument array created by passing a command line to
strToArgs, see above.
env and io, are the current environment and io data.
var command = "ls -l";
var args = stdlib.strToArgs(command);
var path = stdlib.resolvePath(args[0],'/bin');
var r = stdlib.exec(path,args,env,io);
if (r == 0)
return;
wait(cb)
Calls cb(pid) once any child of the current process has exited.
Calls immediately if the are no child processes.
Returns false on error.
waitpid(pid,cb)
Calls cb(pid) when the process with id pid has exited. Calls
immediately if the process does not exist.
If pid is less than 0, functions like wait(cb)
Returns false on error.
waitall(cb)
Calls cb(pid) once all child processes of the current process
group have exited. Calls immediately if the are no child processes.
Returns false on error.
getuid()
Returns the numeric user id of the current user.
getgid()
Returns teh numeric group id of the current user.
clite (libclite.so): io.include('clite')
Provides provides special functions used in CLIte.
resolvePath('path','base')
Resolves a relative path to a full path, using the present
working directory or 'base':
clite.resolvePath('file.txt') -> '/usr/home/guest/file.txt'
clite.resolvePath('file.txt','/etc') -> '/etc/file.txt'
clite.resolvePath('~/../file.txt') -> '/usr/home/file.txt'
strToArgs('string')
Splits a string into an array of arguments for passing to
exec(), supports quotes and so on:
clite.strToArgs('ls -l /var') -> ['ls','-l','var']
stdio (libio.so): io.include('stdio')
Provides access to io functions and types for file access
stdio.types:
object for mapping values of stat.type:
FT_UNKOWN: 0 Unknown file type
FT_TEXT: 1 Plain text file
FT_BINARY: 2 Binary file, likely a javascript function
FT_DIR: 3 Directory
FT_LINK: 4 Symbolic link
FT_DEV: 5 Device
FT_REMOTE: 6 Unloaded remote data (will change after loading)
FT_SCRIPT: 7 Plain text file beginning with #!
FT_IMAGE: 8 Image file, specifically a javascript Image object
creat('path','-')
creates a new file at path
returns true on success
open('path',callback,open_link)
Open the file at path, returns a file descriptor.
On error returns null, and calls callback(null) if set.
If callback is set, will call the function at callback with the
file descriptor, this allows remote data to be loaded for the
file before beginning read or write operations.
If callback is false, open will return directly, without loading
remote data.
If open_link is set and true, and 'path' is a symbolic link, the
returned file descriptor is for the link, not the file pointed to.
var fd = stdio.open('path',false); // opens the file without loading data
var fd = stdio.open('path',callback); // calls callback(fd) when data is loaded
var fd = stdio.open('path',callback,true); // as above, but will not follow a link
var fd = stdio.open('path'); // as a general rule, don't do this
close(fd)
Closes a file opened with open()
stdio.close(fd);
read(fd,callback)
Reads a single character or keystroke from a file.
callback is an optional callback function, used soley for
asynchronously reading from a tty.
Returns null if there is no data to read.
When reading from a regular file, will return a single character.
When reading from a tty:
Returns true on success or false on failure.
Calls callback() and passes as an argument either:
A full line of text as entered by the user.
\1 (start of header) followed by a special key
name (such as ArrowUp).
null if the tty cannot be read from.
var c = stdio.read(fd);
readLine(fd,callback)
Reads a line from a file, up to the next newline, or end of file.
Returns null if there is no data to read.
When reading from a tty, functions the same as read().
var line = stdio.readLine(fd);
readAll(fd)
Returns the entire content of a file.
Returns null if there is no data to read.
Works only on regular files (and some non-tty devices).
var data = stdio.readAll(fd);
write(fd,data)
Write data to a file.
Returns true on success.
if (stdio.write(fd,'string')) {
// it worked
}else{
// it failed
}
ftruncate(fd,length)
truncate('path',length)
Truncates a file's size to no more than length.
Does not increase a file's size to length.
Returns true on success.
var result = stdio.ftruncate(fd,10);
var result = stdio.truncate('/usr/home/guest/file.txt',10);
seek(fd,pos)
Moves the read/write position of an open file to pos.
If pos is less than 0, then returns the current position without
changing, otherwise returns the new position.
pos is always relative to the start of the file. When a file is
first opened, pos will be set to the start of the file.
To set the position to the end of a file, first get the file size
using stat() or fstat().
var p = stdio.seek(fd,10);
remove('path')
Deletes a file or directory.
Returns true on success.
To delete a directory, the directory must be empty.
if (stdio.remove('/usr/home/guest/file.txt'))
// success!
link('path','target')
Creates a new symbolic link at 'path' which points to 'target'.
'target' must exist.
If 'path' exists, and is already a link, will update the link.
Returns true on success.
if (stdio.link('/usr/home/guest/logfile','/vr/logs'))
// success!
stat('path')
fstat(fd)
Returns a stat object with infomation about a file.
Returns null on error.
Editing the returned object does not change anything for the
actual file, it just means your stat object is now wrong.
var st = stdio.stat('/usr/home/guest/file.txt');
var st = stdio.fstat(fd);
Stat object contents:
st.name: string containing the file name
st.type: file type identifier, see stdio.types above for more info
st.uid: numeric id of the file owner
st.gid: numeric id of the file group
st.size: file size, or 0 for non text files
st.perms: the permissions string for the file, see chmod below.
chmod('path','mode')
fchmod(fd,'mode')
Change a file's mode (permissions).
Returns true on success.
The mode string is a 9 or 10 character string describing the
file permissions. The optional first character describes the
file type, and cannot be changed. Attempting to change the first
character will not cause the function to fail, but only the
permissions will be changed.
10 character string: -rwxrwxrwx
9 character string: rwxrwxrwx
After the option first character, the mode string is comprised of
3 sets of permissions for Read, Write, and eXecute, one each for
the user, group, and others.
rwx permissions for the file's owner
rwx permissions for users in the file's group
rwx permissions for other users
Replacing any of the permissions with a dash '-' will remove that
permission from that set:
rwxr-xr--
The user has all permissions, the group has read and execute
permissions, others have only read permissions.
isattty(fd)
returns true if fd refers to a tty.
fprintf(fd,format,args)
Print formatted text to the file at fd.
Actually formatting is a work in progress, ignore the args.
Returns true on success.
printf(fmt,args)
Equivalent to fprintf(io.stdout,fmt,args);
term (libterm.so): io.include('term')
Provides access to raw terminal and tty functions.
clear()
Clears the current terminal, equivalent to running `clear' from
the shell.
opentty()
Creates a new blank terminal (tty) with raw key events, for
custom displays and interactions. (The less command uses this).
Returns a reference object for interacting with the new tty.
Returns null on error.
var tty = term.opentty();
closetty(tty)
Closes a tty created with opentty().
ttyctrl(func,v)
Special function for setting and accessing CLIte-specific tty
data. Specifically for interacting directly with the form used
for user data input.
func is a string containing the intended function.
v is the value to set.
Returns either the requested data, or false on error.
term.ttyctrl('iset',string); // sets the current input value
var txt = term.ttyctrl('iget'); // gets the current input value
term.ttyctrl('prompt',string); // sets the current prompt text

123
readme-programs.txt Normal file
View file

@ -0,0 +1,123 @@
CLIte command details and API:
Commands are mostly contained in clite/commands.js and are loaded in
at runtime. Each command looks something like:
clite.commands.load('name',function(args,env,io) {
io.write("Hello World!");
return 0;
}
The load function is only available during boot time, and will:
1. load the program into the vfs at /bin/name
2. load the source of the program into the vfs at /usr/src/name.js
The function in the second argument is roughly equivalent to main() in C.
This function takes 3 arguments:
'args' is equivalent to argv in C, being an array of strings containing
the command line arguments, args[0] is the command itself, args.length
is equivalent to argc in C.
'env' contains the current environment variables: env.PWD contains the
present working directory, and so on.
'io' contains file descriptors for accessing standard input, output,
and error, as well as a method for loading in libraries:
io.stdout
file descriptor for standard output
io.stderr
file descriptor for standard error
io.stdin
file descriptor for standard input
Note that writing to stdout or stderr, when it is a tty, will
currently always print that output as a line, with a newline
appended. This may change in the future.
io.exit(value) exits the program, equivalent to the C exit() function.
A program can also be exited by returning a non-null value from the 'main'
function.
io.include('name') loads a library into the current scope for use. See
the libs readme file for more details.
Example Programs:
Due to the nature of javascript, it is not possible to simply stop half
way through a function to wait for user input or for some remote data
to load. Instead we have to use a callback function, which complicates
things a little, and means there are two kinds of programs: Synchronous,
and Asynchronous.
Synchronous Program:
A Synchronous program runs and then exits, with no waiting for callbacks.
As such, it looks much like a regular unix program might, and simply
returns with an exit code.
Here's a "Hello World" as an example:
clite.commands.load('hello',function(args,env,io) {
io.write("Hello World!");
return 0;
}
Asynchronous Program:
An Asynchronous program typically uses io calls to interact with data
that may not be immediately available; such as remotely loading file
data or reading input from a user. As such callbacks are needed to
handle that data once it is available.
Therefore a return null is used, which lets the system know it is an
asyncronous program that will exit later using the io.exit() function.
Here's a simple program that reads in a file, and prints it to stdout:
clite.commands.load('show',function(args,env,io) {
var stdlib = io.include('stdlib');
var stdio = io.include('stdio');
// check there's a file to read from
if (args.length != 2) {
io.error('Specify a file to read');
return 1; // not asyncronous yet, so just return
}
// take the argument, and get it's full path
var file = stdlib.resolvePath(args[1]);
// file callback function that will receive the file descriptor
// once the file has data in it
function fcb(fd) {
if (!fd) {
// print an error, exit the program, then end
io.error('could not open file');
io.exit(1);
return;
}
// read in the whole file in one go
var data = stdio.readAll(fd);
// close the file
stdio.close(fd);
// check there's something there
if (!data) {
// print an error, exit the program, then end
io.error('could not read file');
io.exit(1);
return;
}
// write to stdout
io.write(data);
// and exit successfully
io.exit(0);
}
// open the file, and set the callback
var fd = stdio.open(file,fcb);
// we don't want to exit the program yet,
// so return null to let the system know that the
// program is asyncronous (reads user data, or loads remote data)
return null;
}

View file

@ -71,445 +71,6 @@ export - without arguments: will print all environment variables and their
- with argument: allows an environment variable to be changed or
created. `export FOO=bar'
Command details and API:
Commands are currently all contained in clite/commands.js and are loaded in
at runtime. Each command looks something like:
clite.commands.load('name',function(args,env,io) {
io.write("Hello World!");
return 0;
}
The load function is only available during boot time, and will:
1. load the program into the vfs at /bin/name
2. load the source of the program into the vfs at /usr/src/name.js
The function in the second argument is roughly equivalent to main() in C.
This function takes 3 arguments:
'args' is equivalent to argv in C, being an array of strings containing
the command line arguments, args[0] is the command itself, args.length
is equivalent to argc in C.
'env' contains the current environment variables: env.PWD contains the
present working directory, and so on.
'io' contains file descriptors for accessing standard input, output,
and error, as well as a method for loading in libraries:
io.stdout
file descriptor for standard output
io.stderr
file descriptor for standard error
io.stdin
file descriptor for standard input
Note that writting to stdout or stderr, when it is a tty, will
currently always print that output as a line, with a newline
appended. This may change in the future.
io.exit(value) exits the program, equivalent to the C exit() function.
A program can also be exited by returning a non-null value from the 'main'
function.
io.include('name') loads a library into the current scope for use. See
below for more details.
Libraries:
System libraries may be loaded into a program for use of their API using the
io.include() function:
var stdio = io.include('stdio');
This returns a reference to the library which can be stored in a variable as
seen above. Calls to library functions can then be made using that reference:
stdio.open('/path/to/file');
There is no need to name the variable the same as the library name, however
this is considered good practice.
The libraries, and their API functions are listed below:
stdlib: io.include('stdlib')
Provides a growing standard unix-like library.
basename('path')
returns the base name of a file path:
'/usr/home/guest/file.txt' -> 'file.txt'
dirname('path')
returns the directory name of a file path:
'/usr/home/guest/file.txt' -> '/usr/home/guest'
resolvePath('path','base')
special function that resolves a relative path to a full path,
using the present working directory or 'base':
resolvePath('file.txt') -> '/usr/home/guest/file.txt'
resolvePath('file.txt','/etc') -> '/etc/file.txt'
resolvePath('~/../file.txt') -> '/usr/home/file.txt'
strToArgs('string')
special function that splits a string into an array of arguments
for passing to exec(), supports quotes and so on:
'ls -l /var' -> ['ls','-l','var']
uname()
returns an object containing system information:
{
sysname:'CLIte', // system name, always 'CLIte'
nodename:'localhost', // network hostname
release:'0.1...', // contains the current CLIte version as stored in clite.state.version
version:'0.1...', // same as release
machine:navigator.userAgent // contains the browser user agent string
}
nodename is either the website domain, or 'localhost' if loaded
without a webserver. This allows programs to test if the system
is running locally or not (example is `cat -l' which does not
print unloaded files if running without a webserver).
fork(env,io,call)
Creates a new process, with environment and io data passed to it.
Returns the pid of the new process, or 0 on failure.
call should be a function that accepts the env and io as
arguments, this is where the new process begins.
function newProc(env,io) {
io.write('this is a new process!');
io.exit(0);
}
var pid = fork(env,io,newProc);
exec(path,args,env,io)
Executes a new program, replacing the current one.
Returns 0 on success, non-zero on failure.
Unlike typical unix exec(), this always returns. On success the
original program should do nothing more, including not exiting.
path is the fully resolved file path of the program to be
executed, such as '/bin/ls'.
args is the argument array created by passing a command line to
strToArgs, see above.
env and io, are the current environment and io data.
var command = "ls -l";
var args = stdlib.strToArgs(command);
var path = stdlib.resolvePath(args[0],'/bin');
var r = stdlib.exec(path,args,env,io);
if (r == 0)
return;
wait(cb)
Calls cb(pid) once any child of the current process has exited.
Calls immediately if the are no child processes.
Returns false on error.
waitpid(pid,cb)
Calls cb(pid) when the process with id pid has exited. Calls
immediately if the process does not exist.
If pid is less than 0, functions like wait(cb)
Returns false on error.
waitall(cb)
Calls cb(pid) once all child processes of the current process
group have exited. Calls immediately if the are no child processes.
Returns false on error.
getuid()
Returns the numeric user id of the current user.
getgid()
Returns teh numeric group id of the current user.
stdio: io.include('stdio')
Provides access to io functions and types for file access
stdio.types:
object for mapping values of stat.type:
FT_UNKOWN: 0 Unknown file type
FT_TEXT: 1 Plain text file
FT_BINARY: 2 Binary file, likely a javascript function
FT_DIR: 3 Directory
FT_LINK: 4 Symbolic link
FT_DEV: 5 Device
FT_REMOTE: 6 Unloaded remote data (will change after loading)
FT_SCRIPT: 7 Plain text file beginning with #!
FT_IMAGE: 8 Image file, specifically a javascript Image object
creat('path','-')
creates a new file at path
returns true on success
open('path',callback,open_link)
Open the file at path, returns a file descriptor.
On error returns null, and calls callback(null) if set.
If callback is set, will call the function at callback with the
file descriptor, this allows remote data to be loaded for the
file before beginning read or write operations.
If callback is false, open will return directly, without loading
remote data.
If open_link is set and true, and 'path' is a symbolic link, the
returned file descriptor is for the link, not the file pointed to.
var fd = stdio.open('path',false); // opens the file without loading data
var fd = stdio.open('path',callback); // calls callback(fd) when data is loaded
var fd = stdio.open('path',callback,true); // as above, but will not follow a link
var fd = stdio.open('path'); // as a general rule, don't do this
close(fd)
Closes a file opened with open()
stdio.close(fd);
read(fd,callback)
Reads a single character or keystroke from a file.
callback is an optional callback function, used soley for
asynchronously reading from a tty.
Returns null if there is no data to read.
When reading from a regular file, will return a single character.
When reading from a tty:
Returns true on success or false on failure.
Calls callback() and passes as an argument either:
A full line of text as entered by the user.
\1 (start of header) followed by a special key
name (such as ArrowUp).
null if the tty cannot be read from.
var c = stdio.read(fd);
readLine(fd,callback)
Reads a line from a file, up to the next newline, or end of file.
Returns null if there is no data to read.
When reading from a tty, functions the same as read().
var line = stdio.readLine(fd);
readAll(fd)
Returns the entire content of a file.
Returns null if there is no data to read.
Works only on regular files (and some non-tty devices).
var data = stdio.readAll(fd);
write(fd,data)
Write data to a file.
Returns true on success.
if (stdio.write(fd,'string')) {
// it worked
}else{
// it failed
}
ftruncate(fd,length)
truncate('path',length)
Truncates a file's size to no more than length.
Does not increase a file's size to length.
Returns true on success.
var result = stdio.ftruncate(fd,10);
var result = stdio.truncate('/usr/home/guest/file.txt',10);
seek(fd,pos)
Moves the read/write position of an open file to pos.
If pos is less than 0, then returns the current position without
changing, otherwise returns the new position.
pos is always relative to the start of the file. When a file is
first opened, pos will be set to the start of the file.
To set the position to the end of a file, first get the file size
using stat() or fstat().
var p = stdio.seek(fd,10);
remove('path')
Deletes a file or directory.
Returns true on success.
To delete a directory, the directory must be empty.
if (stdio.remove('/usr/home/guest/file.txt'))
// success!
link('path','target')
Creates a new symbolic link at 'path' which points to 'target'.
'target' must exist.
If 'path' exists, and is already a link, will update the link.
Returns true on success.
if (stdio.link('/usr/home/guest/logfile','/vr/logs'))
// success!
stat('path')
fstat(fd)
Returns a stat object with infomation about a file.
Returns null on error.
Editing the returned object does not change anything for the
actual file, it just means your stat object is now wrong.
var st = stdio.stat('/usr/home/guest/file.txt');
var st = stdio.fstat(fd);
Stat object contents:
st.name: string containing the file name
st.type: file type identifier, see stdio.types above for more info
st.uid: numeric id of the file owner
st.gid: numeric id of the file group
st.size: file size, or 0 for non text files
st.perms: the permissions string for the file, see chmod below.
chmod('path','mode')
fchmod(fd,'mode')
Change a file's mode (permissions).
Returns true on success.
The mode string is a 9 or 10 character string describing the
file permissions. The optional first character describes the
file type, and cannot be changed. Attempting to change the first
character will not cause the function to fail, but only the
permissions will be changed.
10 character string: -rwxrwxrwx
9 character string: rwxrwxrwx
After the option first character, the mode string is comprised of
3 sets of permissions for Read, Write, and eXecute, one each for
the user, group, and others.
rwx permissions for the file's owner
rwx permissions for users in the file's group
rwx permissions for other users
Replacing any of the permissions with a dash '-' will remove that
permission from that set:
rwxr-xr--
The user has all permissions, the group has read and execute
permissions, others have only read permissions.
isattty(fd)
returns true if fd refers to a tty.
fprintf(fd,format,args)
Print formatted text to the file at fd.
Actually formatting is a work in progress, ignore the args.
Returns true on success.
printf(fmt,args)
Equivalent to fprintf(io.stdout,fmt,args);
term: io.include('term')
Provides access to raw terminal and tty functions.
clear()
Clears the current terminal, equivalent to running `clear' from
the shell.
opentty()
Creates a new blank terminal (tty) with raw key events, for
custom displays and interactions. (The less command uses this).
Returns a reference object for interacting with the new tty.
Returns null on error.
var tty = term.opentty();
closetty(tty)
Closes a tty created with opentty().
ttyctrl(func,v)
Special function for setting and accessing CLIte-specific tty
data. Specifically for interacting directly with the form used
for user data input.
func is a string containing the intended function.
v is the value to set.
Returns either the requested data, or false on error.
term.ttyctrl('iset',string); // sets the current input value
var txt = term.ttyctrl('iget'); // gets the current input value
term.ttyctrl('prompt',string); // sets the current prompt text
Example Programs:
Due to the nature of javascript, it is not possible to simply stop half
way through a function to wait for user input or for some remote data
to load. Instead we have to use a callback function, which complicates
things a little, and means there are two kinds of programs: Syncronous,
and Asyncronous.
Syncronous Program:
A Syncronous program runs and then exits, with no waiting for callbacks.
As such, it looks much like a regular unix program might, and simply
returns with an exit code.
Here's a "Hello World" as an example:
clite.commands.load('hello',function(args,env,io) {
io.write("Hello World!");
return 0;
}
Asyncronous Program:
An Asycronous program typically uses io calls to interact with data
that may not be immediately available; such as remotely loading file
data or reading input from a user. As such callbacks are needed to
handle that data once it is available.
Therefore a return null is used, which lets the system know it is an
asyncronous program that will exit later using the io.exit() function.
Here's a simple program that reads in a file, and prints it to stdout:
clite.commands.load('show',function(args,env,io) {
var stdlib = io.include('stdlib');
var stdio = io.include('stdio');
// check there's a file to read from
if (args.length != 2) {
io.error('Specify a file to read');
return 1; // not asyncronous yet, so just return
}
// take the argument, and get it's full path
var file = stdlib.resolvePath(args[1]);
// file callback function that will receive the file descriptor
// once the file has data in it
function fcb(fd) {
if (!fd) {
// print an error, exit the program, then end
io.error('could not open file');
io.exit(1);
return;
}
// read in the whole file in one go
var data = stdio.readAll(fd);
// close the file
stdio.close(fd);
// check there's something there
if (!data) {
// print an error, exit the program, then end
io.error('could not read file');
io.exit(1);
return;
}
// write to stdout
io.write(data);
// and exit successfully
io.exit(0);
}
// open the file, and set the callback
var fd = stdio.open(file,fcb);
// we don't want to exit the program yet,
// so return null to let the system know that the
// program is asyncronous (reads user data, or loads remote data)
return null;
}
For more information, check the other readme files for info on CLIte internals.
Also, consider buying the developer a coffee:
https://ko-fi.com/ticklishhoneybee