GNU/Linux >> Linux Esercitazione >  >> Linux

Esegue il programma dall'interno di un programma C

Vuoi usare popen . Ti fornisce una pipe unidirezionale con la quale puoi accedere a stdin e stdout del programma.

popen è standard sui moderni sistemi operativi unix e unix-like, di cui Linux è uno :-)

Digita

man popen

in un terminale per saperne di più.

MODIFICA

Se popen produce tubi unidirezionali o bidirezionali dipende dall'implementazione. In Linux e OpenBSD, popen produce pipe unidirezionali, che sono di sola lettura o di sola scrittura. Su OS X, FreeBSD e NetBSD popen produce tubi bidirezionali.


Qualche tempo fa ho scritto un codice C di esempio per qualcun altro che mostra come farlo. Eccolo per te:

#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. Crea due pipe con pipe(...) , uno per stdin , uno per stdout .
  2. fork(...) il processo.
  3. Nel processo figlio (quello in cui fork(...) restituisce 0) dup (...) le pipe a stdin /stdout .
  4. exec[v][e] il file del programma da avviare nel processo figlio.
  5. Nel processo padre (quello in cui fork ) restituisce il PID del figlio) esegue un ciclo che legge dal stdout del figlio (select(...) o poll(...) , read(...) ) in un buffer, finché il figlio non termina (waitpid(...) ).
  6. Alla fine fornisci al bambino l'input su stdin se ne aspetta.
  7. Al termine close(...) i tubi.

Linux
  1. Ottieni il percorso completo da Bash Script?

  2. Impedire a Signt di raggiungere i processi figlio?

  3. Esegui i comandi della shell dal programma in esecuzione in WINE

  4. È sicuro eseguire il fork dall'interno di un thread?

  5. Chiama una funzione dello spazio utente dall'interno di un modulo del kernel Linux

Programma hardware dalla riga di comando di Linux

Come installare un programma da Source su Linux

Esegue lo script bash dall'URL

Come trovare il percorso completo del programma C++ Linux dall'interno?

Come ottenere l'output da gdb.execute in PythonGDB (GDB 7.1)?

Come eseguire lo script Python da Java?