PtTty

A PtTerminal widget attached to a device

Class hierarchy:

PtWidgetPtBasicPtContainerPtTerminalPtTty

For more information, see the diagram of the widget hierarchy.

PhAB icon:

PtTty button in PhAB

Public header:

<photon/PtTty.h>

Description:

A PtTty widget is a PtTerminal attached to a device. The device output is passed to the terminal, but also can be caught with the Pt_CB_TTY_OUTPUT callback.


PtTty


Output from a terminal device.

If the widget has the Pt_GETS_FOCUS flag set in its Pt_ARG_FLAGS resource, keyboard input to the widget (as well as mouse events) are redirected to the device. You can also use the Pt_ARG_TTY_INPUT resource to simulate keyboard input.

PtTerminal and PtTty

The main difference between PtTerminal and PtTty is that PtTerminal doesn't do any I/O for you. The only way to display characters in a PtTerminal is by giving them to one of the PtTerminalPut*() functions. Similarly, the only thing PtTerminal does with Photon input is translate function keys into text-mode compatible escape sequences and give the result to your Pt_CB_TERM_INPUT callback.

PtTty adds device I/O to that. The code that opens a pty, reads characters from it, and gives those characters to PtTerminalPut() is part of PtTty. Similarly, PtTty attaches a Pt_CB_TERM_INPUT callback that writes Photon keyboard input (translated by PtTerminal to text-mode compatible format) to the pty.

Another responsibility of PtTty is spawning a command for you and invoking the Pt_CB_TTY_TERMINATED callbacks when the command terminates.

Setting PtTty resources

Some of the resources for PtTty aren't just data stored in the widget, they're “action resources” that define an action to be performed when you set the resource. This includes all the resources flagged as write-only.

Some of those actions are order-dependent. For example, you can't spawn a program on a device (by setting Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV) before defining which device it's to be spawned on (by setting Pt_ARG_TTY_SFD, Pt_ARG_TTY_PATH, or Pt_ARG_TTY_PSEUDO).


Note: The widget opens its pty and starts its command as soon as you set Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV, even if the widget hasn't yet been realized. By default, the command continues to run if you unrealize the widget.

Additionally, the following resources are order-dependent even though they're not action resources:

Since the widget looks at the current value of these resources when spawning the command, changing their values after a command has been spawned doesn't affect the command that's already running. Make sure that those resources have correct values before you set Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV.

Here's an example:

/* Open a pseudo tty -- NULL is a shortcut for "/dev";
 * the widget will add something like "ttyp3" to it
 */
PtSetArg( &arg, Pt_ARG_TTY_PSEUDO, NULL, 0 );
PtSetResources( ABW_tty, 1, &arg );

/* Have we succeeded? */
PtSetArg( &arg, Pt_ARG_TTY_SFD, 0, 0 );
PtGetResources( ABW_tty, 1, &arg );
if ( arg.value == -1 )
    PtTerminalPuts( ABW_tty, "Unable to find a pty\r\n" );
else {
    /* Run a program on the pseudo tty.
     * NULL is more or less a shortcut for
     *   "char *argv[] = { "/bin/sh", NULL };",
     * except it runs *your* shell rather than always /bin/sh.
     */
    PtSetArg( &arg, Pt_ARG_TTY_ARGV, NULL, 0 );
    PtSetResources( ABW_tty, 1, &arg );

    /* Have we succeeded? */
    PtSetArg( &arg, Pt_ARG_TTY_PID, NULL, 0 );
    PtGetResources( ABW_tty, 1, &arg );
    if ( arg.value == 0 )
        PtTerminalPuts( ABW_tty, "Unable to spawn the shell\r\n" );
    }

Note: PhAB doesn't know that these resources are order-dependent. Set the resources in the correct order. If you suspect that the order isn't correct, set all the order-dependent resources to their default values, and then set them again in the correct order.

File descriptors

PtTty uses three file descriptors, but they don't have to be different. The following resources are involved:

