IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Probleme avec le file descriptor Language C fork, exec, read


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 5
    Par défaut Probleme avec le file descriptor Language C fork, exec, read
    Bonjour tout le monde ,

    je suis debutante en C , et j'ai eu un devoir qui consiste creer deux processus père et fils...

    j'ai écrit un programme (que nous appellerons père) qui :

    -demande à l’utilisateur une commande (avec options et paramètres éventuels)

    -crée un processus fils

    -lui transmet la commande lue (+ options et paramètres bien sur).

    Le fils exécute la commande reçue et transmet les résultats à son père.

    Le père affiche à l’écran les résultats reçus.

    Quand je compile ce code, ça ne me renvoie aucune erreur... Cependant je le lance par exemple avec cette commande: ./unix ls -l /home
    (avec unix le nom du fichier compilé biensur ).

    ça ne fonctionne pas et ça me renvoie plutôt comme erreur :

    ls: write error: bad file descriptor



    Et ça ne je ne sais pourquoi...

    pourriez vous m'aider? merci d'avance



    Le code est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    #include<stdio.h>
     
    #include<stdlib.h>
     
    #include<unistd.h>
     
    #include<string.h>
     
    #include<sys/types.h>
     
    #include<sys/wait.h>
     
    #include<fcntl.h>
     
     
     
    int main(int argc, char *argv[]) {
     
        /* Père */
     
        char* myargv[argc];
     
        // argv du exec
     
        char* argfils[argc];
     
        int fp[2]; // file descriptor
     
        int rep = pipe(fp);
     
    // Test du pipe
     
    if(rep == -1){
     
      printf("%s\n", "Il y a une erreur dans la création du
      pipe" );
     
      exit(-1);
     
    }
     
    /* Fils */
     
    int f = fork();
     
    if(f == -1){
     
      printf("%s\n", "Erreur du fork");
     
      exit(-1);
     
     }
     
    if(f == 0){
     
    int i;
     
    for(i = 1;i < argc; i++){
     
       myargv[i - 1] = argv[i];
     
    }
     
    myargv[argc - 1] = NULL;
     
    printf("%s\n", argv[1]);
     
    printf("%s et %s et %s et %s\n", myargv[0],myargv[1],myargv[2],myargv[3]);
     
    dup2(fp[1],1); // redirection
     
            execvp(argv[1], myargv);
     
    }
     
    else{
     
    // ferme le out du pere
     
        char lu[1024];
     
       read(fp[1], lu, 1024); // le nombre de byte qui ont été lus
     
               printf("%s\n", lu);
     
      wait(NULL);
     
        // on fait attendre le processus parent
     
    }
     
    return EXIT_SUCCESS;
     
    }

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Tu tentes de lire depuis l'entrée du pipe, fp[1].

    Accessoirement, il me semble qu'il faudrait fermer les deux descripteurs à l'aide de close dans le code du fils après l'appel à dup2.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par manou1998 Voir le message
    Bonjour tout le monde ,

    je suis debutante en C , et j'ai eu un devoir qui consiste creer deux processus père et fils...
    Bonjour
    C'est déjà un TP qui dépasse le domaine du débutant...

    Citation Envoyé par manou1998 Voir le message
    ça ne fonctionne pas et ça me renvoie plutôt comme erreur :

    ls: write error: bad file descriptor

    Et ça ne je ne sais pourquoi...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       read(fp[1], lu, 1024); // le nombre de byte qui ont été lus
     
               printf("%s\n", lu);
    Me semble que dans un tube, on écrit sur le coté [1] et on lit sur le coté [0] (un peu comme avec les processus qui écrivent dans le flux 1 et lisent le flux 0). Toi, tu lis le coté [1]...!!!???

    Autre détails: le tube ayant été ouvert des deux cotés, mais chaque processus père/fils ne travaillant que sur un des deux cotés, alors chaque processus doit fermer le coté qu'il n'utilise pas et aussi, une fois qu'il a fini, fermer le coté qu'il a utilisé.

    Sinon je ne vois pas à quoi servent les tableaux "argfils" (inutilisé) et "myargv" (qui ne fait que récupérer "argv"). A mon avis, quand on a déjà la valeur dans une variable ça ne sert pas à grand chose de la recopier dans une seconde (surtout si on ne touche pas à la première)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 5
    Par défaut
    ok merci à vous! donc le probleme était au niveau de la fermeture des pipes et aussi du read: j'ai les modifié et ça marche maintenant bien!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
     
    	if(f == 0){
     
      	int i;
     
      	for(i = 1;i < argc; i++){
     
      		myargv[i - 1] = argv[i];
     
      	}
     
      	myargv[argc - 1] = NULL;
     
        //close(1);
      	printf("%s\n", argv[1]);
     
      	printf("%s et %s et %s et %s\n", myargv[0],myargv[1],myargv[2],myargv[3]);
     
      	dup2(fp[1],1); // redirection
        close(fp[0]);
        close(fp[1]);
      	execvp(argv[1], myargv);
     
        //close(1);
     
    	}
     
    	else{
    		close(fp[1]);
    		// ferme le out du pere
     
        char lu[10240];
     
    		int count = read(fp[0], lu, 10240); // le nombre de byte qui ont été lus
     
        lu[count] = '\0';
    		//int w = write(fp[1], lu, 255); // ecriture dans stdout
        printf("%s\n", lu);
     
    		wait(NULL);
    	    // on fait attendre le processus parent
     
    	}

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    La fermeture manquante n'empêchait pas le programme de fonctionner. Mais bien évidemment il faut la mettre (quand on sort de sa maison, on éteint la lumière).
    Le read du coté [1] était lui le vrai problème.
    Mais moi j'ai une autre définition de "ça marche bien". Parce que tronquer le résultat d'une commande aux 1024 premiers octets qu'elle renvoie c'est assez moyen comme fonctionnement.
    De plus, quand on remplit l'élément [x] d'un tableau, ça impose au tableau d'avoir la place pour au-moins x+1 éléments (hé oui, un tableau commence à 0 !!!). Or toi tu lis 1024 (au plus) caractères que tu stockes dans un tableau de 1024 caractères et tu vas ensuite y rajouter un '\0'. Il se rajoute où ce '\0' ???
    Et franchement t'as vraiment une indentation de chiotte. Ecrire un code C ce n'est pas seulement écrire un code qui fonctionne mais c'est aussi écrire un code qu'on peut lire/relire/modifier facilement. Et ça, ça passe par un code correctement indenté.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 5
    Par défaut
    message passée! merci pour la précision.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par manou1998 Voir le message
    message passée!
    Pas vraiment. Tu as changé "1024" en "10240" dans ton code précédent mais ça ne change rien au fond du problème. Une commande peut très bien renvoyer 20000, 50000, 100000, 1000000000, 10000000000000000000 d'octets. Fatalement il y aura un moment où tu ne pourras pas stocker tout ce qu'elle renvoie.
    Imagine par exemple un script shell de ce type
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/bin/bash
    while true; do
        ls -Rals /
    done
    Et que je demande à ton programme de l'exécuter ???

    Comment on lit un flux d'octets ? De la même façon qu'on lit un fichier: on fait une boucle !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. cleaning process fils avec waitpid() fork exec pselect
    Par thorgal99 dans le forum Réseau
    Réponses: 2
    Dernier message: 19/08/2014, 11h59
  2. exercices languages C
    Par marwane.boughanmi dans le forum Débuter
    Réponses: 2
    Dernier message: 17/01/2011, 23h29
  3. fork() exec et cie..
    Par lylo01 dans le forum Linux
    Réponses: 4
    Dernier message: 04/12/2009, 12h44
  4. fork + exec + mémoire partagée ?
    Par italiasky dans le forum POSIX
    Réponses: 2
    Dernier message: 26/08/2009, 16h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo