2015-06-06 69 views
1

我有一个Linux进程在后台运行。我想通过SSH接管它的stdin/out/err,并且也是终端控制器。 “原始”文件描述符也是伪终端。 我试过Reptyr和dupx。 Reptyr在vfork周围失败,但dupx工作得很好。所述GDB脚本它产生:控制终端和GDB

attach 123 
set $fd=open("/dev/pts/14", 0) 
set $xd=dup(0) 
call dup2($fd, 0) 
call close($fd) 
call close($xd) 
set $fd=open("/dev/pts/14", 1089) 
set $xd=dup(1) 
call dup2($fd, 1) 
call close($fd) 
call write($xd, "Remaining standard output of 123 is redirected to /dev/pts/14\n", 62) 
call close($xd) 
set $fd=open("/dev/pts/14", 1089) 
set $xd=dup(2) 
call dup2($fd, 2) 
call close($fd) 
call write($xd, "Remaining standard error of 123 is redircted to /dev/pts/14\n", 60) 
call close($xd) 

只要dupx命令完成时,不返回壳和目标应用程序接收我的输入(经由PTS/14)立即。

现在我想用我的独立二进制应用程序来实现相同的结果。我已经移植了相同的系统调用(DUP/DUP2 /关闭等)由dupx驱动什么被脚本由GDB执行:

int fd; int xd; 
char* s = "Remaining standard output is redirected to new terminal\n"; 

fd = open(argv[1], O_RDONLY); 
xd = dup(STDIN_FILENO); 
dup2(fd, STDIN_FILENO); 
close(fd); 
close(xd); 

fd = open(argv[1], O_WRONLY|O_CREAT|O_APPEND); 
xd = dup(STDOUT_FILENO); 
dup2(fd, STDOUT_FILENO); 
close(fd); 
write(xd, s, strlen(s)); 
close(xd); 

fd = open(argv[1], O_WRONLY|O_CREAT|O_APPEND); 
xd = dup(STDERR_FILENO); 
dup2(fd, STDERR_FILENO); 
close(fd); 
write(xd, s, strlen(s)); 
close(xd); 

运行snipplet上述通过注入一个共享库到远程进程完成通过sigstop/ptrace attach/dlopen/etc(使用类似于hotpatch的工具)。让我们考虑这个问题的一部分是安全可靠的:完成所有这些之后,目标进程的文件描述符会根据需要进行更改。我可以通过简单地检查/ proc/pidof target/fd来验证它。

但是,外壳返回,它仍然接收我的所有输入,而不是目标应用程序。

我注意到,如果我在这个点之后简单地用gdb连接/分离(=通过注入的C代码改变了fds)而没有实际改变任何东西,所需的行为就完成了(意思是:shell不返回,但目标应用程序启动接收我的输入)。命令是:

gdb --pid=`pidof target` --batch --ex=quit 

现在我的问题是:如何?在后台发生了什么?如何在没有gdb的情况下做同样的事情?我已经尝试过使用stracing gdb来获取一些提示,并尝试使用tty ioctl API而没有任何运气。

请注意,通过fork/setsid方式获取终端控制器状态(如果这是所有问题的关键),Reptyr使用的方式对我来说是不可接受的:我想避免分叉。 此外,我无法控制启动目标,所以“为什么不在屏幕上运行它”在这里没有答案。

+0

你写了_As一旦dupx命令完成,shell不会返回,目标应用程序立即收到我的输入(通过pts/14)._你从哪里得到这个'pts/14'?如果它是你的shell的终端,那么在'dupx'之后,shell和_target app_正在争夺来自'pts/14'的输入,而难以预测结果。 – Armali

+0

我ssh访问,那是pts/14来自哪里。壳牌和目标应用可能会竞争,但我从来没有经历过这种行为; dupx在这种情况下做了我想要的。 – Saturnus

回答

0

我ssh访问,那是pts/14来自哪里。壳牌和 目标应用可能会竞争,但我从来没有经历过这样的行为; dupx在这种情况下做了我想要的。

那么,坐下来想知道为什么偶然发现的偶然事件并不会解决它,即使这一点会被澄清。要走的路是通过设计而不是偶然的方式进行工作。为此,有必要让您的独立二进制应用程序不要返回到shell(以避免同时读取输入),而输入应该转到目标应用程序
参见e。 G。也Redirect input from one terminal to another,Why does tapping a TTY device only capture every other character?