Récupérer valeur sortie exec

Fermé
Nb2 - 2 juin 2016 à 18:39
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 - 3 juin 2016 à 18:24
Bonjour,

J'ai codé un script qui me permet d’exécuter plusieurs commandes à la suite.

Voici mon code :

# include <stdio.h>
# include <unistd.h>
# include <sys/wait.h>
# include <stdlib.h>
# include <string.h>
# include <assert.h>

int parse( char * arg)
{
int t;
t = fork();
if (t < 0)
return -1;
if (t == 0)
{
execl("/bin/sh", "sh", "-c", arg,NULL);
exit(1);
}
return t;
}

int main(int argc, char *argv[])
{
int t, tt, status, i;
i = 1;

for (i=1; i < argc; i++)
{
t = parse(argv[i]);
tt = wait(&status);
assert(tt == t);

}
return 0;
}


Voici un exemple d’exécution :

$ ./test 'echo foo' 'echo false'
foo
false
$


J'aimerais le modifier de sorte qu'il s’arrête si une commande est fausse, actuellement ce qu'il fait est :

$ ./test 'ech foo' 'echo false'
sh: 1: ech: not found
false
$


Je crois savoir que je dois faire un fork avec l'exec dans l'enfant et récupérer la valeur de sortie de l'exec mais je n'y arrive pas.

Est-ce que quelqu'un voudrait bien m'aider ?

1 réponse

paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
Modifié par paly2 le 3/06/2016 à 16:05
Il faut que le processus fils écrive la valeur de retour dans une variable à une adresse connue.

# include <stdio.h> 
# include <unistd.h> 
# include <sys/wait.h> 
# include <stdlib.h> 
# include <string.h> 
# include <assert.h>

int parse(const char* arg, int* exec_return)
{
 int t;
 t = fork();
 if (t < 0)
  return -1;
 if (t == 0)
 {
  *exec_return = execl("/bin/sh", "sh", "-c", arg,NULL); // On modifie à l'adresse d'exec_return.
  exit(1);
 } 
 return t; 
} 
 
int main(int argc, char *argv[])
{
 int t, tt, status, i, exec_return;
 
 for (i = 1; i < argc; i++)
 {
  exec_return = 0;
  t = parse(argv[i], &exec_return); // S'il n'y a pas eu d'erreur, exec_return est resté à 0 (parce que execl n'a pas retourné), sinon, il est passé à -1.
  printf("exex_return: %d\n", exec_return);
  tt = wait(&status);
  assert(tt == t);
 }
 return 0; 
}


Note que execl ne retourne que s'il y a eu une erreur dans l'exécution de la fonction (pas celle du processus appelé).


Si c'est le retour du processus appelé que tu souhaites en fait récuperer (et visiblement c'est le cas), il faut utiliser la variable status que tu as la bonne idée de récupérer :
tt = wait(&status);
if(WIFEXITED(status))
        printf("Retour de la commande: %d\n", WEXITSTATUS(status));


La curiosité est une excellente qualité !
0
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
3 juin 2016 à 16:15
Note aussi la commande system() de stdlib.h, beaucoup plus simple à utiliser, mais j'ai souvenir d'avoir entendu que son utilisation causait une faille de sécurité. En tous cas, ton programme est largement simplifié par son utilisation :
# include <stdio.h>
# include <stdlib.h>

int main(int argc, char *argv[])
{
	int i, system_return;
	
	for (i = 1; i < argc; i++)
	{
		system_return = system(argv[i]);
       		// system_return est maintenant égal au retour de la commande argv[i] (donc 0 s'il n'y a eu aucune erreur), ou -1 s'il y a eu une erreur pendant l'exécution de system().
	}
	return 0; 
}


En fait, la fonction system() fait exactement ce que ton programme faisait: elle fork(), elle execve(), elle wait() puis elle retourne.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835 > paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018
3 juin 2016 à 17:51
Hello paly2,

Je confirme. C'est le mal absolu cette fonction system() :-).
Si c'est pour l'utiliser, autant programmer dans un autre langage car niveau performance elle n'est pas terrible.
Côté sécurité, le problème est que si l'utilisateur contrôle la variable dedans (accès direct sans contrôle, buffer overflow, etc.), il peut faire exécuter du code.
0
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
3 juin 2016 à 18:24
Ok merci pour les infos, c'était assez obscur pour moi cette faille de sécurité ^^
0