2010-06-04 2 views
4

Linux에서 (유닉스 98 스타일) 유사 TTY를 사용하여 write(1)wall(1) 메시지를 받고 싶습니다.pty에서 읽기

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <errno.h> 
#include <fcntl.h> 
#include <signal.h> 
#include <utempter.h> 

#define BUF_LENGTH 1024 

int 
main (void) 
{ 
    FILE *lf; 
    int masterfd, slavefd; 
    char *slave_name = NULL; 
    char buf[BUF_LENGTH]; 
    size_t nbytes = sizeof(buf); 
    ssize_t bytes_read; 
    int exit_code = EXIT_SUCESS; 

    if ((masterfd = posix_openpt (O_RDWR | O_NOCTTY)) == -1 
      || grantpt (masterfd) == -1 
      || unlockpt (masterfd) == -1 
      || (slave_name = ptsname (masterfd)) == NULL) 
     exit (EXIT_FAILURE); 

    if (!(lf = fopen("term.log","w"))) 
     exit (EXIT_FAILURE); 

    addToUtmp (slave_name, NULL, masterfd); 

    for (;;) 
    { 
     bytes_read = read(masterfd, buf, nbytes); 
     if (bytes_read <= 0) 
      break 
     fwrite (buf, 1, bytes_read, lf); 
    } 

    if (bytes_read < 0) 
    { 
     fprintf (stderr, "error reading from master pty: %s\n", strerror (errno)); 
     exit_code = EXIT_FAILURE; 
    } 

    fclose (lf); 
    if (slavefd >= 0) 
     close (slavefd); 
    if (masterfd >= 0) 
    { 
     removeLineFromUtmp (slave_name, masterfd); 
     close (masterfd); 
    } 
    exit (exit_code); 
} 

문제는 그것이 첫 번째 메시지를 읽기 위해 작동하는 지금, 그때 나에게 EIO 오류를 제공 읽어 은 이미 다음과 같은 최소한의 구현을 가지고있다. 왜 그런가요?

답변

1

마지막 슬레이브 파일 설명자가 닫힐 때 간단히 발생합니다. write(1)wall(1)이 슬레이브에 대한 유일한 파일 디스크립터를 가지고 있다고 가정하면 쓰기를 마자 마자 EIO를 얻게됩니다.

이 문제를 방지하는 가장 쉬운 방법은 파일 설명자를 유지하는 것입니다. ptsname 전화가 오면 바로 open(slave_name, O_RDRW)으로 전화하십시오.

(호기심, 당신은 이미 slavefd 변수, 그리고 그것을 정리하는 코드를 가지고 당신이 우리를 테스트 :.? p)를

+0

가 D' 오, 내가 실수로 오픈 라인을 실험하면서 삭제해야합니다 (당신으로 fd 변수에 주목하고 정리가 이미 있음). 고마워, 또 다른 한 쌍의 눈은 때로는 매우 도움이 될 수 있습니다 :) – gber