Je cherche à faire la chose suivante en C++/C :
- executer une commande depuis mon code
- recuperer le code de retour
- recuperer stderr d'un coté
- recuperer stdout d'un autre coté
Pour le moment j'ai trouvé une solution avec popen+close qui me permet de recuperer le code de retour, en revanche, pour stderr et stdout, je ne vois pas comment les recuperer separement.
PS : on oubli le cat dans 2 fichiers, question d'optimisation
PS : via l'API java, on peut récuperer code de retour, stdout et stderr separement, donc c'est forcement possible en C, mais comment ... ?
Voila "en gros" mon code pour le moment :
FILE* pipe = popen(command.c_str(), "r");
if ( 0 == pipe ) {
// popen failed, log the error
return -1;
}
// Read pipe until it is closed by the child process
// store data in the output variable
char tmp[1024];
string output = "";
while ( 0 != fgets(tmp, 1024, pipe) )
{
output.append(tmp);
}
// wait for the end of the child process
int status = pclose(pipe);
// check status
std::cout << "status: " << status << std::endl;
if ( (-1 == status) and (ECHILD == errno) )
{
std::cout << "pclose failled " << std::endl;
return -1;
} else if ( false == WIFEXITED(status)) {
std::cout << "command exit with error " << std::endl;
return -1;
} else {
std::cout << "command exit ok" << std::endl;
return -1;
}
Je ne suis pas du tout sur pour le "WIFEXITED(status) == false".
Peut etre qu'il faut seulement mettre "status == -1" ?
Merci
# .
Posté par Vincent ORDY . Évalué à 5.
Je viens d'écrire rapidement (comprendre pas très propre) un code sur lequel tu peux te baser, si tu as des questions n'hésite pas !
[^] # Re: .
Posté par guitouu . Évalué à 1.
J'espérais pouvoir éviter les fork/execlp/dup2/waitpid.
Mais manifestement je ne peux pas faire ce que je veux juste avec system ou popen.
Donc je vais faire comme tu dis, encore merci.
[^] # Re: .
Posté par -=[ silmaril ]=- (site web personnel) . Évalué à 3.
[^] # Re: .
Posté par guitouu . Évalué à 1.
Mais ce n'est pas grave, je vais prendre la premiere, son fonctionnement est clair.
Une autre petite question :
Si la commande que je lance dans mon execl() pose une question (password par exemple) et qu'on ne s'y attendait pas, le processus ne finira jamais et on reste bloqué sur le waitpid dans le pere ... N'y a t'il pas une solution pour que le processus fils ne se bloque pas en attente d'une interaction sur stdin ? Par exemple, ne peut on pas "fermer" stdin de ce process ?
merci pour votre aide
[^] # Re: .
Posté par Vincent ORDY . Évalué à 1.
Bien sûr ! Il suffit de mettre dans le fils, avant le execl() :
close(STDIN_FILENO);
[^] # Re: .
Posté par guitouu . Évalué à 1.
if (close(STDIN_FILENO) != 0) {exit(-1);}
Je l'ai bien mis juste avant mon execl dans le code du child...
Une idée ?
[^] # Re: .
Posté par Vincent ORDY . Évalué à 1.
[^] # Re: .
Posté par guitouu . Évalué à 1.
close(stdin) marche bien effectivement pour la commande "/usr/bin/passwrd"
Par contre, si on fait "ssh localhost ls" (et que cette commande demande un mot de passe), ben ca marche pas, le process child demande le mot de passe dans la console qui a lancé le pere ...
Original .... Une idée du pourquoi il y a cette difference et comment faire pour le cas où ca marche pas ?
[^] # Re: .
Posté par Vincent ORDY . Évalué à 1.
[^] # Re: .
Posté par guitouu . Évalué à 1.
donc je peux pas faire grand chose ?
[^] # Re: .
Posté par Vincent ORDY . Évalué à 1.
Si, lire le man de SSH.
-> utilise une authentification SSH par clé, soit sans passphrase (c'est pas bien), soit avec une passphrase (et dans ce cas là tu peux utiliser ssh-agent pour la taper une seule fois, et en dehors du programme)
-> regarde du côté des paramètres -f et -n de SSH :
[^] # Re: .
Posté par guitouu . Évalué à 1.
[^] # Re: .
Posté par guitouu . Évalué à 1.
Le process demande tjrs le mot de passe au lieu de retourner "autantification failed".
De plus je ne veux pas lancer la commande en arriere plan (l'appel doit etre bloquant).
[^] # Re: .
Posté par Vincent ORDY . Évalué à 1.
Et là, pas de problème de mot de passe.
[^] # Re: .
Posté par guitouu . Évalué à 1.
Mais si la machine est mal configurée, par exemple le .ssh est supprimé...
La la commande SSH va à nouveau demander le mot de passe.
Et la il faudrait que ma fonction sorte en cas d'erreur plutot que de rester freeze sur un read() ... et ca je vois pas comment le faire.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.