[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

#### 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.

- If the process terminates before any pattern matching the prompt strings is received from it, all of the output from the process up to the point where it terminated is collected into the received strings list and passed to the function. This situation includes cases where the process terminates immediately upon being spawned, but not abnormal completion of the `exp_popen` library function, which is a fatal error. This feature of the interface is what allows `EOF` to be used for collecting all the output at once from a non-interactive command.
- If the list of command lines is empty, and no process currently exists due to a previous iteration, the effect is the same as if the process terminates unexpectedly before outputting anything. I.e., the function is applied to a pair containing an empty list of received strings. There is no good reason for an application to get into this situation.
- If the list of command lines is empty but a process persists from a previous iteration, no output is sent to it, but receiving from it proceeds normally. This feature of the interface could be used effectively by applications intended to process the received data in parts, but will cause deadlock if the process is already quiescent.
- All character strings have to consist of lists of valid representations of non-null characters according to Character Table, or else there will be some fatal error messages.
- If the list of prompt strings contains only the empty string, `avram` will not wait to receive anything from the process, but will proceed with the next iteration immediately. If this effect is intended, care must be taken not to confuse the empty list of prompt strings with the list containing the empty string. The former indicates character oriented interaction, which is explained next.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated on November 8, 2012 using texi2html 1.82.