OVH Cloud OVH Cloud

probleme avec wait

6 réponses
Avatar
did
salut
Je suis en train d'ecrire un shell tout con, qui est cense gerer le &.
Le probleme est que lorsque j'ecris par exemple pwd & sur la ligne de
commande, ca a l'air de marcher, mais quand je fais de suite apres un
pwd sans le &, le pere n'attend pas le fils. Je vous met a disposition
mon code. Si vous pouvez me dire ce qui cloche:

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

#define MAXLIGNE 50

#define OUI_EXIT(c) (strcmp("exit", c) == 0 ? 1 : 0)
#define OUI_ET(c) (strcmp("&", c) == 0 ? 1 : 0)

int saisir_ligne(char* chaine) {
return (fgets(chaine, MAXLIGNE, stdin) != NULL ? 1 : -1) ;
}


void vide_buffer() {
int c ;
while ((c = getchar()) != '\n') {
}
}


int main(int argc, char* argv[])
{
char ligne[MAXLIGNE] ;
char* listecom[100] ;
char* p ; /* pour strchr */
int et_vrai ;

while (1) {
char* pc ; /* pour strtok */
int i = 0 ;

int ret ; /* retour de fork */
int status ;

et_vrai = 0 ;

(void) printf("> ") ;
fflush(stdout) ;

if (saisir_ligne(ligne) == -1) {
(void) fprintf(stderr, "erreur de saisi de la ligne\n") ;
return EXIT_FAILURE ;
}
p = strchr(ligne, '\n') ;
if (p == NULL) {
(void) fprintf(stderr, "erreur: chaine trop longue\n") ;
vide_buffer() ;
}
else {
*p = '\0' ; /* on remplace le \n trouve par NULL */

if (OUI_EXIT(ligne)) {
return EXIT_SUCCESS ;
}

if (pc = strtok(ligne, " ")) {
listecom[i] = strdup(pc) ;
i++ ;
while (pc = strtok(NULL, " ")) {
listecom[i] = strdup(pc) ;
if (OUI_ET(listecom[i])) {
(void) printf("Y'a un &\n") ;
et_vrai = 1 ;
listecom[i] = NULL ;
}
i++ ;
}

listecom[i] = NULL ;

i = 0 ;

ret = fork() ;
if (ret < 0) {
perror("erreur:fork") ;
return EXIT_FAILURE ;
}
else if (ret == 0) {
(void) printf("execution du fils\n") ;
execvp(listecom[0], listecom) ;
perror("erreur:execvp") ;
exit (EXIT_FAILURE) ;
}
else {
if (et_vrai == 0) {
(void) printf("J'attends le fils\n") ;
if (wait(&status) < 0) {
perror("erreur:wait") ;
return EXIT_FAILURE ;
}
if (!WIFEXITED(status)) {
(void) printf("Le fils a mal fini\n") ;
}
}
for (i = 0 ; i < nb_mots ; i++) {
free(listecom[i]) ;
listecom[i] = NULL ;
}
}

}

}
}

return EXIT_SUCCESS ;
}

6 réponses

Avatar
Stephane Chazelas
2004-01-10, 10:43(+01), did:
Je suis en train d'ecrire un shell tout con, qui est cense gerer le &.
Le probleme est que lorsque j'ecris par exemple pwd & sur la ligne de
commande, ca a l'air de marcher, mais quand je fais de suite apres un
pwd sans le &, le pere n'attend pas le fils.
[...]


Utilise waitpid au lieu de wait. wait attend jusqu'à ce que
n'importe quel fils se termine, pas forcément celui que tu viens
de lancer.

Si tu fais

pwd &
puis
pwd

Le wait pour le deuxième "pwd" retourne immédiatement pour
rapporter la terminaison du premier "pwd".

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]

Avatar
did
Stephane Chazelas wrote:



Utilise waitpid au lieu de wait. wait attend jusqu'à ce que
n'importe quel fils se termine, pas forcément celui que tu viens
de lancer.

Si tu fais

pwd &
puis
pwd

Le wait pour le deuxième "pwd" retourne immédiatement pour
rapporter la terminaison du premier "pwd".



mais comment récupérer le pid du fils que l'on veut attendre? On fait un
getpid sur ledit fils, et il transmet le résultat au pere par un pipe?

Avatar
no
On Sat, 10 Jan 2004 13:56:07 +0100, did wrote:

Stephane Chazelas wrote:



Utilise waitpid au lieu de wait. wait attend jusqu'à ce que
n'importe quel fils se termine, pas forcément celui que tu viens
de lancer.

Si tu fais

pwd &
puis
pwd

Le wait pour le deuxième "pwd" retourne immédiatement pour
rapporter la terminaison du premier "pwd".



mais comment récupérer le pid du fils que l'on veut attendre? On fait un
getpid sur ledit fils, et il transmet le résultat au pere par un pipe?


Comment tu crés un « process fils » toi ?


Avatar
Mat Free
Le retour du fork() dans le pere est le pid du fils
Avatar
did
Mat Free wrote:
Le retour du fork() dans le pere est le pid du fils


Le probleme, c'est que vu que fork renvoie 0 quand on est dans le fils,

et une valeur > 0 quand on est dans le pere, je vois vraiment pas
comment on peut s'en sortir avec waitpid en utilisant ce resultat.
En gros, j'ai fait:
if (res > 0) {
if (NON_ET) {
waitpid(res, &status, WNOHANG) ;
}
}

Mais bon, sans convictions :'(

Avatar
Mat Free
En gros, j'ai fait:
if (res > 0) {
if (NON_ET) {
waitpid(res, &status, WNOHANG) ;
}
}

Mais bon, sans convictions :'(


Pour faire propre

switch(ret=fork())
{
case -1 : fprintf(stderr,"Erreur de forkn"); exit(1);

case 0 : printf("Chez le filsn");
exit(1);

default : /* chez le pere */
}

/* Chez le pere (puisque le fils a fait un exit) */

/* Attend la fin du fils pour continuer le traitement */
waitpid(ret, ...);