[manual index][section index]


file2chan, rblock, rdata, rerror, rget, rread, rreadone, rwrite - shell interface to file2chan


load file2chan file2chan filename readcmd writecmd [ closecmd ]
rblock [ tag ]
fetchwdata [ tag ]
putrdata [ tag ]
rerror [ tag ] errmsg
rread [ tag ] readdata
rreadone [ tag ] readdata
rwrite [ tag [ count ] ]
${rget (data|count|offset|fid) [ tag ] }


File2chan is a loadable module for sh(1) that provides facilities to create a file in the namespace with properties determined by a shell script. File2chan creates filename in the namespace and spawns a new thread to serve the file. If the creation succeeds and the thread is spawned successfully, then the environment variable $apid is set to the process id of the new thread; otherwise an error (non-nil) status is returned. Readcmd, writecmd and closecmd should be executable sh(1) command blocks. Subsequently, whenever a process reads from filename, readcmd will be invoked; whenever a process writes to filename, writecmd will be invoked; whenever an open file on filename is closed, then closecmd will be invoked, if present.

When a read or write request arrives, it is added to a list of currently outstanding tags maintained by file2chan. If the request is not replied to or acknowledged by the time the invoked command has finished, then a reply will be made automatically (the default is to accept all writes and to give an error on all reads). Each tag is assigned a unique tag id which is stored in the environment variable $tag for the duration of the invoked command. Most commands take an optional tag argument which should be the tag id of a currently outstanding request; if omitted, the value of $tag will be used. The following commands are provided to reply to requests and obtain information about requests:

Rblock marks tag as a blocking request - no automatic reply will be made when the currently invoked command has terminated; the process making the request will block until a reply is made.
Fetchwdata writes the data associated with tag (which must be a write request) to its standard output. It is useful if an uncorrupted version of binary data is wanted, as it avoids the data being interpreted as a utf-8 string.
Putrdata is the converse of fetchwdata: it reads data from its standard input and replies to tag (which must be a read request) with the data read. Any data in excess of that requested will be lost.
Rerror replies to tag with an error code; the remote read or write request will return an error, with the description errmsg.
Rread replies to the read request tag with the data in readdata. If readdata is longer than the number of bytes requested, then only the requested number of bytes of readdata will be sent. The offset of the read request is ignored.
Rreadone is similar to rread except that it honours the offset of the client's read request, so the client can use consecutive reads to retrieve all of readdata.
Rwrite replies to the write request tag. If count is given, then the client's write request will return that number (it is usually considered an error if the return from write (see sys-read(2)) is not the same as the number of bytes written). If count is omitted, all the bytes are assumed to have been written.
Rget retrieves information associated with tag. The information it yields depends on its first argument, which must be one of:
The data associated with write request tag.
The number of bytes requested by read request tag.
The client's file identifier associated with tag. A unique fid is associated with all client requests emanating from the same open file. This is the only rget request valid with the tag associated with a close operation.
The file offset associated with the request tag.


The following code creates a very simple memory-based file called /tmp/memfile.
	file2chan /tmp/memfile {rreadone $data} {data = ${rget data}}
It is, however, very limited, as binary data stored in the file will be corrupted, and the size of the file is limited to the amount of data that can be transmitted in a single write (see sys-read(2)).

The following code implements a single-threaded logfile which can support multiple concurrent writers:

	{file2chan /chan/log {} {fetchwdata}} >> /tmp/logfile

The following code makes the command cmd available to external programs, and defines a shell function to use it. Note that there's an approximate 8K limit on the size of the argument list that can be passed in this way.

	load std
	file2chan /chan/cmdchan {} {cmd ${unquote ${rget data}}}
	fn runcmd {echo -n ${quote $*} > /chan/cmdchan}




sys-file2chan(2), sh(1), intro(5),

SH-FILE2CHAN(1 ) Rev:  Tue Mar 31 02:42:38 GMT 2015