C语言 向伪终端发送特殊字符?



我正在尝试编写一个 C 程序,该程序创建一个运行新 bash 实例的伪终端,并记录通过它的所有输入和输出。最终目标是将其异步发送到服务器,其他人可以实时查看您的终端活动。

我已经完成了伪术语创建步骤,我可以启动一个新的 bash 实例并记录"大部分"输入和输出。我现在的问题是伪术语无法正确识别箭头键。它们作为 ASCII 值(^[[A, ^[[[B, ^[[C, ^[[D)打印到屏幕上,而不是在命令行周围移动光标。

这是 pty 的从属部分,它将运行 bash:

if(pid == 0){ //child 
struct termios term_settings;
close(ptyfds.master);
rc = tcgetattr(ptyfds.slave, &term_settings);
cfmakeraw(&term_settings);
tcsetattr(ptyfds.slave, TCSANOW, &term_settings);
//replace stdin,out,err with the slave filedesc 
close(0);
close(1);
close(2);
dup(ptyfds.slave);
dup(ptyfds.slave);
dup(ptyfds.slave);
//We can close original fd and use 0,1,2 
close(ptyfds.slave);
//Make this process the session lead 
setsid();
//Slave side of PTY becomes the new controlling terminal 
ioctl(0, TIOCSCTTY, 1);
char ** child_argv = (char **) malloc(argc * sizeof(char*));
int i;
for(i=1; i<argc; i++){
child_argv[i-1] = strdup(argv[i]); //could be bash, bc, python
}
child_argv[i-1] = NULL;
rc = execvp(child_argv[0], child_argv); 
}

这是pty的主站,向从站发送输入并捕获其输出。

if(pid == 0){ //parent
fd_set fd_in;
close(ptyfds.slave);
FILE *logFile = fopen("./log", "w");
while(1){
//Add stdin and master fd to object 
FD_ZERO(&fd_in);
FD_SET(0,&fd_in);
FD_SET(ptyfds.master, &fd_in);
//intercept data from stdin or from slave out (which is redirected to master) 
rc = select(ptyfds.master+1, &fd_in, NULL,NULL,NULL);
switch(rc){
case -1:
fprintf(stderr, "Error %d on select()n", errno);
exit(1);
default:
if (FD_ISSET(0, &fd_in)){ //There's data on stdin 
rc = read(0, input, sizeof(input));
if(rc > 0){
input[rc] = '';
write(ptyfds.master, input, rc);//send to master -> slave 
fputs(input, logFile);
}
else if(rc < 0){
fprintf(stderr, "Error %d on stdinn", errno);
exit(1);
}
}
if(FD_ISSET(ptyfds.master, &fd_in)){ //There's data from slave 
rc = read(ptyfds.master, input, sizeof(input)-1);
if(rc > 0){
input[rc] = '';
write(1, input, rc);//send to stdout 
fputs(input, logFile);
}
else if (rc < 0){
fprintf(stderr, "Error %d on read master ptyn", errno);
exit(1);
}
}
}//switch 
}//while 
}//end parent

我尝试在这里弄乱 termios 标志,但没有一个指定箭头键。

我需要做什么?

其中大部分代码来自这里。

我认为示例程序中有一个错误。 我能够通过移动来修复它:

rc = tcgetattr(ptyfds.slave, &term_settings);
cfmakeraw(&term_settings);
tcsetattr(ptyfds.slave, TCSANOW, &term_settings); 

进入主部分并将ptyfds.slave替换为STDIN_FILENO

(这会将 STDIN 设置为原始模式,而不是从模式(

相关内容

  • 没有找到相关文章

最新更新