this documentation is work-in-progress, edit here (md).

Program/StdOut

sections in this chapter:
stdout
modulesplugins
reflection
[ Program ] memory: [Number]
[ Program ] shell-escape: [ String ]
[ Program ] os: [ String ]
[ Program ] chdir: [ String ]
[ Program ] mkdir: [ String ] mode: [ Number ]
[ Program ] argument: [ Number ]
[ Program ] number.
[ Program ] string
[ Program ] path
[ Program ] use: [ String ]
[ Program ] [ String ]
[ Program ] find: [ String ]
[ Program ] [ String ]: [ String ]
[ Program ] arguments
[ Program ] end
[ Program ] alarm: [ Number ]
[ Program ] pledge: [ String ]
[ Program ] unveil: [ String ] permissions: [ String ]
[ Program ] setting: [ String ]
[ Program ] setting: [ String ] value: [ String ]
[ Program ] ask
[ Program ] ask password
[ Program ] input
[ Program ] flush
[ Program ] error: [ String ]
[ Program ] version: [ Moment ]
[ Program ] feature: [ String ] enable: [ Boolean ]
[ Program ] feature: [ String ]

The Program Object represents the currently running app. This object offers functionality to execute system commands, include sub programs, read arguments and more. All system related functions.

StdOut

Out is the standard output object. It basically has two methods: write: and stop. The write: message is used to send a string to stdout, the stop message prints a newline character. Instead of stop you can also use \n.

Example:

Out write: ['Hello World'], stop.

result:

Hello World

Modules/Plugins

The world of Xoscript can be expanded with new system objects, by installing modules . A new system object can be added to the world of Xoscript by placing the module file (usually a file with the suffix .so or .dll) into the mods folder.

When you send a message to the object that is made available through the plugin module, it will be automatically loaded by Xoscript.

Reflection

There are various ways for system exploring during program execution. Xoscript holds a couple of methods to detect which objects are present and to which messages these objects respond. Firstly, each object can be asked what type it is, however types in Xoscript are malleable and therefore unreliable.

It is also possible to ask the Program object if a given object is already present in the program:

Program Tool true: { ... }.

In case of an object name which consists of one single symbol, it is best to apply the following notation to avoid confusion:

Program find: ['X'], true: { ... }.

Besides asking about objects, it is equally possible to ask the Program object about messages. For instance, it can be asked if the object Number knows the message between:and:, in the way as is illustrated below:

Program Number: ['between:and:'], stop.

[ Program ] memory: [Number]

Example:


Program memory: 8 MB.
Program memory: 500 KB.

Result:


[ Program ] shell-escape: [ String ]

Example:

# Program shell-escape produces canonical posix shell syntax
# compatible with: bash/dash, zsh, ksh
>> c := Program shell-escape: ['abc'].
Out write: c, stop.
Out write: ( Program os: ['echo '] + c ), stop.
c := Program shell-escape: ['a'b'c'].
Out write: c, stop.
Out write: ( Program os: ['echo '] + c ), stop.
c := Program shell-escape: ['a\'c'].
Out write: c, stop.
Out write: ( Program os: ['echo '] + c ), stop.

Result:

'abc'
abc
'a'\''b'\''c'
a'b'c
'a'\''c'
a'c

[ Program ] os: [ String ]

Example:

#Linux
>> x := Program os: Command uname.
Out write: x.

Result:

Linux

[ Program ] chdir: [ String ]

Example:


Program chdir: ['/tmp'].
Out write: (Program os: Command pwd).

Result:

/tmp

[ Program ] mkdir: [ String ] mode: [ Number ]

Example:

#Linux
Server init.
Program mkdir: ['/tmp/b'] mode: Oct o777.
Out write: (Program os: ['stat -c"%a" /tmp/b']) trim, stop.
Program os: ['rmdir /tmp/b'].

Result:

755

[ Program ] argument: [ Number ]

Example:


>> x := Program argument: 1.
Out write: x, stop.

Result:

../../../tests/t-0552.ctr

[ Program ] number.

Example:


>> x := Program number.
Out write: x, stop.

Result:

105011

[ Program ] string

Example:


>> x := Program string.
Out write: x, stop.

Result:

Welcome to xoscript.

[ Program ] path

Example:

>> path := Program path.
(path contains: ['/bin']) true: {
Out write: ['OK'], stop.
}.

Result:

OK

[ Program ] use: [ String ]

Example:


>> f := File new: (Path /tmp: ['x.ctr']).
f write: ['>> x := 123.'].
Program use: (Path /tmp: ['x.ctr']).
Out write: x, stop.

Result:

123

[ Program ] [ String ]

Example:


