외부 프로세스와 상호 작용할 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;
}
select에 대한 fdset 및 fdclr을 처리한다고 가정합니다.
다음 문제
는 부모 프로세스에서 관찰되고있다 :- 때때로의 readBytes> 0 만에 수익을 읽고 다시 읽어 터미널에 기록 된 어떤
- 때로는 버퍼에 존재 아무것도
- 일부 쓰레기 값 등 ^] 49] 1R은
PS (이것은 내 출력 창 즉 실제 단말기 인) 단자에 버려진되고 : 전자 xternal 프로세스는 C/C++로 작성되었지만이 문제는 발생하지 않습니다. 모노로 C# 프로그램을 실행할 때만.
['pipe (2)'매뉴얼 페이지] (http://linux.die.net/man/2/pipe)에서 "파이프의 쓰기 끝 부분에 쓰여진 데이터는 다음과 같이 버퍼링됩니다. 파이프의 읽기 끝에서 읽을 때까지 커널. " 이것은 파이프 자체가 "완전히 버퍼링"되어 있지 않다는 것을 의미하지만, 당신이 통신하는 프로그램은 C 프로그램에서'stdout'에 쓰는 것과 같이 출력 버퍼를 별도로 버퍼링하는 경우가 많습니다. –
@JoachimPileborg 성명서에 동의하십시오. 사실, 이것은 정확히 프로그램이하는 일입니다. – Cik