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

POSIX C Discussion :

Utilisation de popen


Sujet :

POSIX C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 126
    Points : 58
    Points
    58
    Par défaut Utilisation de popen
    Bonsoir a tous voila, j aimerai savoir a koi sert exactement la fonction popen et si elle est utilisable sous windows car je pense qu'elle pourrai mettre utille pour mon programme mais je ne sais comment l'utilise (je debute en c).Je me suis bien evidament referencer a man page mais leur explication est sans nul doute un peu trop technique pour un debutant comme moi. Si c'etait possible d'avoir un petit exemple ou meme un prototype de la fonction assez simple se serai tres sympa merci d'avance

  2. #2
    Membre régulier Avatar de yakamoneye
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 122
    Points
    122
    Par défaut
    POPEN(3) Manuel du programmeur Linux POPEN(3)

    NOM
    popen, pclose - Entrées-sorties pour un processus

    SYNOPSIS
    #include <stdio.h>

    FILE *popen (const char *commande, const char *type);

    int pclose (FILE *stream);

    DESCRIPTION
    La fonction popen() engendre un processus en créant un tube (pipe), exécutant un fork(2), et en invoquant le shell.
    Comme un tube est unidirectionnel par définition, l’argument type doit indiquer seulement une lecture ou une écriture,
    et non pas les deux. Le flux correspondant sera ouvert en lecture seule ou écriture seule.

    L’argument commande est un pointeur sur une chaîne de caractères, terminée par un octet nul, et contenant une ligne de
    commande shell. Cette commande est transmise à /bin/sh en utilisant l’option -c. L’interprétation en est laissée au
    shell.

    L’argument type est un pointeur sur une chaîne de caractères, terminée par un octet nul, qui doit contenir « r » pour
    la lecture ou « w » pour l’écriture.

    La valeur renvoyée par popen() est un flux d’entrée-sortie normal, à la seule différence qu’il doit être fermé en
    appelant pclose() à la place de fclose(3). L’écriture dans le flux correspond à écrire sur l’entrée standard de la
    commande. Le flux de sortie standard de la commande est le même que celui du processus appelant popen(), à moins que
    la commande le modifie. Symétriquement, la lecture depuis un flux ouvert par popen() correspond à lire la sortie stan-
    dard de la commande, et dans ce cas l’entrée standard de la commande est la même que celle du processus appelant
    popen().

    Notez que, par défaut, les flux de sortie fournis par popen() disposent d’un tampon.

    La fonction pclose() attend que le processus correspondant se termine, et renvoie alors l’état de sortie de la com-
    mande, comme en utilisant wait4(2).

    VALEUR RENVOYÉE
    La fonction popen() renvoie NULL si l’appel système fork(2) ou pipe(2) échoue, ou s’il n’a pas assez de mémoire.

    La fonction pclose() renvoie -1 si wait4(2) échoue, ou si une autre erreur est détectée.

    ERREURS
    La fonction popen() ne remplit pas errno si une allocation mémoire échoue. Si les appels fork(2) ou pipe(2) sous-
    jacents échouent, errno est correctement rempli. Si l’argument type est invalide, et si cette condition est détectée,
    errno contient EINVAL.

    Si pclose() n’arrive pas à obtenir l’état du fils, errno contient ECHILD.


    Pourquoi les pierres carrées font elles des ronds dans l'eau ?

  3. #3
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    popen est une fonction POSIX qui permet de créer un tube, d'exécuter une commande (exactement comme ce qui se passe avec la fonction system) et de rediriger l'entrée et/ou les sorties standard de cette commande vers le tube ainsi créé. Comme certainement ton problème n'est pas son lien avec le thread que t'as créé sur le forum Programmation Windows, je suppose que tu est sous Windows et dans ce cas, tu devrais plutôt utiliser la fonction _popen (qui est popen qui a changé de nom sous Windows), conformément aux recommandations de Microsoft.

    PS: Toutes les fonctions non standard (ANSI C) de la bibliothèque d'exécution du C de Microsoft commencent par un underscore (_). Cela permet de savoir immédiatement si une fonction est standard ou nom rien qu'en regardant son nom. Il y a peut-être quelques exceptions.

  4. #4
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Melem Voir le message
    Comme certainement ton problème n'est pas sans lien avec le thread que t'as créé sur le forum Programmation Windows, je suppose que tu est sous Windows et dans ce cas, tu devrais plutôt utiliser la fonction _popen (qui est popen qui a changé de nom sous Windows), conformément aux recommandations de Microsoft.
    Seulement s'il utilise les fonctions Windows, il peut très bien se tourner vers cygwin et disposer de popen() normalement.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Melem Voir le message
    rediriger l'entrée et/ou les sorties standard
    Pas "et/ou", hélas. C'est "ou", un "ou" tout ce qu'il y a de plus exclusif. On ne peut pas rediriger à la fois l'entrée et la sortie standard avec popen().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pas "et/ou", hélas. C'est "ou", un "ou" tout ce qu'il y a de plus exclusif. On ne peut pas rediriger à la fois l'entrée et la sortie standard avec popen().
    Ah oui c'est vrai, un tube c'est toujours à sens unique.

  7. #7
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Melem Voir le message
    Ah oui c'est vrai, un tube c'est toujours à sens unique.
    Même remarque : http://www.developpez.net/forums/sho...8&postcount=12
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  8. #8
    Nouveau membre du Club
    Inscrit en
    Décembre 2006
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 37
    Points : 28
    Points
    28
    Par défaut
    pour redirriger à la fois stdin, stdout et stderr d'un process, il faut faire :


    sous unix/linux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int stdin_fd[2]  = { -1, -1 };
    int stdout_fd[2] = { -1, -1 };
    int stderr_fd[2] = { -1, -1 };
    pipe( stdin_fd );
    pipe( stdout_fd );
    pipe( stderr_fd );
    fork();
    dans le processus fils:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    close( stdin_fd[1] );
    			close( stdout_fd[0] );
    			close( stderr_fd[0] );
    			dup2( stdin_fd[0],	fileno( stdin ) );
    			dup2( stdout_fd[1], fileno( stdout ) );
    			dup2( stderr_fd[1], fileno( stderr ) );
     
                            ...
                            exécuter le process
    dans le père:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    close( stdin_fd[0] );
    			close( stdout_fd[1] );
    			close( stderr_fd[1] )
     
                            ...
                          //  puis se mettre en attente de la fin du processus fils 
                            //avec wait() ou waitpid()
    sous windows:
    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
    PROCESS_INFORMATION	piProcessInfo;
    	SECURITY_ATTRIBUTES sa_attr; 
    	HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, hChildStderrRd, hChildStderrWr;
     
    	// Set the bInheritHandle flag so pipe handles are inherited. 
    	sa_attr.nLength              = sizeof( SECURITY_ATTRIBUTES ); 
    	sa_attr.bInheritHandle       = TRUE; 
    	sa_attr.lpSecurityDescriptor = NULL; 
     
     
    	// Create a pipe for the child process's STDERR. 
     	CreatePipe( &hChildStderrRd, &hChildStderrWr, &sa_attr, 0 );
     
    	// Ensure that the read handle to the child process's pipe for STDOUT is not inherited.
    	SetHandleInformation( hChildStderrRd, HANDLE_FLAG_INHERIT, 0 );
     
     
    	// Create a pipe for the child process's STDOUT. 
     	CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &sa_attr, 0 );
    	// Ensure that the read handle to the child process's pipe for STDOUT is not inherited.
    	SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0 );
     
     
    	// Create a pipe for the child process's STDIN. 
            CreatePipe( &hChildStdinRd, &hChildStdinWr, &sa_attr, 0 );
    	// Ensure that the write handle to the child process's pipe for STDIN is not inherited. 
            SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0 );
     
     
    	// Startup information.
    	STARTUPINFO  siStartupInfo;
    	FWK_System::bzero( (FWK_Byte *) &siStartupInfo, sizeof( siStartupInfo ) );
    	siStartupInfo.cb         = sizeof( STARTUPINFO ); 
    	siStartupInfo.hStdError  = hChildStderrWr;
    	siStartupInfo.hStdOutput = hChildStdoutWr;
    	siStartupInfo.hStdInput  = hChildStdinRd;
    	siStartupInfo.dwFlags   |= STARTF_USESTDHANDLES;
     
    	// Launch the process.
    	BOOL status = CreateProcess( path.to_char(),
    							     cmd_line.to_char(),0,0,FALSE,
    								 CREATE_DEFAULT_ERROR_MODE,0,0,                              
    								 &siStartupInfo, &piProcessInfo );


    puis jouer avec WaitForSingleObject( process->_pid.hProcess, INFINITE ) et GetExitCodeProcess( process->_pid.hProcess, &cr ) pour attendre la fin du processus exécuté

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/12/2015, 08h15
  2. Utilisation de os.system ou subprocess.Popen
    Par othke dans le forum Général Python
    Réponses: 8
    Dernier message: 28/09/2011, 12h05
  3. Réponses: 5
    Dernier message: 16/02/2011, 10h23
  4. popen comment utiliser!
    Par laracroft87 dans le forum Linux
    Réponses: 1
    Dernier message: 05/04/2009, 11h46
  5. Programme avec processes et utilisation de popen
    Par Johan.Mazel dans le forum Général Python
    Réponses: 12
    Dernier message: 28/03/2008, 18h47

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