cocreate [-r rpath] [-w wpath] [-i id] [-R refname] [-s send_string] [-e expect_string] command
cosend [-n] proc_id string
codestroy [-R refname] proc_id [string]
The cocreate function starts command as a co-process and initializes communications by setting up pipes between FMLI and the standard input and standard output of command. The argument command must be an executable and its arguments (if any). This means that command expects strings on its input (supplied by cosend) and sends information on its output that can be handled in various ways by FMLI. The following options can be used with cocreate.
The cosend function sends string to the co-process identified by proc_id via the pipe set up by cocreate (optionally wpath), where proc_id can be either the command or id specified in cocreate. By default, cosend blocks, waiting for a response from the co-process. Also by default, FMLI does not send a send_string and does not expect an expect_string (except a newline). That is, it reads only one line of output from the co-process. If -e expect_string was not defined when the pipe was created, then the output of the co-process is any single string followed by a newline: any other lines of output remain on the pipe. If the -e option was specified when the pipe was created, cosend reads lines from the pipe until it reads a line starting with expect_string. All lines except the line starting with expect_string become the output of cosend. The following option can be used with cosend:
The cocheck function determines if input is available from the process identified by proc_id, where proc_id can be either the command or id specified in cocreate. It returns a Boolean value, which makes cocheck useful in if statements and in other backquoted expressions in Boolean descriptors. cocheck receives no input from the co-process; it simply indicates if input is available from the co-process. You must use coreceive to actually accept the input. The cocheck function can be called from a reread descriptor to force a frame to update when new data is available. This is useful when the default value of a field in a form includes coreceive.
The coreceive function is used to read input from the co-process identified by proc_id, where proc_id can be either the command or id specified in cocreate. It should only be used when it has been determined, using cocheck, that input is actually available. If the -e option was used when the co-process was created, coreceive will continue to return lines of input until expect_string is read. At this point, coreceive will terminate. The output of coreceive is all the lines that were read excluding the line starting with expect_string. If the -e option was not used in the cocreate, each invocation of coreceive will return exactly one line from the co-process. If no input is available when coreceive is invoked, it will simply terminate without producing output.
The codestroy function terminates the read/write pipes to proc_id, where proc_id can be either the command or id specified in cocreate. It generates a SIGPIPE signal to the (child) co-process. This kills the co-process, unless the co-process ignores the SIGPIPE signal. If the co-process ignores the SIGPIPE, it will not die, even after the FMLI process terminates (the parent process id of the co-process will be 1).
The optional argument string is sent to the co-process before the co-process dies. If string is not supplied, a NULL string is passed, followed by the normal send_string (newline by default). That is, codestroy will call cosend proc_id string: this implies that codestroy will write any output generated by the co-process to stdout. For example, if an interactive co-process is written to expect a ``quit'' string when the communication is over, the close descriptor could be defined;
close=`codestroy ID 'quit' | message`
and any output generated by the co-process when the string quit is sent to it via codestroy (using cosend) would be redirected to the message line.
The codestroy function should usually be given the -R option, since you may have more than one process with the same name, and you do not want to kill the wrong one. codestroy keeps track of the number of refnames you have assigned to a process with cocreate, and when the last instance is killed, it kills the process (id) for you. codestroy is typically called as part of a close descriptor because close is evaluated when a frame is closed. This is important because the co-process will continue to run if codestroy is not issued.
When writing programs to use as co-processes, the following tips may be useful. If the co-process program is written in C language, be sure to flush output after writing to the pipe. [Currently, awk(1) and sed(1) cannot be used in a co-process program because they do not flush after lines of output.] Shell scripts are well-mannered, but slow. C language is recommended. If possible, use the default send_string, rpath and wpath. In most cases, expect_string will have to be specified. This, of course, depends on the co-process.
In the case where asynchronous communication from a co-process
is desired, a co-process program should use
vsig to force strings into the pipe
and then signal FMLI that output from the co-process is available.
This causes the reread descriptor of all frames to be evaluated
If cosend is used without the -n option, a co-process that does not answer will cause FMLI to permanently hang.
The use of non-alphabetic characters in input and output strings to a co-process should be avoided because they may not get transferred correctly.