2009-09-02 8 views
1

이제 저는 이것을 최소한의 테스트 케이스로 축소했습니다. 지금까지 나는 이것이 ssh의 파이프와 관련된 pseudo-terminal과 관련된 쟁점이라고 판단 할 수 있었다. ssh 호출에 '-t -t'를 추가하면 문제를 일으키는 fgets()가 두 번째 호출됩니다. ssh 명령의 stderr 출력이 어떻게 든 문제에 영향을 미쳤다고 생각합니다. 현재 stderr를 ssh 코드의 stdout으로 리디렉션했습니다. "tcgetattr : 잘못된 인수"오류가 문제의 일부인지 궁금해하지만 그걸 제거하는 방법을 모르겠다. 그것은 -t-t에서 오는 것 같습니다. 나는 -t- t가 올바른 방향으로 움직이고 있다고 믿지만, 어떻게 든 stderr를위한 pseudo terminal을 설정해야하고 아마 테스트가 제대로 작동 할 것인가? 'ssh'의 popen()에 fgets()를 호출하면 호출 프로세스의 stdin의 시작 부분이 비워지고 있습니다. (아주 좋은 문제입니다)

Makefile을 :

test: 
    gcc -g -DBUILD_MACHINE='"$(shell hostname)"' -c -o test.o test.c 
    gcc -g -o test test.o 

.PHONY: clean 
clean: 
    rm -rf test.o test 

TEST.C 소스 파일 :

> echo "The quick brown fox jumped" | ./test n 
Command: ls 
First result: ARCH.linux_26_i86 

Second result: Makefile 

!!!!!!! Without ssh popen() did not consume stdin !!!!!!! 

이가 실패한 방법을 실행 보여줍니다

#include <unistd.h> 
#include <string.h> 
#include <stdio.h> 

int 
main(int argc, char *argv[]) 
{ 
    const unsigned int bufSize = 32; 
    char buf1[bufSize]; 
    char buf2[bufSize]; 
    int ssh = argv[1][0] == 'y'; 
    const char *cmd = ssh ? "ssh -t -t " BUILD_MACHINE " \"ls\" 2>&1" : "ls"; 

    FILE *fPtr = popen(cmd, "r"); 

    if (fPtr == NULL) { 
    fprintf(stderr,"Unable to spawn command.\n"); 
     perror("popen(3)"); 
     exit(1); 
    } 
    printf("Command: %s\n", cmd); 
    if (feof(fPtr) == 0 && fgets(buf2, bufSize, fPtr) != NULL) { 
    printf("First result: %s\n", buf2); 
    if (feof(fPtr) == 0 && fgets(buf2, bufSize, fPtr) != NULL) { 
     printf("Second result: %s\n", buf2); 
     int nRead = read(fileno(stdin), buf1, bufSize); 

     if (nRead == 0) { 
     printf("???? popen() of ssh consumed the beginning of stdin ????\n"); 
     } else if (nRead > 0) { 
     if (strncmp("The quick brown fox jumped", buf1, 26) != 0) { 
      printf("??? Failed ???\n"); 
     } else { 
      printf("!!!!!!! Without ssh popen() did not consume stdin !!!!!!!\n"); 
     } 
     } 
    } 
    } 
} 

이 그것을 통과 방법을 실행 보여줍니다 :

> echo "The quick brown fox jumped" | ./test y 
Command: ssh -t -t hostname "ls" 2>&1 
First result: tcgetattr: Invalid argument 

Second result: %backup%~    gmon.out 

???? popen() of ssh consumed the beginning of stdin ???? 

답변

1

좋아, 나는 마침내이 작업을했습니다. 코드가 제대로 작동하는 동안, 나는 분명히 내가가 무시할 수있는 불쾌한 메시지가,

 const char *cmd 
     = ssh ? "ssh -t -t " BUILD_MACHINE " \"ls\" 2>&1 < /dev/null" : "ls"; 

그러나 : 위의 테스트 케이스에서 다음과 같이 비밀은 내 ssh 명령의 입력으로는/dev/null을 공급했다 내 목적 (비록 내가 메시지를 사라지게하고 싶지만) :

tcgetattr: Inappropriate ioctl for device 
+0

출력 대신에/dev/null을 출력하려고 시도한다. – GaZ