[Previous] [Contents] [Index] [Next]

PtTty

A PtTerminal widget attached to a device

Class hierarchy:

PtWidget --> PtBasic --> PtContainer --> PtTerminal --> PtTty

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. The Pt_ARG_TTY_INPUT resource can also be used 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 have to open a device (by setting Pt_ARG_TTY_FD, Pt_ARG_TTY_PATH, or Pt_ARG_TTY_PSEUDO) before you can spawn a program on the device (by setting Pt_ARG_TTY_CMD or Pt_ARG_TTY_ARGV).


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 resouces are order-dependent even though they're not action resources:

Since the widget looks at the current value of those 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 "//0/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_FD, 0, 0 );
PtGetResources( ABW_tty, 1, &arg );
if ( arg.value == -1 )
    PtTerminalPuts( "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( "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.

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_FD 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 NULL
Pt_ARG_TTY_INPUT_WRITTEN unsigned short Scalar 0 (read-only)
Pt_ARG_TTY_MFD int Scalar -1 (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_SPAWN_OPTIONS PtSpawnOptions_t const * Pointer NULL
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 this resource is being set, 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 allows to 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 this resource is set, both the address and the length of a buffer must be given. The widget then uses the given buffer. Several widgets may share a common buffer, provided that none of them attaches a callback that could cause a recursive invocation of the PtTerminalPut() function.

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 this resource is set, the widget allocates a buffer.

Pt_ARG_TTY_CMD (write-only)

C type Pt type Default
char * String

When this resource is being set, 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. The value can be examined using the POSIX macros described in the C Library Reference, under waitpid(). The value is valid only after the child process has terminated.

Pt_ARG_TTY_FD

C type Pt type Default
int Scalar -1

When this resource is set, the widget attaches itself to the given file descriptor. The descriptor must be a character device open in a mode that allows reading. Using a value of -1 forces the widget to detach from any device it's attached to.

When this resource is read, the current file descriptor is returned. If the widget isn't attached to any device, -1 is returned.

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

The possible flags are as follows:

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. The Pt_ARG_TTY_INPUT_WRITTEN resource can be used to find out how many bytes the widget managed to read.

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_MFD (read-only)

C type Pt type Default
int Scalar -1

The current "master" file descriptor. It's equal to the Pt_ARG_TTY_FD resource unless the device has been opened using the Pt_ARG_TTY_PSEUDO resource, in which case this is the descriptor of the "master" size of the pty.

Pt_ARG_TTY_PATH

C type Pt type Default
char * String NULL

When this resource is set, the widget opens the given pathname for reading and writing and attaches itself to the open device. The pathname must be a character device.

The descriptor is greater than 2 and has the CLOEXEC flag set.

When this resource is read, the pathname of the current device is returned. If the widget isn't attached to any device or was attached using the Pt_ARG_TTY_FD resource, NULL is returned.

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 this resource can be explicitly set 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

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 this resource is set, the widget attempts to find an unused pseudo-tty device and attach to it. The resource value is used as a prefix to which a string similar to /ttyp0 is appended. If a NULL is given, //0/dev is used instead. If an empty string "" is given, /dev is assumed and thus the default network root rather than the local node is used. The application can also choose an explicit prefix or scan a configuration-dependent prefix list.

If a pseudo tty has been opened in this way, the widget uses the "master" end of the tty, but when reading the Pt_ARG_TTY_FD or Pt_ARG_TTY_PATH resources, information about the "slave" end is returned. The Pt_ARG_TTY_PSEUDO resource can be read to obtain the "master" device pathname.

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_PROTOCOL resource. 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 greater than 2 and have the CLOEXEC flag set.

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 this resource is left as NULL, default values in

extern const PtSpawnOptions_t PtTtyDefaultSpawnOptions
    

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

Pt_CB_TTY_DEVSIZE

C type Pt type Default
PtCallback_t * Link NULL

A list of 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
The name of the callback resource (Pt_CB_TTY_DEVSIZE) that caused this callback to be invoked.
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 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
The name of the callback resource (Pt_CB_TTY_OUTPUT) that caused this callback to be invoked.
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 callbacks invoked after the child process has terminated. Each callback is passed a PtCallbackInfo_t structure that contains at least the following members:

reason
The name of the callback resource (Pt_CB_TTY_TERMINATED) that caused this callback to be invoked.
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 PtContainer
Pt_ARG_ANCHOR_OFFSETS PtContainer
Pt_ARG_AREA PtWidget
Pt_ARG_BANDWIDTH_THRESHOLD PtBasic Ph_BAUD_SLOW (see below)
Pt_ARG_BITMAP_CURSOR PtWidget
Pt_ARG_BORDER_WIDTH PtWidget
Pt_ARG_BOT_BORDER_COLOR PtBasic
Pt_ARG_COLOR PtBasic
Pt_ARG_CONTAINER_FLAGS PtContainer
Pt_ARG_CURSOR_COLOR PtWidget
Pt_ARG_CURSOR_TYPE PtWidget
Pt_ARG_DATA PtWidget
Pt_ARG_DIM PtWidget
Pt_ARG_EFLAGS PtWidget
Pt_ARG_FILL_COLOR PtBasic
Pt_ARG_FILL_PATTERN PtBasic
Pt_ARG_FLAGS PtWidget
Pt_ARG_HELP_TOPIC PtWidget
Pt_ARG_HIGHLIGHT_ROUNDNESS PtBasic
Pt_ARG_MARGIN_HEIGHT PtBasic
Pt_ARG_MARGIN_WIDTH PtBasic
Pt_ARG_POS PtWidget
Pt_ARG_RESIZE_FLAGS PtWidget
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_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_TOP_BORDER_COLOR PtBasic
Pt_ARG_TRANS_PATTERN PtBasic
Pt_ARG_USER_DATA PtWidget
Pt_CB_ACTIVATE PtBasic
Pt_CB_ARM PtBasic
Pt_CB_BALLOONS PtContainer
Pt_CB_BLOCKED PtWidget
Pt_CB_DESTROYED PtWidget
Pt_CB_DISARM PtBasic
Pt_CB_FILTER PtContainer
Pt_CB_GOT_FOCUS PtBasic
Pt_CB_HOTKEY PtWidget
Pt_CB_LOST_FOCUS PtBasic
Pt_CB_MENU PtBasic
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
Pt_ARG_BANDWIDTH_THRESHOLD
The threshold value for graphics bandwidth (as reported by PhQuerySystemInfo()) that defines a slow connection. For more information, see Pt_ARG_TERM_CURSOR_FLAGS and the "Scrolling optimization" part of the "Description" section for PtTerminal.

Convenience functions:

The PtTty widget defines the following convenience functions:

PtTtyShell()
Return the default user's shell.

[Previous] [Contents] [Index] [Next]