Next: , Previous: Output From Interactive Applications, Up: Output From Interactive Applications


2.6.4.1 Line Oriented Interaction

Within this general pattern, more specific styles of interaction are possible. In the simplest one to explain first, the result returned by the function is always a data structure of the form (state,(command lines,prompts)), wherein the fields have these interpretations.

state
is a tree incorporating any data in any format that the application needs to remember from one invocation to the next.
command lines
is a list of character strings that are piped to the standard input stream of a separately spawned process. The process may persist from one invocation of the function to the next, or may be spawned each time.
prompts
is a non-empty list of character strings containing a suffix of the text expected from the standard output stream of the process as a result of sending the command lines to it.

On each iteration, avram sends the command line character strings to a separately spawned process, with line breaks between them if there are more than one command. If a process remains from the previous iteration that has not terminated itself, the list of command lines is sent to the same process. If no such process already exists, the first string in the list of command lines is treated as a shell command and used to spawn the process (using the exp_popen library function), and the remaining strings are sent to the newly spawned process.

Normally processes spawned with commands that invoke interactive command line interpreters of their own, such as bash, ftp or bc, will persist indefinitely unless the command causing them to exit is issued or some other event kills them. Processes spawned with non-interactive commands, such as ls or pwd, will terminate when the last of their initial output has been received.

In the case of processes that persist after being spawned, avram needs some way of knowing when to stop waiting for more output from them so that it doesn't get stuck waiting forever. This purpose is served by the prompts field. This field could contain a single string holding the last thing the process will send before becoming quiescent, such as the strings bash$ or ftp> in the above examples. Alternatively, a sequence of more than one prompt string can be used to indicate that the corresponding sequence of lines must be detected. An empty string followed by ftp> would indicate that the ftp> prompt is expected to be immediately preceded by a line break. There is also the option of using prompt strings to indicate a pattern that does not necessarily imply quiescence, but is a more convenient point at which to stop reading the output from the process.

For processes spawned with commands that do not start their own interactive command line interpreters, such as ls or pwd, it may be preferable to read all the output from them until they terminate. To achieve this effect, the list of prompt strings should contain only the single string containing only the single EOF character (usually code 4) or any other character that is certain not to occur in the output of the process. This technique is based on the assumption that the process was spawned originally with the command in question, not that such a command is sent to an existing shell process.

In any case, when enough output has been received from the process, it is collected into a list of received strings including the prompt strings at the end (if they were received), and the function is applied to the pair (state,received strings). If the cycle is to continue, the result returned by the function will include a new state, a new list of command lines, and a new list of prompt strings. A result of nil will cause the computation to terminate.

There are some unusual situations that could occur in the course of line oriented interaction, and are summarized as follows.