2010-03-23 3 views
4

새로운 소켓 연결에서 프로그램을 실행해야하는 간단한 "텔넷/서버"데몬을 개발하려고합니다. 이 부분은 정상적으로 작동합니다.forkpty - 소켓

그러나이 프로세스에는 readline과 같은 일부 터미널 기능이 있으므로 pty에 새 프로세스를 연결해야합니다.

내가 경제력 한 코드입니다 (socketfd은 새로운 입력 연결에 대한 새로운 소켓의 파일 기술자입니다) : 해당 코드, 내 "prgName의 표준 입력/표준 출력/표준 에러 파일 기술자와

int masterfd, pid; 
const char *prgName = "..."; 
char *arguments[10] = ....; 

if ((pid = forkpty(&masterfd, NULL, NULL, NULL)) < 0) 
    perror("FORK"); 
else if (pid) 
    return pid; 
else 
{ 
    close(STDOUT_FILENO); 
    dup2(socketfd, STDOUT_FILENO); 

    close(STDIN_FILENO); 
    dup2(socketfd, STDIN_FILENO); 

    close(STDERR_FILENO); 
    dup2(socketfd, STDERR_FILENO); 

    if (execvp(prgName, arguments) < 0) 
    { 
     perror("execvp"); 
     exit(2); 
    } 
} 

"(ls -la/proc/PID/fd로 볼 때) 소켓에 연결되어 있으므로이 프로세스의 터미널 기능이 작동하지 않습니다.

원격 장치에서 ssh/sshd를 통한 연결을 테스트하고 "localy"(ssh 연결 아래) prgName을 실행하면 "prgName"프로세스의 stdin/stdout/stderr fd가 pty (이 프로세스의 터미널 기능이 잘 작동 함).

내가 뭘 잘못하고 있니? 내 socketfd를 pty (forkpty로 생성)와 연결하는 방법은 무엇입니까?

감사

알렉스

답변

4

당신은 마스터 PTY 그 반대로 소켓에서 데이터를 전송하는 코드를 작성해야합니다. 대개는 부모 프로세스의 일입니다. 데이터 전송은 양방향이어야합니다. 많은 옵션이 있습니다 선별() - 구동 사이클이 masterfd과 socketfd 모두를 추적 할 수

(그냥 생산을위한 힌트, 아주 나쁜 코드로! 누락 오류 및 EOF 검사!)

for (;;) { 
    FD_ZERO(&set); 
    FD_SET(masterfd,&set); 
    FD_SET(socketfd,&set); 
    select(...,&set,...); 
    if (FD_ISSET(masterfd,&set)) { 
     read(masterfd,&c,1); 
     write(socketfd,&c,1); 
    } 
    if (FD_ISSET(sockerfd,&set)) { 
     read(sochetfd,&c,1); 
     write(masterfd,&c,1); 
    } 

또는 한 쌍의 스레드, socketfd-> masterfd 및 masterfd-> sockefd 전송 중 하나입니다. (다만 힌트로, 매우 나쁜 코드가 아닌 생산을위한!)

/*thread 1 */ 
     while (read(masterfd,&c,1) > 0) 
      write(socketfd,&c,1); 


/*thread 2 */ 
     while (read(socketfd,&c,1) > 0) 
      write(masterfdfd,&c,1); 

어쨌든 당신은 지점의 부모 측에 몇 가지 코드를 추가해야합니다.

안부

--- 편집 --- 물론 , 당신은 FD 0.1과 2는 자식 프로세스에 socketfd로 리디렉션하지 않아야합니다.

+0

감사합니다. 수동으로 masterfd를 sockfd로 복사하는 대신 "dup"을 만들 수 있습니까? 다른 함수 (openpty, grantpt, ...)를 사용하여 slavefd를 socketfd (masterfd를 만드는 대신)와 직접 통신하는 방법이 있습니까? – Alexxx

+0

필자가 아는 한, 아니요, 파일 디스크립터를 다른 디스크립터에 "바인딩"하는 자동 메커니즘이 없습니다 (스택 오버플로에 게시하는 것이 좋은 질문 일 수도 있습니다). 나는 당신이 "전통적인"해결책 중 하나를 선택해야하는 것이 아닌가 걱정됩니다. 안녕! –