Pt_ARG_TTY_RFD
The file descriptor that the widget uses for reading. Any input from this fd is displayed in the widget.
Pt_ARG_TTY_WFD
The fd to which the widget writes keyboard input.
Pt_ARG_TTY_SFD
The fd that the widget maps stdin, stdout, and stderr to when you set Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV.

Note: Pt_ARG_TTY_SFD overrides the entries in the iov array of the Pt_ARG_TTY_SPAWN_OPTIONS resource that correspond to the set bits in Pt_ARG_TTY_FDSET.

Pt_ARG_TTY_FDS
A shortcut for setting Pt_ARG_TTY_RFD, Pt_ARG_TTY_WFD, and Pt_ARG_TTY_SFD to the same value. Setting Pt_ARG_TTY_FDS to -1 closes any previously open file descriptors and sets Pt_ARG_TTY_PATH to NULL.

When you set Pt_ARG_TTY_RFD or Pt_ARG_TTY_WFD to a file descriptor, the widget sets the O_NONBLOCK flag on that fd if it isn't already set.

When the widget is later destroyed, or its resources are changed in such a way that neither Pt_ARG_TTY_RFD nor Pt_ARG_TTY_WFD references that fd any more, the widget unsets the O_NONBLOCK flag. If the Pt_ARG_TTY_SFD resource doesn't reference that fd either, the fd is then closed.

In short, if you give an fd to a PtTty widget, it's the widget's responsibility to close it when it's no longer used. If you want to keep the fd, make a copy using dup() (see the QNX Neutrino Library Reference) and give that copy to the widget. Either way, don't use either the copy or the original fd for any I/O while the widget is using it.

Drag and Drop

If you select some text and hold down the Ctrl key, you can drag the selected text to a PtText, PtMultiText, PtTerminal, or PtTty widget.

New resources:

Resource C type Pt type Default
Pt_ARG_TTY_ARGV char ** Pointer (write-only)
Pt_ARG_TTY_BUFFER char, unsigned short Array allocated
Pt_ARG_TTY_BUFLEN unsigned short Scalar 1024
Pt_ARG_TTY_CMD char * String (write-only)
Pt_ARG_TTY_DEVSIZE PtTerminalRowCol_t Struct 0, 0
Pt_ARG_TTY_EXIT_STATUS int Scalar 0 (read-only)
Pt_ARG_TTY_FDS int Scalar -1
Pt_ARG_TTY_FDSET unsigned short Scalar 7
Pt_ARG_TTY_FLAGS unsigned short Flag See below
Pt_ARG_TTY_INPUT char, unsigned short Array (write-only)
Pt_ARG_TTY_INPUT_WRITTEN unsigned short Scalar 0 (read-only)
Pt_ARG_TTY_PATH char * String NULL
Pt_ARG_TTY_PID pid_t Scalar 0
Pt_ARG_TTY_PRI int Scalar -1
Pt_ARG_TTY_PSEUDO char * String NULL
Pt_ARG_TTY_RFD int Scalar -1
Pt_ARG_TTY_SFD int Scalar -1
Pt_ARG_TTY_SPAWN_OPTIONS PtSpawnOptions_t const * Pointer NULL
Pt_ARG_TTY_WFD int Scalar -1
Pt_CB_TTY_DEVSIZE PtCallback_t * Link NULL
Pt_CB_TTY_OUTPUT PtCallback_t * Link NULL
Pt_CB_TTY_TERMINATED PtCallback_t * Link NULL

Pt_ARG_TTY_ARGV (write-only)

C type Pt type Default
char ** Pointer

When you set this resource, the widget spawns a process on the device. The resource value must be the pointer to a NULL-terminated array of pointers to strings. These strings are used for the program name and arguments.

The first string in the array specifies the program to execute. If it doesn't contain a slash character, the PATH environment variable is used to search for the program.

If the Pt_TTY_ARGV0 flag is set (which is the default), the first string is also used as the first argument to the new process (argv[0]). If the flag is clear, the argument list is assumed to start from the second item of the array passed as the resource value. This lets you run a program whose argv[0] entry is different from the actual name of the program.

