Go to the first, previous, next, last section, table of contents.


The last three examples involved communication only one direction with the subprocess: Either readOnly or write-only. This arrangement is simple and reliable, and is good when it suffices, but we often need to send information both to and from the subprocess.

Arranging such two-way communication with a Muq subprocess is simple, but when doing so you must always be wary of falling into a deadlock configuration in which both ends of the socket are waiting for the other to send something.

One good way to avoid deadlock is to use separate Muq jobs to read and write the socket. If you are sending long blocks of information each direction, this approach is recommended.

Another way to avoid deadlock is to simply send short one-line queries and responses, and to always wait for the response to one query before sending the next. We will use this approach in this example.

In this example, we show how to use a unix coprocess as a subroutine: We will define a process which reads one line, converts it to upper case, returns the result, and then exits. We will then write a MUF function which hides the process of invoking the server, so that we wind up with a function which to the caller looks much like stringUpcase -- but much slower, since a unix process must be started and stopped for each call. This is not a practical way to convert strings to uppercase, of course! But this might be a practical way to invoke a special FTP subserver, say, which fetched files on command from another site and then perhaps loaded them into the Muq db.

For simplicity, our example function will also assume that the given string contains exactly one newline, at the end of the string, and hence can be trivially read and written as a single line.

In muq/srv/ create a file unix-string-upcase-1 with contents

$_ = <STDIN>;

As usual, at the unix level, do chmod +x unix-string-upcase-1 to make the script executable.

Now, at the Muq prompt do:

: my-string-upcase-1 { $ -> $ } -> input
;----> makeSocket -> s
;----> makeMessageStream -> i
;----> makeMessageStream -> o
;----> i --> s$S.standardInput
;----> o --> s$S.standardOutput
;----> [ :socket s :commandline "|unix-string-upcase-1|" | ]rootPopenSocket
;----> input i writeStream
;----> o readStreamLine pop
;----> ;
"abc\n" my-string-upcase-1
root: "ABC

Fine point: Our my-string-upcase-1 function doesn't bother explicitly closing the socket. Doing an explicit close would do no harm, but since our unix-string-upcase-1 program exits by itself, and since Muq will close the socket automatically when the associated process exits, there is no actual need to explicitly close the socket.

Go to the first, previous, next, last section, table of contents.