2015-06-06 108 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?