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 :

MiniShell - les processus en arrière plan


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 4
    Par défaut MiniShell - les processus en arrière plan
    Bonjour à tous,

    J'écris un MiniShell en C, et j'essaie de rajouter la possibilité de lancer des processus en arrière-plan quand la ligne de commande se termine par le symbole "&".
    Pour l'instant le programme reconnait bien une commande qui se termine par le symbole "&", mais il ne s’exécute pas, par exemple : quand je tape
    , j'obtiens une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    commande = [ls]
    Argument = []
    ls: cannot access '': No such file or directory
    Voici le programme entier : (les processus en arrière processus sont dans les lignes 53 - 58 )
    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
     
    # include <stdio.h>
    # include <stdlib.h>
    # include <unistd.h>
    # include <sys/types.h>
    # include <sys/wait.h>
    # include <assert.h>
    # include <string.h>
     
    enum {
    	MaxLigne = 1024,              // longueur max d'une ligne de commandes
    	MaxMot = MaxLigne / 2,        // nbre max de mot dans la ligne
    	MaxDirs = 100,                // nbre max de repertoire dans PATH
    	MaxPathLength = 512,          // longueur max d'un nom de fichier
    };
     
    void decouper(char *, char *, char **, int);
     
    # define PROMPT "? "
     
    int main(int argc, char * argv[]){
        char ligne[MaxLigne];
        char pathname[MaxPathLength];
        char * mot[MaxMot];
        char * dirs[MaxDirs];
        int i, tmp, bg;
        pid_t pid, pid1; 
        int etat;  
     
     
        decouper(getenv("PATH"), ":", dirs, MaxDirs);
     
        for(printf(PROMPT); fgets(ligne, sizeof ligne, stdin) != 0; printf(PROMPT)){
        	decouper(ligne, " \t\n", mot, MaxMot);
        	for(i = 0; mot[i] != 0 ; i++); // MODIFICATION
        		if (mot[0] == 0) 
        			continue;
     
        	tmp = fork();
     
            // enfant : 
        	if (tmp < 0){
        		perror("fork");
                continue;
                }
     
            // parent :
            if (tmp != 0)
            {
               continue; 
            }
     
             // Background 
            if (*mot[i-1] == '&')
            {
                *mot[i-1] = '\0';
                printf("\ncommande = [%s] \nArgument = [%s]\n", mot[0], mot[1]);
            }
     
            //Execution de la commande : 
            for(i = 0; dirs[i] != 0; i++){
                snprintf(pathname, sizeof pathname, "%s/%s", dirs[i], mot[0]);
                execvp(pathname, mot);
            }
            fprintf(stderr, "%s: not found\n", mot[0]);
            exit(1);
        }
        printf("Bye\n");
        return 0;
    }
     
     
    void decouper(char * ligne, char * separ, char * mot[], int maxmot){
    	int i;
    	mot[0] = strtok(ligne, separ);
    	for(i = 1; mot[i - 1] != 0; i++){
    	 if (i == maxmot){
    	 	fprintf(stderr, "Erreur dans la fonction decouper: trop de mots\n");
    	 	mot[i - 1] = 0;
    	 }
    	 mot[i] = strtok(NULL, separ);
    	}
    }
    Je ne vois pas d'où vient l'erreur, est - ce quelqu'un pourrait éclairer ?

    Bien à vous.

  2. #2
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 258
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 258
    Par défaut
    Tu ne parse pas correctement ta chaine je pense.

    En regardant vite fait ta fonction découper, le séparateur devrait être un espace, et il te faut aussi traiter les guillemets (si un argument est passé entre guillemet le texte contenu entre les guillemets est un argument).
    Tu crée ensuite ton tableau d'argument pour la fonction exec, et met ton processus misnishell en attente sauf si le dernier argument est &. Le test de la présence de cet argument aura du être testé avant et non intégré au tableau d'argument d'exec.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Ton minishell se comporte exactement comme si on tapait ls "" en bash (tente le, tu auras exactement le même message d'erreur). La commande "ls" traite la chaine vide comme un argument ; or il y a une différence entre "pas d'argument" et "argument vide". Je pense qu'en traitant la chaine "ls &" tu as pris en compte le "&" mais laissé l'espace qui a été alors passé à "ls" en tant qu'argument. chrtophe a raison. Je pense aussi que tu devrais traiter le cas spécial "& présent" en le supprimant alors de la string puis ensuite tu retomberais dans le cas normal "traiter la commande et ses arguments éventuels".

    Attention, utiliser sizeof() pour détecter une longueur de tableau est une très mauvaise idée. Tant que le tableau est un tableau ça va, mais si tu déportes le traitement dans une fonction annexe, laquelle reçoit le tableau en paramètre, ce tableau est alors stocké dans un pointeur et sizeof pointeur ça marche moins bien...
    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
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 4
    Par défaut
    Bonjour,

    Merci pour vos explications et suggestions, j'ai finalement réussi à résoudre le problème.


    Bien à vous.

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

Discussions similaires

  1. Lancer un processus en arrière-plan
    Par Morgan7469 dans le forum C#
    Réponses: 10
    Dernier message: 17/03/2011, 14h48
  2. Changer la priorité des processus d'arrière plan Oracle
    Par dcollart dans le forum Administration
    Réponses: 1
    Dernier message: 16/07/2010, 15h22
  3. Lancer sous la console dos un processus en arrière plan.
    Par ziad.shady dans le forum Scripts/Batch
    Réponses: 6
    Dernier message: 25/10/2009, 14h44
  4. Lancer des processus en arrière plan
    Par momeftah dans le forum Shell et commandes GNU
    Réponses: 11
    Dernier message: 01/05/2007, 18h50
  5. 98SE les applis en arrière plan
    Par Speed41 dans le forum Windows 2000/Me/98/95
    Réponses: 3
    Dernier message: 04/01/2007, 17h52

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