Inferno and the Limbo Application Development Environment by Phillip Stanley-Marbell Example 1 : 0 /net/tcp/0/ctl 0 /net/tcp/0/data 0 /net/tcp/0/err 0 /net/tcp/0/listen 0 /net/tcp/0/local 0 /net/tcp/0/remote 0 /net/tcp/0/status 0 /net/tcp/0 0 /net/tcp/clone 0 /net/tcp/stats 0 /net/tcp 0 /net/icmp/clone 0 /net/icmp/stats 0 /net/icmp 0 /net/gre/clone 0 /net/gre/stats 0 /net/gre 0 /net/arp 0 /net/bootp 0 /net/iproute 0 /net/log 0 /net/ssl/clone 0 /net/ssl 1 /net Example 2: namaste% cd /net/tcp namaste% cat clone 7 namaste% cd 7 namaste% ls ctl data err listen local remote status namaste% cat local ::!0 namaste% cat remote ::!0 namaste% echo 'connect 199.125.85.76!80' > ctl namaste% cat local 192.168.1.2!18259 namaste% cat remote 199.125.85.76!80 namaste% Example 3: FileIO: adt { read: chan of (int, int, int, Rread); write: chan of (int, array of byte, int, Rwrite); }; Example 4: namaste$ ls -ls -rw-rw-r-- M 3 pip pip 138 Jul 04 08:29 simpleserver.m -rw-rw-r-- M 3 pip pip 1832 Jul 06 07:53 simpleserver.b namaste$ limbo simpleserver.b namaste$ ls -l -rw-rw-r-- M 3 pip pip 138 Jul 04 08:29 simpleserver.m -rw-rw-r-- M 3 pip pip 892 Jul 06 11:16 simpleserver.dis -rw-rw-r-- M 3 pip pip 1832 Jul 06 07:53 simpleserver.b namaste$ simpleserver Server - Initialising... namaste$ ls -l -rw------- s 0 pip pip 0 Jul 06 11:11 server.html -rw-rw-r-- M 3 pip pip 138 Jul 04 08:29 simpleserver.m -rw-rw-r-- M 3 pip pip 892 Jul 06 11:16 simpleserver.dis -rw-rw-r-- M 3 pip pip 1832 Jul 06 07:53 simpleserver.b namaste$ cat server.html Generated HTML

Dynamically Generated

Thu Jul 06 11:17:13 GMT 2000 namaste$ echo 'junk' > server.html namaste$ cat server.html Generated HTML

Dynamically Generated

Thu Jul 06 11:17:35 GMT 2000 namaste$ ls -l -rw------- s 0 pip pip 0 Jul 06 11:11 server.html -rw-rw-r-- M 3 pip pip 138 Jul 04 08:29 simpleserver.m -rw-rw-r-- M 3 pip pip 892 Jul 06 11:16 simpleserver.dis -rw-rw-r-- M 3 pip pip 1832 Jul 06 07:53 simpleserver.b namaste$ unmount . namaste$ ls -l -rw-rw-r-- M 3 pip pip 1832 Jul 06 07:53 simpleserver.b -rw-rw-r-- M 3 pip pip 892 Jul 06 11:16 simpleserver.dis -rw-rw-r-- M 3 pip pip 138 Jul 04 08:29 simpleserver.m namaste$ Table 1: Data Type Description int 32-bit, signed in two's complement notation big 64-bit, signed in two's complement notation real 64-bit, in IEEE long floating notation byte 8-bit, unsigned string Vector of Unicode characters Listing One SimpleFileServer : module { PATH : con "/usr/pip/dis/simpleserver.dis"; init : fn(ctxt : ref Draw->Context, args : list of string); }; Listing Two implement SimpleFileServer; include "sys.m"; include "draw.m"; include "daytime.m"; include "simpleserver.m"; sys : Sys; draw : Draw; daytime : Daytime; chanref : ref sys->FileIO; init(ctxt : ref Draw->Context, args : list of string) { sys = load Sys Sys->PATH; sys->print("Server - Initialising...\n"); sys->bind("#s", "/usr/pip", sys->MBEFORE); chanref = sys->file2chan("/usr/pip", "server.html"); if (chanref == nil) { sys->print("Server - Could not create chan file : %r\n"); } spawn worker(); } worker () { data : array of byte; index : int = 0; while (1) alt { (off, nbytes, fid, rc) := <-chanref.read => { if (rc == nil) break; ## If this is a new read, generate a new page if (index == 0) { data = gendata(); } ## len returns number of bytes in an array of bytes, ## number of unicode characters in a string or ## number of elements in a list. if (index < len data) { end := min(index+nbytes, len data); ## Serve the reader with data tha's left rc <-= (data[index:end], ""); index = end; } else { ## Finished serving contents of data[] rc <-= (nil, ""); ## So next read of data will start afresh index = 0; } } (offset, writedata, fid, wc) := <-chanref.write => { if (wc == nil) { break; } wc <-= (len writedata, ""); } } } gendata () : array of byte { daytime = load Daytime Daytime->PATH; head := "Generated HTML\n"; top := "

Dynamically Generated

\n"; body := daytime->time() + "\n"; tail := "\n"; return array of byte (head+top+body+tail); } min (a, b : int) : int { if (a < b) return a; return b; } 4