Advanced Programming in UNIX Environment Episode 122

本文介绍了如何使用伪终端(PTY)来驱动那些需要终端才能运行的交互式程序,例如解决passwd命令在非交互模式下运行的问题。pty可以帮助在非控制台环境中模拟终端行为,使得程序的标准输入和输出变为行缓冲,方便运行长时间运行的程序并监控其输出。文章还提到了pty的打开方式、grantpt和unlockpt函数的作用,并提供了ptym_open和ptys_open两个函数来简化PTY设备的使用。
摘要由CSDN通过智能技术生成
expect Program

Pseudo terminals can be used to drive interactive programs in noninteractive modes. Numerous programs are hard-wired to require a terminal to run. One example is the passwd(1) command, which requires that the user enter a password in response to a prompt.

Running Coprocesses

In the coprocess example in Figure 15.19, we couldn’t invoke a coprocess that used the standard I/O library for its input and output, because when we talked to the coprocess across a pipe, the standard I/O library fully buffered the standard input and standard output, leading to a deadlock. If the coprocess is a compiled program for which we don’t have the source code, we can’t add fflush statements to solve this problem.

Now the standard input and standard output of the coprocess look like a terminal device, so the standard I/O library will set these two streams to be line buffered.

Watching the Output of Long-Running Programs

If we have a program that runs for a long time, we can easily run it in the background using any of the standard shells. Unfortunately, if we redirect its standard output to a file, and if it doesn’t generate much output, we can’t easily monitor its progress, because the standard I/O library will fully buffer its standard output. All that we’ll see are blocks of output written by the standard I/O library to the output file, possibly in chunks as large as 8,192 bytes.

If we have the source code, we can insert calls to fflush to force the standard I/O buffers to be flushed at select points or change the buffering mode to line buffered using setvbuf. If we don’t have the source code, however, we can run the program under the pty program, making its standard I/O library think that its standard output is a terminal.

Opening Pseudo-Terminal Devices

PTYs act like physical terminal devices so that applications are unaware of which type of device they are using. However, applications don’t need to set the O_TTY_INIT flag when opening PTY device files. The Single UNIX Specification already requires that implementations initialize the slave side of a PTY device when it is first opened so that any nonstandard termios flags needed for the device to operate as expected are set. This requirement is intended to allow the PTY device to operate properly with POSIX-conforming applications that call tcgetattr and tcsetattr.

#include <stdlib.h>
#include <fcntl.h>
int posix_openpt(int oflag);

The oflag argument is a bitmask that specifies how the master device is to be opened, similar to the same argument used with open(2). Not all open flags are supported, however. With posix_openpt, we can specify O_RDWR to open the master device for reading and writing, and we can specify O_NOCTTY to prevent the master device from becoming a controlling terminal for the caller. All other open flags result in unspecified behavior.

#include <stdlib.h>
int grantpt(int fd);
int unlockpt(int fd);

The ptsname function is used to find the pathname of the slave pseudo terminal device, given the file descriptor of the master. This allows applications to identify the slave independent of any particular conventions that might be followed by a given platform. Note that the name returned might be stored in static memory, so it can be overwritten on successive calls.

#include <stdlib.h>
char *ptsname(int fd);

On FreeBSD, grantpt and unlockpt do nothing other than argument validation; the PTYs are created dynamically with the correct permissions. Note that FreeBSD defines the O_NOCTTY flag only for compatibility with applications that call posix_openpt. FreeBSD does not allocate a controlling terminal as a side effect of opening a terminal device, so the O_NOCTTY flag has no effect.

The Single UNIX Specification has improved portability in this area, but differences remain. We provide two functions that handle all the details: ptym_open to open the next available PTY master device and ptys_open to open the corresponding slave device.

#include "apue.h"
int ptym_open(char *pts_name, int pts_namesz);
int ptys_open(char *pts_name);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值