telnet中的终端操作.
telnet使用make_new_session来创建一个新的session.
在make_new_session中调用xgetpty来创建一个伪终端会话。
int FAST_FUNC xgetpty(char *line)
{
int p;
#if ENABLE_FEATURE_DEVPTS
p = open("/dev/ptmx", O_RDWR);
if (p > 0) {
grantpt(p); /* chmod+chown corresponding slave pty */
unlockpt(p); /* (what does this do?) */
#if 0 /* if ptsname_r is not available... */
const char *name;
name = ptsname(p); /* find out the name of slave pty */
if (!name) {
bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
}
safe_strncpy(line, name, GETPTY_BUFSIZE);
#else
/* find out the name of slave pty */
if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) {
bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
}
line[GETPTY_BUFSIZE-1] = '\0';
#endif
return p;
}
#else
struct stat stb;
int i;
int j;
strcpy(line, "/dev/ptyXX");
for (i = 0; i < 16; i++) {
line[8] = "pqrstuvwxyzabcde"[i];
line[9] = '0';
if (stat(line, &stb) < 0) {
continue;
}
for (j = 0; j < 16; j++) {
line[9] = j < 10 ? j + '0' : j - 10 + 'a';
if (DEBUG)
fprintf(stderr, "Trying to open device: %s\n", line);
p = open(line, O_RDWR | O_NOCTTY);
if (p >= 0) {
line[5] = 't';
return p;
}
}
}
#endif /* FEATURE_DEVPTS */
bb_error_msg_and_die("can't find free pty");
}
好像现在的linux操作系统都是会进入ENABLE_FEATURE_DEVPTS中。
即通过打开/dev/ptmx来创建一个伪终端会话。
/dev/ptmx是一个用于创建伪终端对。当一个进程调用open打开/dev/ptmx的时候,它会返回主伪终端的fd,并且在会在/dev/pts目录下创建一个对应的slave伪终端。
man说明如下。
NAME
ptmx and pts - pseudo-terminal master and slave
DESCRIPTION
The file /dev/ptmx is a character file with major number 5 and minor
number 2, usually of mode 0666 and owner.group of root.root. It is
used to create a pseudo-terminal master and slave pair.
When a process opens /dev/ptmx, it gets a file descriptor for a pseudo-
terminal master (PTM), and a pseudo-terminal slave (PTS) device is cre-
ated in the /dev/pts directory. Each file descriptor obtained by open-
ing /dev/ptmx is an independent PTM with its own associated PTS, whose
path can be found by passing the descriptor to ptsname(3).
Before opening the pseudo-terminal slave, you must pass the master’s
file descriptor to grantpt(3) and unlockpt(3).
Once both the pseudo-terminal master and slave are open, the slave pro-
vides processes with an interface that is identical to that of a real
terminal.
Data written to the slave is presented on the master descriptor as
input. Data written to the master is presented to the slave as input.
In practice, pseudo-terminals are used for implementing terminal emula-
tors such as xterm(1), in which data read from the pseudo-terminal mas-
ter is interpreted by the application in the same way a real terminal
would interpret the data, and for implementing remote-login programs
such as sshd(8), in which data read from the pseudo-terminal master is
sent across the network to a client program that is connected to a ter-
minal or terminal emulator.
Pseudo-terminals can also be used to send input to programs that nor-
mally refuse to read input from pipes (such as su(1), and passwd(1)).
FILES
/dev/ptmx, /dev/pts/*
NAME
ptsname, ptsname_r - get the name of the slave pseudo-terminal
SYNOPSIS
#define _XOPEN_SOURCE
#include
char *ptsname(int fd);
#define _GNU_SOURCE
#include
int ptsname_r(int fd, char *buf, size_t buflen);
DESCRIPTION
The ptsname() function returns the name of the slave pseudo-terminal (pty) device corresponding to the master referred to by fd.
The ptsname_r() function is the reentrant equivalent of ptsname(). It returns the name of the slave pseudo-terminal device as a null-terminated string
in the buffer pointed to by buf. The buflen argument specifies the number of bytes available in buf.
阅读(3895) | 评论(0) | 转发(1) |