If the list is NULL or contains too few non-NULL elements (the minimum is one when the Pt_TTY_ARGV0 flag is set and two when it's clear), the user's shell is spawned. If the Pt_TTY_ARGV0 flag is clear and the list is NULL or empty, this is a login shell.

All the flags and resources described under Pt_ARG_TTY_CMD, except the Pt_TTY_ARGV0 flag, have the same effect when this resource is set.

Pt_ARG_TTY_BUFFER

C type Pt type Default
char, unsigned short Array allocated

The buffer that's used by the widget for reading data from the device and passing them to the PtTerminalPut() function. If you set this resource, you must give both the address and the length of a buffer for the widget to use. Several widgets may share a common buffer, provided that none of them attaches a callback that could cause a recursive invocation of PtTerminalPut().

Pt_ARG_TTY_BUFLEN

C type Pt type Default
unsigned short Scalar 1024

The length of the buffer used by the widget for reading data from the device. If you set this resource, the widget allocates a buffer.

Pt_ARG_TTY_CMD (write-only)

C type Pt type Default
char * String

When you set this resource, the widget spawns a process on the device.

If the resource value is a NULL or points to an empty string, the user's shell is spawned. If the resource is a nonempty string, the widget spawns the user's shell with two arguments: -c and the resource string. In either case, if the Pt_TTY_ARGV0 flag is clear, the shell is started as a login shell.

If another process has been spawned previously and is still running, and the Pt_ARG_TTY_PID resource hasn't been set to zero, a SIGTERM signal is sent to the process group of that process before starting the new program.

If the Pt_TTY_SETENV flag is set (which is the default), the TERM environment variable of the new process is set to a value corresponding to the current terminal protocol (using the PtTerminalName() function). The environment variables LINES and COLUMNS are also removed if they exist.

Pt_ARG_TTY_DEVSIZE

C type Pt type Default
PtTerminalRowCol_t Struct 0, 0

The current device size. It can differ from the terminal widget's size, depending on the Pt_ARG_TTY_FLAGS resource. The PtTerminalRowCol_t structure contains the following members:

Pt_ARG_TTY_EXIT_STATUS (read-only)

C type Pt type Default
int Scalar 0

The exit status of the process spawned on the device. You can examine the value using the POSIX macros described for waitpid() in the QNX Neutrino Library Reference. The value is valid only after the child process has terminated.

Pt_ARG_TTY_FDS

C type Pt type Default
int Scalar -1

A shortcut for setting Pt_ARG_TTY_RFD, Pt_ARG_TTY_WFD, and Pt_ARG_TTY_SFD to the same value. Setting Pt_ARG_TTY_FDS to -1 closes any previously open file descriptors and sets the Pt_ARG_TTY_PATH to NULL.

For more details, see File descriptors,” above.

Pt_ARG_TTY_FDSET

C type Pt type Default
unsigned short Scalar 7

This number defines (as a bitmask) the set of file descriptors that the widget sets for a new process started when the Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV resource is set. The default value of 7 means that the PtTty widget's device is available as descriptors 0, 1 and 2. Only the ten low-order bits are used because the redirection is done using the iov[] member of the PtSpawnOptions_t structure, which has ten elements.

Pt_ARG_TTY_FLAGS

C type Pt type Default
unsigned short Flag See below

Flags that affect the widget's behavior. Any combination of:

By default, all bits are set except Pt_TTY_DEVFORCE.

If both Pt_TTY_TERMRESIZE and Pt_TTY_DEVRESIZE flags are set, changes of sizes are propagated in both directions. However, if the sizes differ at the moment when the flags are set or when the device is being opened, the device size is adjusted.

If the Pt_TTY_DEVFORCE flag is set, the Pt_TTY_DEVLIMIT flag is ignored.

Pt_ARG_TTY_INPUT

C type Pt type Default
char, unsigned short Array NULL

Characters to be written to the device.

Since the device is opened with the O_NONBLOCK flag, the number of bytes that are actually written may be less than the specified length. You can use the Pt_ARG_TTY_INPUT_WRITTEN resource to find out how many bytes the widget managed to write.

Pt_ARG_TTY_INPUT_WRITTEN (read-only)

C type Pt type Default
unsigned short Scalar 0

The number of characters successfully written by the Pt_ARG_TTY_INPUT resource.

Pt_ARG_TTY_PATH

C type Pt type Default
char * String NULL

When you set this resource, the widget closes all its file descriptors, then attempts to open the given pathname and stores the new fd (or -1 on error) in Pt_ARG_TTY_RFD, Pt_ARG_TTY_WFD, and Pt_ARG_TTY_SFD.

The descriptor is guaranteed to be greater than 2 and have the FD_CLOEXEC flag set.

Pt_ARG_TTY_PID

C type Pt type Default
pid_t Scalar 0

Zero or the process ID of the process that has been spawned on the device. The only value to which you can explicitly set this resource is zero, meaning “Forget about that process.” If this resource is nonzero when the device is closed (e.g. when the widget is being destroyed), a SIGHUP signal is sent to the process group of the child process.

Pt_ARG_TTY_PRI

C type Pt type Default
int Scalar -1

The priority of Photon pulses attached to the device — see PtAppAddFdPri() in the Photon Library Reference.

Pt_ARG_TTY_PSEUDO

C type Pt type Default
char * String NULL

When you set this resource, the widget closes all its file descriptors, then attempts to find and open a pseudo-tty.

The “master” fd is stored in both Pt_ARG_TTY_RFD and Pt_ARG_TTY_WFD, and the “slave” fd in Pt_ARG_TTY_SFD.

Also, the pathname of the slave device is stored in Pt_ARG_TTY_PATH.

You should set this resource to NULL or to the name of a directory that contains some ptys.

After opening the pseudo tty, the stty entry of the “slave” device is set to default modes. The editing keys are set according to the current value of the Pt_ARG_TERM_ANSI_PROTOCOL resource (see PtTerminal). If the protocol is changed with the same call to PtSetResources() that opens the pseudo tty, the order of the argument list is significant.

Both descriptors opened in this mode are guaranteed to be greater than 2 and have the FD_CLOEXEC flag set.

Pt_ARG_TTY_RFD

C type Pt type Default
int Scalar -1

The file descriptor that the widget uses for reading. Any input from this FD is displayed in the widget.

For more details, see File descriptors,” above.

Pt_ARG_TTY_SFD

C type Pt type Default
int Scalar -1

The file descriptor to which the widget maps stdin, stdout, and stderr when you set Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV.

For more details, see File descriptors,” above.


Note: Pt_ARG_TTY_SFD overrides the entries in the iov array of the Pt_ARG_TTY_SPAWN_OPTIONS resource that correspond to the set bits in Pt_ARG_TTY_FDSET.

Pt_ARG_TTY_SPAWN_OPTIONS

C type Pt type Default
PtSpawnOptions_t const * Pointer NULL

A pointer to a PtSpawnOptions_t structure that's used for spawning the child process.

If you leave this resource set to NULL, the widget uses the default values in:

extern const PtSpawnOptions_t PtTtyDefaultSpawnOptions
    

For more information about this structure, see PtSpawn() in the Photon Library Reference.


Note: Pt_ARG_TTY_SFD overrides the entries in the iov array of the Pt_ARG_TTY_SPAWN_OPTIONS resource that correspond to the set bits in Pt_ARG_TTY_FDSET.

Pt_ARG_TTY_WFD

C type Pt type Default
int Scalar -1

The file descriptor to which the widget writes keyboard input.

When you set this resource, the widget attaches itself to the given file descriptor. The descriptor must be open in a mode that allows writing. To force the widget to detach from any file descriptor it's attached to, set this resource to -1.

For more details, see File descriptors,” above.

Pt_CB_TTY_DEVSIZE

C type Pt type Default
PtCallback_t * Link NULL

A list of PtCallback_t structures that define the callbacks invoked when a resize event is received from the device (and before the terminal widget is resized according to the new size).

Each callback is passed a PtCallbackInfo_t structure that contains at least the following members:

reason
Pt_CB_TTY_DEVSIZE
event
NULL
cbdata
A pointer to a PtTerminalSizeChange_t structure that has at least following members:
PtTerminalRowCol_t old_size;
Previous size of the device.
PtTerminalRowCol_t new_size;
Current size.

The PtTerminalRowCol_t structure contains the following members:

These callbacks should return Pt_CONTINUE.

Pt_CB_TTY_OUTPUT

C type Pt type Default
PtCallback_t * Link NULL

A list of PtCallback_t structures that define the callbacks invoked when any output from the device is received (and before the output is passed to the terminal widget)

Each callback is passed a PtCallbackInfo_t structure that contains at least the following members:

reason
Pt_CB_TTY_OUTPUT
event
NULL
cbdata
A pointer to a PtTtyOutput_t structure that has at least following members defined:
int length;
The number of characters received.
const char * buffer;
A pointer to buffer containing the characters.

These callbacks should return Pt_CONTINUE.

Pt_CB_TTY_TERMINATED

C type Pt type Default
PtCallback_t * Link NULL

A list of PtCallback_t structures that define the callbacks invoked after the child process has terminated. Each callback is passed a PtCallbackInfo_t structure that contains at least the following members:

reason
Pt_CB_TTY_TERMINATED
event
NULL
cbdata
A pointer to an int containing the Pt_ARG_TTY_EXIT_STATUS resource.

These callbacks should return Pt_CONTINUE.

Inherited resources:

If the widget modifies an inherited resource, the “Default override” column indicates the new value. This modification affects any subclasses of the widget.

Resource Inherited from Default override
Pt_ARG_ANCHOR_FLAGS PtWidget
Pt_ARG_ANCHOR_OFFSETS PtWidget
Pt_ARG_AREA PtWidget
Pt_ARG_BANDWIDTH_THRESHOLD PtBasic Ph_BAUD_SLOW (see PtTerminal)
Pt_ARG_BASIC_FLAGS PtBasic
Pt_ARG_BEVEL_WIDTH PtWidget
Pt_ARG_BITMAP_CURSOR PtWidget
Pt_ARG_BEVEL_COLOR PtBasic
Pt_ARG_BEVEL_CONTRAST PtBasic
Pt_ARG_COLOR PtBasic
Pt_ARG_CONTAINER_FLAGS PtContainer
Pt_ARG_CONTRAST PtBasic
Pt_ARG_CURSOR_COLOR PtWidget
Pt_ARG_CURSOR_OVERRIDE PtContainer
Pt_ARG_CURSOR_TYPE PtWidget
Pt_ARG_DARK_BEVEL_COLOR PtBasic
Pt_ARG_DARK_FILL_COLOR PtBasic
Pt_ARG_DATA PtWidget
Pt_ARG_DIM PtWidget
Pt_ARG_EFLAGS PtWidget
Pt_ARG_EXTENT PtWidget
Pt_ARG_FILL_COLOR PtBasic
Pt_ARG_FILL_PATTERN PtBasic
Pt_ARG_FLAGS PtWidget
Pt_ARG_GRID_LAYOUT_DATA PtWidget
Pt_ARG_HEIGHT PtWidget
Pt_ARG_HELP_TOPIC PtWidget
Pt_ARG_HIGHLIGHT_ROUNDNESS PtBasic
Pt_ARG_INLINE_COLOR PtBasic
Pt_ARG_LAYOUT_DATA PtWidget
Pt_ARG_LIGHT_BEVEL_COLOR PtBasic
Pt_ARG_LIGHT_FILL_COLOR PtBasic
Pt_ARG_MARGIN_HEIGHT PtBasic
Pt_ARG_MARGIN_WIDTH PtBasic
Pt_ARG_MAXIMUM_DIM PtWidget
Pt_ARG_MINIMUM_DIM PtWidget
Pt_ARG_OUTLINE_COLOR PtBasic
Pt_ARG_POINTER PtWidget
Pt_ARG_POS PtWidget
Pt_ARG_RESIZE_FLAGS PtWidget
Pt_ARG_ROW_LAYOUT_DATA PtWidget
Pt_ARG_STYLE PtBasic
Pt_ARG_TERM_APP PtTerminal
Pt_ARG_TERM_COLOR_MODE PtTerminal
Pt_ARG_TERM_COLOR_TABLE PtTerminal
Pt_ARG_TERM_COLS PtTerminal
Pt_ARG_TERM_CONSOLE PtTerminal
Pt_ARG_TERM_CUR_COL PtTerminal
Pt_ARG_TERM_CUR_POS PtTerminal
Pt_ARG_TERM_CUR_ROW PtTerminal
Pt_ARG_TERM_CURSOR_FLAGS PtTerminal
Pt_ARG_TERM_DRAW_MODES PtTerminal
Pt_ARG_TERM_FONT PtTerminal
Pt_ARG_TERM_FONT_LIST PtTerminal
Pt_ARG_TERM_FONT_INDEX PtTerminal
Pt_ARG_TERM_FONT_SIZE PtTerminal
Pt_ARG_TERM_MARGINS PtTerminal
Pt_ARG_TERM_MAXCOLS PtTerminal
Pt_ARG_TERM_MAXROWS PtTerminal
Pt_ARG_TERM_MAXSIZE PtTerminal
Pt_ARG_TERM_MINCOLS PtTerminal
Pt_ARG_TERM_MINROWS PtTerminal
Pt_ARG_TERM_MINSIZE PtTerminal
Pt_ARG_TERM_OPTIONS PtTerminal
Pt_ARG_TERM_OPTMASK PtTerminal
Pt_ARG_TERM_ANSI_PROTOCOL PtTerminal
Pt_ARG_TERM_RESIZE_FL PtTerminal
Pt_ARG_TERM_RESIZE_FUN PtTerminal
Pt_ARG_TERM_RESIZE_STR PtTerminal
Pt_ARG_TERM_ROWS PtTerminal
Pt_ARG_TERM_SCRLBK_COUNT PtTerminal
Pt_ARG_TERM_SCRLBK_LIMIT PtTerminal
Pt_ARG_TERM_SCRLBK_POS PtTerminal
Pt_ARG_TERM_SCROLL PtTerminal
Pt_ARG_TERM_SELECTION PtTerminal
Pt_ARG_TERM_SIZE PtTerminal
Pt_ARG_TERM_VISUAL_BELL PtTerminal
Pt_ARG_TITLE PtContainer
Pt_ARG_TITLE_FONT PtContainer
Pt_ARG_TRANS_PATTERN PtBasic
Pt_ARG_USER_DATA PtWidget
Pt_ARG_WIDTH PtWidget
Pt_CB_ACTIVATE PtBasic
Pt_CB_ARM PtBasic
Pt_CB_BALLOONS PtContainer
Pt_CB_BLOCKED PtWidget
Pt_CB_CHILD_ADDED_REMOVED PtContainer
Pt_CB_DESTROYED PtWidget
Pt_CB_DISARM PtBasic
Pt_CB_DND PtWidget
Pt_CB_FILTER PtWidget
Pt_CB_GOT_FOCUS PtBasic
Pt_CB_HOTKEY PtWidget
Pt_CB_IS_DESTROYED PtWidget
Pt_CB_LOST_FOCUS PtBasic
Pt_CB_MENU PtBasic
Pt_CB_OUTBOUND PtWidget
Pt_CB_RAW PtWidget
Pt_CB_REALIZED PtWidget
Pt_CB_REPEAT PtBasic
Pt_CB_RESIZE PtContainer
Pt_CB_TERM_APP PtTerminal
Pt_CB_TERM_FONT PtTerminal
Pt_CB_TERM_INPUT PtTerminal
Pt_CB_TERM_OPTIONS PtTerminal
Pt_CB_TERM_RESIZE PtTerminal
Pt_CB_TERM_RESIZED PtTerminal
Pt_CB_TERM_SCRLBK PtTerminal
Pt_CB_UNREALIZED PtWidget

Convenience functions:

The PtTty widget defines the following convenience function:

PtTtyShell()
Return the user's default shell.