GNU/Linux >> Tutoriels Linux >  >> Linux

Exécuter le programme à partir d'un programme C

Vous souhaitez utiliser popen . Il vous donne un tube unidirectionnel avec lequel vous pouvez accéder à stdin et stdout du programme.

popen est standard sur les systèmes d'exploitation modernes Unix et de type Unix, dont Linux fait partie :-)

Saisissez

man popen

dans un terminal pour en savoir plus à ce sujet.

MODIFIER

Que ce soit popen produit des tuyaux unidirectionnels ou bidirectionnels dépend de l'implémentation. Sous Linux et OpenBSD, popen produit des canaux unidirectionnels, qui sont en lecture seule ou en écriture seule. Sous OS X, FreeBSD et NetBSD popen produit des tuyaux bidirectionnels.


J'ai écrit un exemple de code C pour quelqu'un d'autre il y a quelque temps qui montre comment faire cela. Le voici pour vous :

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

void error(char *s);
char *data = "Some input data\n";

main()
{
  int in[2], out[2], n, pid;
  char buf[255];

  /* In a pipe, xx[0] is for reading, xx[1] is for writing */
  if (pipe(in) < 0) error("pipe in");
  if (pipe(out) < 0) error("pipe out");

  if ((pid=fork()) == 0) {
    /* This is the child process */

    /* Close stdin, stdout, stderr */
    close(0);
    close(1);
    close(2);
    /* make our pipes, our new stdin,stdout and stderr */
    dup2(in[0],0);
    dup2(out[1],1);
    dup2(out[1],2);

    /* Close the other ends of the pipes that the parent will use, because if
     * we leave these open in the child, the child/parent will not get an EOF
     * when the parent/child closes their end of the pipe.
     */
    close(in[1]);
    close(out[0]);

    /* Over-write the child process with the hexdump binary */
    execl("/usr/bin/hexdump", "hexdump", "-C", (char *)NULL);
    error("Could not exec hexdump");
  }

  printf("Spawned 'hexdump -C' as a child process at pid %d\n", pid);

  /* This is the parent process */
  /* Close the pipe ends that the child uses to read from / write to so
   * the when we close the others, an EOF will be transmitted properly.
   */
  close(in[0]);
  close(out[1]);

  printf("<- %s", data);
  /* Write some data to the childs input */
  write(in[1], data, strlen(data));

  /* Because of the small amount of data, the child may block unless we
   * close it's input stream. This sends an EOF to the child on it's
   * stdin.
   */
  close(in[1]);

  /* Read back any output */
  n = read(out[0], buf, 250);
  buf[n] = 0;
  printf("-> %s",buf);
  exit(0);
}

void error(char *s)
{
  perror(s);
  exit(1);
}

  1. Créer deux canaux avec pipe(...) , un pour stdin , un pour stdout .
  2. fork(...) le processus.
  3. Dans le processus enfant (celui où fork(...) renvoie 0) dup (...) les tuyaux à stdin /stdout .
  4. exec[v][e] le fichier de programme à démarrer dans le processus enfant.
  5. Dans le processus parent (celui où fork ) renvoie le PID de l'enfant) faire une boucle qui lit à partir du stdout de l'enfant (select(...) ou poll(...) , read(...) ) dans un tampon, jusqu'à ce que l'enfant se termine (waitpid(...) ).
  6. Finalement fournir à l'enfant une entrée sur stdin s'il en attend.
  7. Une fois terminé close(...) les tuyaux.

Linux
  1. Envoyer une entrée à une session d'écran depuis l'extérieur ?

  2. Comment rendre un programme exécutable de partout ?

  3. Exécuter des scripts Perl/PHP à partir de la ligne de commande

  4. Comment puis-je extraire un seul bloc d'octets d'un fichier ?

  5. Comment obtenir la valeur de retour de CHILD PROCESS ?

Programmer le matériel à partir de la ligne de commande Linux

Comment installer un programme à partir de la source sous Linux

Appeler une fonction de l'espace utilisateur à partir d'un module du noyau Linux

Comment exécuter un script Python à partir de Java ?

Comment obtenir un processus enfant à partir d'un processus parent

matlab exécute le script à partir de la ligne de commande linux