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
<HTML><HEAD><TITLE>Generated HTML</TITLE></HEAD>
<BODY><CENTER><H1>Dynamically Generated</H1></CENTER>
Thu Jul 06 11:17:13 GMT 2000
</BODY></HTML>
namaste$ echo 'junk' > server.html
namaste$ cat server.html
<HTML><HEAD><TITLE>Generated HTML</TITLE></HEAD>
<BODY><CENTER><H1>Dynamically Generated</H1></CENTER>
Thu Jul 06 11:17:35 GMT 2000
</BODY></HTML>
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 := "<HTML><HEAD><TITLE>Generated HTML</TITLE></HEAD>\n";
        top  := "<BODY><CENTER><H1>Dynamically Generated</H1></CENTER>\n";
        body := daytime->time() + "\n";
        tail := "</BODY></HTML>\n";
        return array of byte (head+top+body+tail);
}
min (a, b : int) : int
{
        if (a < b)
                return a;
        return b;
}



4


