Récupérer le résultat d’une commande système depuis un programme C

En C, il arrive qu’on utilise la fonction system() pour appeler des commandes systèmes. Lors de son utilisation, notre programme est suspendu et le programme passé en paramètre est exécuté par le shell. Quand il a terminé, l’exécution de notre programme reprend. Vous trouverez des détails sur cette fonction dans les man pages. On peut utiliser system() pour « voir le résultat » d’une commande car la sortie standard du programme est défaut redirigirée vers celle de notre programme. Prenons par exemple le code suivant pour afficher le dossier courant :

#include <stdlib.h>

int main(void)
{
	system("pwd");
	return EXIT_SUCCESS;
}

Dans mon cas, il affiche :

/Users/pierregradot/Documents/workspace-luna/Developpez

Très bien. Mais comment procéder pour réellement récupérer le dossier courant dans une chaine de caractères utilisable dans la suite de notre programme ? La solution est de « remplacer » system() par popen(). Les détails sur cette fonction sont eux aussi donnés par les man pages (normal). Plutôt que de simplement exécuter le programme donné en paramètre comme le fait system(), popen() va bien plus loin : il fait un fork, crée un pipe et invoque le shell pour exécuter le programme souhaité. On récupère alors un descripteur FILE* pour communiquer avec ce programme. Dans le cas de pwd, on peut lire le nom du fichier courant puisque c’est ce qu’il écrit sur la sortie standard (et donc ici, dans le pipe). Ce descripteur peut / doit être refermé à l’aide de pclose(). Voici un exemple simple d’utilisation :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN		512

int main(void)
{
	FILE * f = popen("pwd", "r");

	char pwd[MAX_LEN] = {0};
	fgets(pwd, MAX_LEN, f);
	printf("Current folder is %s\n", pwd);

	pclose(f);
	return EXIT_SUCCESS;
}

Vous vous doutez sans doute de ce qu’il affiche :

Current folder is /Users/pierregradot/Documents/workspace-luna/Developpez

Sous Windows, on utilisera _popen() à la place. La documentation et un exemple sont donnés sur MSDNA.

Publicités

2 Réponses

  1. Mauvais exemple: la fonction getcwd fait ça sans avoir besoin de tout ce bazar :o)
    http://linux.die.net/man/3/getcwd

    J'aime

    5 janvier 2015 à 8:44

    • Pas chiant le mec ! Il fallait un exemple simple…. et je ne connaissais pas getcwd() de toute façon XD Pour être honnête, je connais peu le contenu de unistd.h. Je viens de regarder vite le contenu de io.h (qui est inclus par unistd.h), il y a des trucs mal pour remplacer des choses telle que system(« pwd »), comme mkdir() ou chdir().

      J'aime

      12 janvier 2015 à 2:20

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s