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 :

valeur de retour de la fonction "system" en C


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Par défaut valeur de retour de la fonction "system" en C
    bonjour,

    je développe actuellement sous DOS un programme (prog1) qui doit en appeller un autre (prog2).

    prog1 appelle prog2 à l'aide de la fonction system et agit selon la valeur retournée par 2. Enfin, c'est ce que je voudrais, mais soit je me débrouille mal, soit system ne retourne pas la valeur renvoyée par le programme appelé comme c'est le cas sous les UNIX like. Il semble retourner zéro du moment que l'appel s'est bien passé, et j'ai beau mettre des return(xxxx) (avec xxx>0 !) dans le main de prog2, rien à faire.

    qui peut confirmer ? apparemment les valeurs de retour de system dépendent de l'implémentation.

    Merci par avance.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Citation Envoyé par MSDN
    If command is not NULL, system returns the value that is returned by the command interpreter. It returns the value 0 only if the command interpreter returns the value 0.
    Sous win32, ça devrait retourner le code de retour du processus...
    Sous DOS, je ne sais pas... C'est quelle version?

    Sinon, sous DOS, tu peux essayer les fonctions _spawnxxx en mode _P_WAIT, elles sont supposées fonctionner de façon similaire à system() dans ce mode... (et retourner le code de sortie)
    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.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Par défaut
    Après quelques essais, je ne crois pas que sous Unix la valeur retournée par la fonction system soit égale à celle renvoyée par le programme appelé par system.
    Uniquement si ce dernier renvoie 0, alors system renvoie 0, sinon system retourne une valeur différente, mais toujours la même pour une valeur retournée identique.
    Doit y avoir une explication !

    Quelqu'un ?

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Par défaut
    sous unix, j'ai les deux programmes suivants pour tester :
    test.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    int main(int argc, char **argv) {
    	int ret = 0;
    	char cmd[500];
     
    	sprintf(cmd, "prog %s", argv[1]);
     
    	ret = system(cmd)>>8;
     
    	printf("ret = %d\n", ret);
    }
    et prog.c (le binaire doit s'appeller code)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <stdio.h>
     
    int main(int argc, char **argv) {
    	printf("%s\n", argv[1]);
    	return(atoi(argv[1]));
    }
    et j'ai bien l'impression que system retourne la valeur de retour du main * 256 !! (d'où le >>8 dans mon code)

    mais en tous cas ça marche.

    Médinoc ça ressemble pas mal à la page Man de system sous HP UX. donc effectivement ça devrait retourner les bonnes valeurs !

    J'aurai dû le dire avant mais je suis sous Windows 2000, j'utilise Visual C++ et voici le code du main dont je voudrais récupérer la valeur du return
    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
     
    int main(int argc, char *argv[])
    {
    	int ret = 0;
    	char cmd[256];
     
    	if((ret = getFreeID(argv[2])) < 0)
    		return ret; /* erreur lors de la recherche d'un ID libre, on sort */
     
    	sprintf(cmd, "start C:\\SYS\\PCOM\\pcsws \"%s\" /S=%c", argv[1], ret);
    	/* faire attention à la valeur de retour de system qui dépend de l'implémentation */
    	system(cmd);
     
    	return(ret);
    }
    c'est banal !!! même en testant avec le strict minimum (main(void){return(xxx);}) je n'y arrive pas !

  5. #5
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Dans le man de system() on trouve :
    The system() function forks to create a child process that
    in turn invokes one of the exec family of functions (see
    exec(2)) on the shell to execute string. If fork() or the
    exec function fails, system() returns -1 and sets errno to
    indicate the error.
    Donc, dans le man de exec, on trouve :
    If a function in the exec family returns to the calling pro-
    cess, an error has occurred; the return value is -1 and
    errno is set to indicate the error.
    Donc en gros, si la valeur que tu récupères est -1, alors tu as eu une erreur.

    Mais en aucun cas la valeur retournée n'est celle retournée par l'application en question.

    je ne crois pas qu'il soit possible, de manière portable, d'avoir le code de retour du programme appelé, mais je peux me tromper.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Par défaut
    Citation Envoyé par benhoeil

    et j'ai bien l'impression que system retourne la valeur de retour du main * 256 !! (d'où le >>8 dans mon code)
    même constat de mon côté !

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Par défaut
    Tous d'abords merci beaucoup à tous pour votre aide !

    je viens de trouver. En fait, mon binaire était appelé par la commande start (donc "start binaire") et start retourne zéro si l'exécution s'est bien passée, quelque soit la valeur retournée par binaire d'où mes constatations pas correctes ! On pouvait encore chercher longtemps...

    J'ai retiré le start, et maintenant tout va bien. Je confirme donc ce que dit Médinoc, mais infirme gangsoleil : system renvoie bien la valeur renvoyée par le binaire exécuté, mais le exec du processus fils ne renvoie pas cette valeur directement par un return, plutôt par quelque chose qui a un rapport avec l'utilisation de wait .

    je reprend l'extrait du man de system sous HP-UX:
    If command is not null, system() returns the termination status of the
    command language interpreter in the format specified by wait(2)
    .
    si quelqu'un sait comment est implémenté system...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Ben... Sous les UNIX, il parait qu'il fait bêtement fork/exec/wait (dixit mon prof de système)...

    Sous Windows, je suppose qu'il fait spawn, et que spawn sous Windows fait CreateProcess/WaitForSingleObject...
    Par contre, je ne sais pas comment marchait spawn sous DOS... Je sais seulement que seuls les modes _P_WAIT et _P_OVERLAY marchaient, DOS n'étant pas multitache...

    En tout cas, l'avantage suprème de spawn(n'importe quel programme) sur fork/exec(n'importe quel programme) est qu'on sait immédiatement si la création du nouveau proces a réussi ET s'il elle a échoué, alors qu'avec fork/exec, on a moyen de savoir immédiatement si exec() a échoué, mais pas s'il a réussi... (ou s'il y a un moyen, il doit être rudement bien caché)
    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.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 17
    Par défaut
    ben s'il a réussi c'est si il n'as pas foiré ?

    Sinon tu attend la fin du processus et si le wait retourne qqchose tu peut savoir tout ce qu'il s'est passé.

    Sinon tu n'attend pas la fin et tu surveille son état dans l'ensemble des processus.

  10. #10
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Pour avoir la "vraie" valeur de retour, il faut convertir la valeur retournée par wait() en utilisant la macro WEXITSTATUS() définie dans sys/wait.h.
    Exemple:
    code source du programme appelé par system()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include <stdio.h>
     
    int main(void)
    {
      printf("I've been called!\n");
      return 200;
    }
    code source du programme appelant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
     
    int main(void)
    {
      int t = system("./called");
      t = WEXITSTATUS(t);
      printf("system() returned %d\n", t);
     
      return 0;
    }
    Le résultat est bien celui escompté:
    I've been called!
    system() returned 200
    - cela a été testé sous Unix. Les choses sont sans doute différentes sous Windows (quoique wait() est POSIX.1)
    - contrairement à l'intuition, la plage de valeur que l'on peut renvoyer est celle d'un unsigned char (0..255) et non d'un int.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Citation Envoyé par Cunixsvp
    ben s'il a réussi c'est si il n'as pas foiré ?

    Sinon tu attend la fin du processus et si le wait retourne qqchose tu peut savoir tout ce qu'il s'est passé.

    Sinon tu n'attend pas la fin et tu surveille son état dans l'ensemble des processus.
    Justement! Si tu veux faire un fork/exec sans attendre la fin du processus, le père n'a aucun moyen de savoir si le fils a correctement chargé le nouveau programme avant la fin de celui-ci!
    (par contre, si exec() a échoué, le fils peut toujours prévenir le père qu'il a foiré. Mais s'il réussi, aucun moyen.

    _spawn par contre, répond directement si le nouveau programme a été correctement chargé ou non. Comme CreateProcess(), d'ailleurs (à certaines erreurs bien précises près)
    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.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Par défaut
    Médinoc, qu'est-ce qui empêcherait le fils d'envoyer un message au père dès qu'il vient d'être créé, par exemple avec un pipe ?

    Si le père reçoit un message dans le pipe, c'est forcément de son fils, et donc c'est que le fork a bien réussi non ?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Le fils lui-même le peut AVANT l'appel à exec(), mais j'ai dis charger N'IMPORTE QUEL PROGRAMME, c'est-à-dire un programme qui n'a pas été développé par toi (un jeu vidéo, par exemple). Donc, un programme qui ne connait aucun protocole pour communiquer avec le père.
    Puisque seul le fils peut communiquer avec le père "de son vivant", le père ne peut recevoir un message du fils que si le exec() échoue, ou quand le processus chargé par le fils se termine (donc pas "de son vivant")

    Donc, je ne te contredis pas sur le fait que le père a tous les moyens de savoir si le fork() a réussi. Mais il n'en a aucun pour savoir si le exec() a réussi avant la fin du processus fils.
    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.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 17
    Par défaut
    Hum tu réfléchie trop vite, voila une solution :

    Le pere se souviens du pid du fils, donc a tout moment il peut regarder l'état du fils ( zombie, execution, stopped .... ) ainsi que la mémoire consommé et le cpu utiliser .

    Je ne vois pas en quoi il n'as pas accès à l'état du fils.

    édit : pour t'en convaincre fait un programme qui watch tous ses fils et qui donnent l'état de ceux ci lors d'une modification, et envoie des signaux aux hazard sur tout tes fils. Mirable le pere te dira que le fils viens de se prendre un SIGKILL ou un SIGSTOP dans la gueule .

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Il détecte qu'un fils a réussi un exec() ?
    Parce que pour l'instant, le seul moyen de le savoir, c'est "Ah, il ne s'est pas terminé alors que je l'ai lançé il y a deux secondes? Bon, il a du réussir son exec()..."
    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.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 18/09/2006, 14h17
  2. Réponses: 2
    Dernier message: 11/05/2006, 18h41
  3. Pourquoi une seule valeur de retour pour les fonctions ?
    Par Bruno75 dans le forum Langages de programmation
    Réponses: 33
    Dernier message: 18/01/2004, 13h58

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