2012-10-26 2 views
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; 
} 

select에 대한 fdset 및 fdclr을 처리한다고 가정합니다.

다음 문제

는 부모 프로세스에서 관찰되고있다 :

  1. 때때로의 readBytes> 0 만에 수익을 읽고 다시 읽어 터미널에 기록 된 어떤
  2. 때로는 버퍼에 존재 아무것도
  3. 일부 쓰레기 값 등 ^] 49] 1R은

PS (이것은 내 출력 창 즉 실제 단말기 인) 단자에 버려진되고 : 전자 xternal 프로세스는 C/C++로 작성되었지만이 문제는 발생하지 않습니다. 모노로 C# 프로그램을 실행할 때만.

+0

['pipe (2)'매뉴얼 페이지] (http://linux.die.net/man/2/pipe)에서 "파이프의 쓰기 끝 부분에 쓰여진 데이터는 다음과 같이 버퍼링됩니다. 파이프의 읽기 끝에서 읽을 때까지 커널. " 이것은 파이프 자체가 "완전히 버퍼링"되어 있지 않다는 것을 의미하지만, 당신이 통신하는 프로그램은 C 프로그램에서'stdout'에 쓰는 것과 같이 출력 버퍼를 별도로 버퍼링하는 경우가 많습니다. –

+0

@JoachimPileborg 성명서에 동의하십시오. 사실, 이것은 정확히 프로그램이하는 일입니다. – Cik

답변

0

C++에서 수행 할 필요가 없다면 파이썬에서 pexpect은 좋은 선택이라고 생각합니다. 많은 시간을 절약 할 수 있습니다. 또한 pyinstaller과 같은 python 고정 도구를 사용하여 python 스크립트를 독립 실행 형 이진 파일로 변환 할 수 있습니다.