이제 저는 이것을 최소한의 테스트 케이스로 축소했습니다. 지금까지 나는 이것이 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 ????
출력 대신에/dev/null을 출력하려고 시도한다. – GaZ