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

Biblioth�ques, syst�mes et outils C Discussion :

Probleme fonction readline et pipe


Sujet :

Biblioth�ques, syst�mes et outils C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2019
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : F�vrier 2019
    Messages : 4
    Par d�faut Probleme fonction readline et pipe
    Bonjour a tous !

    Je suis actuellement entrain de commencer a recoder un minishell, j ai actuellement un gros probleme avec l implantation de la fonction readline avec mon simple pipe, en effet bizarrement le pipe yes | head fonctionne parfaitement, par contre ls | wc -l ne m affiche absolument rien sur la sortie standard, par contre la commande pwd | grep "test" fonctionne mais m affiche le resultat directement apres mon prompt ce qui est plutot bizzare car j attends la fin de tout mes processus fils avant de reappeller readline et donc d afficher le prompt

    J ai l impression que readline modifie mon fd stdin car si je n utilise pas la fonction et que je remplace les in_put de readline par la commande direct par exemple in_put = "ls | wc -l", le pipe m affiche bien le bon resultat, j ai pense reset stdin avec l appel a readline mais cela ne fonctionne pas non plus, auriez vous donc une idee de ce qui cloche svp ?

    Voici la partie du code qui nous interesse:

    main.c:
    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
    int	main(int argc, char **argv, char **envp)
    {
    	char	*prompt;
    	char	*in_put;
    	int	is_alive;
    	int status;
    int oldstdin;
    	int oldstdout;
     
    	argc = (int) argc;
    	argv = (char **)argv;
    	envp = (char **) envp;
    	prompt = ">$";
    	is_alive = 1;
    	while (is_alive)
    	{
    		in_put = readline(prompt);
    		add_history(in_put);
                   dup2(oldstdin, STDIN_FILENO);
    		dup2(oldstdout, STDOUT_FILENO);
    		if (!run_pipe(in_put, envp))
    			return (1);
    		waitpid(-1, &status, 0);
    	}
    return (0);
    }
    pipex.c:

    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
    95
    96
    97
    98
    char	**make_cmd(char *one_string_cmd, char **envp)
    {
    	char	**cmd;
    	char	*tempo_cmd;
    	size_t	i;
     
    	cmd = ft_split(one_string_cmd, ' ');
    	if (!cmd)
    		return (NULL);
    	tempo_cmd = format_string(cmd);
    	if (!tempo_cmd)
    		return (NULL);
    	cmd[0] = tempo_cmd;
    	i = 0;
    	while (envp[i] && ft_strncmp(envp[i], "PATH=", 5) != 0)
    		++i;
    	tempo_cmd = find_path(envp, cmd, i);
    	if (!tempo_cmd)
    		return (NULL);
    	cmd[0] = tempo_cmd;
    	return (cmd);
    }
    void	receiver(char *input_cmd, char **envp, int *pipe_fd, size_t num_proc, size_t pipes_nb)
    {
    	char	**cmd;
     
    	//verif make cmd
    	cmd = make_cmd(input_cmd, envp);
    	pipes_nb = (size_t) pipes_nb;
    	num_proc = (size_t) num_proc;
     
    		close(pipe_fd[1]);
    		dup2(pipe_fd[0], 0);
    		close(pipe_fd[0]);
    	execve(cmd[0], cmd, envp);
    	//verif execve
    }
    void	sender(char *input_cmd, char **envp, int *pipe_fd, size_t num_proc, size_t pipes_nb)
    {
    	char	**cmd;
     
    	//verif make cmd
    	cmd = make_cmd(input_cmd, envp);
    	pipes_nb = (size_t) pipes_nb;
    	num_proc = (size_t) num_proc;
     
    		close(pipe_fd[0]);
    		dup2(pipe_fd[1], 1);
    		close(pipe_fd[1]);
    	execve(cmd[0], cmd, envp);
    	//verif execve
    }
     
    int	run_pipe(char *in_put, char **envp)
    {
    	size_t	i;
    	size_t	pipes_nb;
    	pid_t	pid;
    	char	**cmds;
    	int	pipes_fd[2];
     
    	i = 0;
    	pipes_nb = 0;
    	while (*(in_put + i))
    	{
    		if (*(in_put + i) == '|')
    			++pipes_nb;
    		++i;
    	}
    	cmds = ft_split(in_put, '|');
    	envp = (char **) envp;
     
    	if (pipe(pipes_fd) == -1)
    	{
    		printf("Erreur init pipe\n");
    		return (0);
    	}
     
    	i = 0;
    	while (i < pipes_nb + 1)
    	{
    		pid = fork();
    		if (pid < 0)
    		{
    			perror("Probleme fork");
    			return(0);
    		}
    		else if (pid == 0)
    		{
    			if (i == 0)
    				sender(cmds[i], envp, pipes_fd, i, pipes_nb);
    			else
    				receiver(cmds[i], envp, pipes_fd, i, pipes_nb);
    		}
    		++i;
    	}
    	return (1);
    }
    Je tiens a preciser que j ai teste le formattage des commandes envoye a execve et que je n ai trouve aucuns soucis par rapport a ca

    Voila a toute !

  2. #2
    R�dacteur/Mod�rateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    D�cembre 2011
    Messages
    4 173
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : D�cembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par d�faut
    Citation Envoy� par RickSanchez Voir le message
    auriez-vous donc une id�e de ce qui cloche SVP ?
    Bonjour ! L�, comme �a, malheureusement non. Si vous pouviez poster le projet complet, en pr�cisant comment vous le compilez, et quelles manipulations vous faites ensuite, il serait plus facile de vous aider (pour moi en tout cas).

    Bon courage pour la suite.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2019
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : F�vrier 2019
    Messages : 4
    Par d�faut
    Bonjour !

    Tout d abord merci Roland Chastain pour avoir pris le temps de t interesser a mon probleme

    Voici le code complet qui est sur github: https://github.com/UhtredTheDane/min...he/tree/master

    J ai tente de resoudre le probleme par moi meme aujourd hui mais sa a ete infructueux mais j ai pu effectuer certains tests.

    Quand j indique EOF a la fonction readline le resultat de mon simple pipe s affiche, pareil si je supprime ma boucle infinie avec la variable is_alive le resultat s affiche bien.

    J ai l impression readline ne me rend pas correctement stdin pourtant j ai tente d enregistrer l etat de mon stdin avec un dup avant d executer readline puis de restaurer avec dup2 mais cela ne change rien

    Cordialement.

  4. #4
    R�dacteur/Mod�rateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    D�cembre 2011
    Messages
    4 173
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : D�cembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par d�faut
    J'ai t�l�charg� le projet et j'ai pu le compiler.

    Pourriez-vous donner un ou plusieurs exemples de commandes qui ne donnent pas le r�sultat attendu ?

    Pour le moment j'ai essay� ls et exit. Ni l'un ni l'autre n'ont fonctionn�.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2019
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : F�vrier 2019
    Messages : 4
    Par d�faut
    Oui j'ai simplifi� au maximun, on ne peut rentrer que un pipe, par exemple yes | head qui fonctionne mais par exemple ls | wc -l ne fonctionne pas.

    Modif: Avec les commandes pwd | grep mini ou cat Makefile | grep S sa fonctionne mais le prompt est affich� avant les resultats j'ai l'impression que le processus pere n 'attend pas la terminaison de tout ces fils avec waitpid(-1, &status, 0);

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    F�vrier 2006
    Messages
    12 841
    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 841
    Billets dans le blog
    1
    Par d�faut
    Bonjour
    Citation Envoy� par RickSanchez Voir le message
    Je suis actuellement entrain de commencer a recoder un minishell
    D�j� avant de voir le pourquoi des erreurs, on peut commencer � voir ce qui ne va pas dans ton code...
    Citation Envoy� par RickSanchez Voir le message
    Code c : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    argc = (int) argc;
    argv = (char **)argv;
    envp = (char **) envp;
    Jusque l�, rien que de tr�s normal. Tu aurais d� rajouter aussi status=(int) status et is_alive=(int) is_alive pour plus de s�ret�...

    Citation Envoy� par RickSanchez Voir le message
    Code c : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    is_alive = 1;
    while (is_alive)
    C'est voulu (utile) cette variable qui ne varie jamais???

    Citation Envoy� par RickSanchez Voir le message
    return (cmd)
    Pas de parenth�ses ni au return (ce n'est pas une fonction), ni � la variable (ce n'est pas non plus une expression faisant intervenir des op�rateurs de priorit�s diff�rentes et n�cessitant de modifier explicitement ces priorit�s). C'est peut-�tre pinailler mais quand on en est � vouloir recoder un minishell, on est en droit d'attendre de toi un code professionnel.

    Citation Envoy� par RickSanchez Voir le message
    Code c : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    while (*(in_put + i))
    	{
    		if (*(in_put + i) == '|')
    Manifestement tu aimes bien indenter pour rien mais ce n'est pas le plus important. Ce qui est important, c'est qu'�crire *(in_put + i) n'est absolument pas plus efficace qu'�crire in_put[i], et bien moins lisible. Or �crire du code lisible aide � sa relecture.
    Oui passer par un pointeur est plus rapide que passer par la notation indic�e, mais uniquement quand le pointeur est d�j� positionn� sur la bonne case. S'il faut lui appliquer un calcul, cela perd alors tout l'avantage d'utiliser un pointeur et �a devient alors exactement la m�me chose qu'un indice (qui n'est qu'un d�calage dans un tableau). Et �a peut m�me �tre pire car avec la notation indic�e, le compilateur peut arriver � trouver des optimisations (en rempla�ant par exemple de lui-m�me l'indice par un pointeur), ce qu'il ne fera pas dans le cas de ce pointeur que tu d�cales. Donc *(in_put + i) c'est soit pareil que in_put[i], soit pire...
    Code c : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    for (char* pt=in_put; *pt != '\0'; pt++) {
    	if (*pt == '|') ++pipes_nb;
    }

    Citation Envoy� par RickSanchez Voir le message
    Code c : 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
    i = 0;
    	while (i < pipes_nb + 1)
    	{
    		pid = fork();
    		if (pid < 0)
    		{
    			perror("Probleme fork");
    			return(0);
    		}
    		else if (pid == 0)
    		{
    			if (i == 0)
    				sender(cmds[i], envp, pipes_fd, i, pipes_nb);
    			else
    				receiver(cmds[i], envp, pipes_fd, i, pipes_nb);
    		}
    		++i;
    }
    L� aussi indentation pareillement inutile de ce qui aurait pu �tre une simple boucle for(). Mais ce qui me pr�occupe vraiment (en dehors aussi de ces parenth�ses l� encore inutiles ainsi que ce "else" qui l'est tout autant), c'est le fait que le fils, une fois cr��, se mette lui-aussi � continuer la boucle (ben oui, je ne vois pas d'instruction pour l'arr�ter). Ca ressemble assez � une fork-bomb. Ok sender et receiver font du execve ce qui substitue le fils par le programme ex�cut� mais (l� j'ai un flou) je me demande si c'est suffisant. A voir si rajouter un exit() qui, pour l'occasion, serait vraiment s�curitaire.
    Et while (i < pipes_nb + 1) s�rieux??? => while (i <= pipes_nb) !!!

    Citation Envoy� par RickSanchez Voir le message
    Code c : 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
    void	receiver(char *input_cmd, char **envp, int *pipe_fd, size_t num_proc, size_t pipes_nb)
    {
    	char	**cmd;
     
    	//verif make cmd
    	cmd = make_cmd(input_cmd, envp);
    	pipes_nb = (size_t) pipes_nb;
    	num_proc = (size_t) num_proc;
     
    		close(pipe_fd[1]);
    		dup2(pipe_fd[0], 0);
    		close(pipe_fd[0]);
    	execve(cmd[0], cmd, envp);
    	//verif execve
    }
    void	sender(char *input_cmd, char **envp, int *pipe_fd, size_t num_proc, size_t pipes_nb)
    {
    	char	**cmd;
     
    	//verif make cmd
    	cmd = make_cmd(input_cmd, envp);
    	pipes_nb = (size_t) pipes_nb;
    	num_proc = (size_t) num_proc;
     
    		close(pipe_fd[0]);
    		dup2(pipe_fd[1], 1);
    		close(pipe_fd[1]);
    	execve(cmd[0], cmd, envp);
    	//verif execve
    }
    Ah, on retrouve avec plaisir ces pipes_nb = (size_t) pipes_nb et num_proc = (size_t) num_proc tellement utiles (sait-on jamais, si les valeurs changeaient par magie entre temps... ). Mis � part, tu ne trouves pas que ces fonctions sont redoutablement similaires et pourraient �tre mutualis�es selon le num_proc. Cela �viterait ainsi de tester i==0 dans la boucle pr�c�dente...

    Code c : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void action(char *input_cmd, char **envp, int *pipe_fd, size_t num_proc, size_t pipes_nb) {
    	char	**cmd;
     
    	//verif make cmd
     
    	cmd = make_cmd(input_cmd, envp);
    	int sens=num_proc > 0 ?0 :1;
     
    	close(pipe_fd[1-sens]);
    	dup2(pipe_fd[sens], sens);
    	close(pipe_fd[sens]);
    	execve(cmd[0], cmd, envp);
    	//verif execve
    }

    Et la boucle pr�c�dente
    Code c : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for (i=0; i <= nb_pipes; i++) {
    	pid = fork();
    	if (pid < 0) {
    		// Erreur de fork
    		perror("Probleme fork");
    		return -1;		// Conventionnellement, un code d'erreur système doit être de valeur inférieure à 0...
    	}
    	if (pid == 0) {
    		// Fils
    		action(cmds[i], envp, pipes_fd, i, pipes_nb);
    		exit(0);
    	}
    }
    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]

Discussions similaires

  1. [XSL]Probleme fonction recursive
    Par Le-Cortex dans le forum XSL/XSLT/XPATH
    R�ponses: 9
    Dernier message: 12/12/2005, 15h10
  2. [Mail] Probleme fonction mail()
    Par tissot dans le forum Langage
    R�ponses: 1
    Dernier message: 14/11/2005, 12h55
  3. problème fonctions callback
    Par youp_db dans le forum GTK+ avec C & C++
    R�ponses: 1
    Dernier message: 02/10/2005, 14h47
  4. probleme fonction gethostbyname
    Par oclone dans le forum D�veloppement
    R�ponses: 6
    Dernier message: 14/04/2005, 10h31
  5. probleme fonction syntaxe
    Par gIch dans le forum G�n�ral JavaScript
    R�ponses: 8
    Dernier message: 28/02/2005, 09h52

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