J'ai maintenant réduit cela à un cas de test minimal. Jusqu'à présent, j'ai été en mesure de déterminer que c'est un problème lié aux pseudo-terminaux qui se produisent avec le tuyau de SSH. L'ajout de '-t -t' à l'appel de ssh a amélioré les choses, en ce sens que maintenant, il faut un second appel à fgets() pour provoquer le problème. Je suspecte que la sortie stderr de la commande ssh fonctionne d'une manière ou d'une autre dans le problème, pour l'instant j'ai redirigé stderr vers stdout dans le code ssh pour l'exécuter. Je me demande si l'erreur "tcgetattr: Invalid argument" fait partie du problème, mais je ne suis pas sûr de savoir comment m'en débarrasser. Il semble provenir du -t -t étant présent. Je crois que -t -t va dans la bonne direction, mais je dois configurer le pseudo terminal pour stderr d'une manière ou d'une autre et peut-être que le test fonctionnera correctement?L'appel de fgets() sur popen() de 'ssh' vide le début de stdin du processus appelant (problème de ptty)
Le 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
Le fichier source test.c:
#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");
}
}
}
}
}
Cela montre fonctionner comme passage:
> 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 !!!!!!!
Cela montre fonctionner comme défaut :
> 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 ????
essayez d'acheminer la sortie TO/dev/null au lieu de FROM. – GaZ