Out write: Program Object, stop.
Out write: Program Dream, stop.

Result:

True
False

[ Program ] find: [ String ]

Example:


Out write: (Program find: ['✎']), stop.
Out write: (Program find: ['Q']), stop.

Result:

False
False

[ Program ] [ String ]: [ String ]

Example:


Out write: (Program ✎: ['AAA']), stop.
Out write: (Program Program: ['test']), stop.

Result:

False
True

[ Program ] arguments

Example:


Out write: Program arguments, stop.

Result:

2

[ Program ] end

Example:


Out write: ['1..2..3..'], stop.
Program end.
Out write: ['4..5..6..'], stop.

Result:

1..2..3..

[ Program ] alarm: [ Number ]

Example:

# Setting alarm
# terminates the program after 1 sec.
Program alarm: 1.
Out write: ['max 1 sec.'], stop.
Moment wait: 2.
Out write: ['takes too long.'], stop.
# note:
# Setting an alarm is irreversible,
# an attacker cannot disable it.
# After the first call, the alarm is locked.
# Also the alarm is really harsh,
# the program *WILL* be stopped after the
# specified time interval, even if it is
# in a blocking read or something.
# note:
# Alarm is heavy, consider setting basic
# timeouts in the webserver instead.

Result:

max 1 sec.

[ Program ] pledge: [ String ]

Example:

#OBSD
# see https://man.openbsd.org/pledge for details
Program pledge: ['stdio'].
Out write: ['stdio allowed'], stop.
File list: ['/'].
Out write: ['process killed'], stop.

Result:

stdio allowed

[ Program ] unveil: [ String ] permissions: [ String ]

Example:

#OBSD
File list: ['/'].
# for details: https://man.openbsd.org/unveil
Program unveil: ['/tmp'] permissions: ['r'].
Program unveil: None permissions: None. # lock
{ File list: ['/']. } except: {
Out write: ['not unveiled!'], stop.
}, start.

Result:

not unveiled!

[ Program ] setting: [ String ]

Example:

#Linux
>> x := Program setting: ['SHELL'].
Out write: x, stop.
Program setting: ['TEST'] value: ['123'].
>> x := Program setting: ['TEST'].
Out write: x, stop.

Result:

/bin/bash
123

[ Program ] setting: [ String ] value: [ String ]

Example:

#Linux
>> x := Program setting: ['SHELL'].
Out write: x, stop.
Program setting: ['TEST'] value: ['123'].
>> x := Program setting: ['TEST'].
Out write: x, stop.

Result:

/bin/bash
123

[ Program ] ask

Example:


#Out write: Program ask, stop.
#@result
#~$ hello_
#hello
#~$_

Result:


[ Program ] ask password

Example:


#Out write: Program ask-password, stop.
#@result
#~$ ****_
#1234
#~$_

Result:


[ Program ] input

Example:

Server init.
>> message := ['this is a string to be encrypted!'].
>> key := ['secret123!'].
>> vault := Vault new: ['myvault'].
>> encrypted := vault encrypt: message key: key.
>> decrypted := vault decrypt: encrypted key: key.
Out
write: ['Message:'], stop
write: message, stop
write: ['Decrypted:'], stop
write: decrypted, stop.

Result:

Message:
this is a string to be encrypted!
Decrypted:
this is a string to be encrypted!

[ Program ] flush

Example:


Out write: ['Flush stdout buffer.'], stop.
Program flush.

Result:

Flush stdout buffer.

[ Program ] error: [ String ]

Example:

Program error: ['123'].

Result:

123

[ Program ] version: [ Moment ]

Example:

# backward compatibility forever
>> now := Moment new
year: 1993,
month: 1.
# program will always remain compatible with 1993-1
Program version: now.
Out write: ['
This program
will always run
like it ran in 1993!
Even with the latest
updates.
'], stop.

Result:


This program
will always run
like it ran in 1993!
Even with the latest
updates.

[ Program ] feature: [ String ] enable: [ Boolean ]

Example:

# toggle feature
>> feature := Program feature: ['RECURSIVE_STRINTPOL'].
Out write: feature, stop.
Program feature: ['RECURSIVE_STRINTPOL'] enable: True.
feature := Program feature: ['RECURSIVE_STRINTPOL'].
Out write: feature, stop.

Result:

False
True

[ Program ] feature: [ String ]

Example:

# toggle feature
>> feature := Program feature: ['RECURSIVE_STRINTPOL'].
Out write: feature, stop.
Program feature: ['RECURSIVE_STRINTPOL'] enable: True.
feature := Program feature: ['RECURSIVE_STRINTPOL'].
Out write: feature, stop.

Result:

False
True