2009-09-02 11 views
1

これを最小限のテストケースに減らしました。これまで私は、これがsshのパイプで起こる擬似端末に関連する問題であると判断することができました。 ssh呼び出しに '-t -t'を追加すると、問題を引き起こすためにfgets()への2回目の呼び出しが必要になりました。私は、sshコマンドのstderr出力が何らかの形で問題になっていると思われます。今はstderrをsshコードのstdoutにリダイレクトして実行しています。私は "tcgetattr:無効な引数"エラーが問題の一部であるのだろうかと思っていますが、それを取り除く方法はわかりません。それは-t -tが存在することから来ているようです。私は-t -tが正しい方向に動いていると信じていますが、何とかstderr用の擬似端末を設定しなければならず、おそらくテストは正しく動作しますか?'ssh'のpopen()でfgets()を呼び出すと、呼び出し元プロセスのstdinの開始がフラッシュされています(ptty issue)

の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

FROMの代わりにTO/dev/nullをパイプしてみてください。 – GaZ

関連する問題