2
我正在編寫一個與外部進程交互的C++程序。外部進程用C#編寫,並在單聲道上運行。請注意,我不能修改C#代碼,因爲它不是我寫的程序。在Linux中使用僞終端讀取寫入問題
在這方面,我首先通過使用管道進行了設置,當然後來我意識到這是完全緩衝的,因此我面臨很多同步問題。實質上,外部進程在每次寫入之後都必須刷新輸出,這是不可能的。
接下來我要嘗試的是文件,但是我發現在我的情況下使用僞終端更合適。下面是我寫的一些示例代碼:
int main()
{
int fdm, fds, rc, pid;
bool rValue;
/* Setup Master pty*/
rValue = rValue && (fdm = posix_openpt(O_RDWR)) >= 0 &&
(rc = grantpt(fdm)) == 0 && (rc = unlockpt(fdm) == 0);
if (rValue) {
/* Open Slave pty */
fds = open(ptsname(fdm), O_RDWR);
pid = fork();
if(pid < 0)
perror("fork failed");
else if(pid == 0) //child
{
close(fdm); //close master
struct termios slave_orig_term_settings;
struct termios new_term_settings;
tcgetattr(slaveTTY, &slave_orig_term_settings);
new_term_settings = slave_orig_term_settings;
cfmakeraw(&new_term_settings);
tcsetattr(slaveTTY, TCSANOW, &new_term_settings);
//redirect I/O of this process
close(0);
close(1);
close(2);
dup(slaveTTY);
dup(slaveTTY);
dup(slaveTTY);
close(slaveTTY);
setsid();
ioctl(0, TIOCSCTTY, 1);
//launch the external process and replace its image in this process
execve(argv[0],...);
}
else
{
close(fds); //close slave
//Perform some interaction
write(something using fdm);
//Assume fdsets declared and set somewhere here
select(fdm +1,&fdset,NULL,NULL,NULL);
int readBytes = read(someting using fds);
}
}
return EXIT_SUCCESS;
}
假設對於選擇的fdset和fdclr正在採取的照顧。
以下問題在父進程被觀察:
- 有時讀取的ReadBytes> 0,但返回沒有什麼存在於緩衝器
- 有時任何已寫入到所述終端被讀回
- 一些無用值如^]] 49] 1R被傾倒在終端上(這是我的即輸出窗口的實際終端)
PS:當電子xternal進程是用C/C++編寫的,這個問題不會發生。只有當我運行單聲道C#程序。
只是爲了澄清,從['pipe(2)'手冊頁](http://linux.die.net/man/2/pipe):「寫入到管道寫入端的數據被緩衝內核直到從管道的讀取端讀取。「這意味着管道本身並不是「完全緩衝」的,但很可能您與之通信的程序將其輸出單獨緩衝,例如從C程序寫入「stdout」。 –
@JoachimPileborg同意您的陳述。事實上,這正是程序正在做的事情。 – Cik