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);
}
- Créer deux canaux avec
pipe(...)
, un pourstdin
, un pourstdout
. fork(...)
le processus.- Dans le processus enfant (celui où
fork(...)
renvoie 0)dup (...)
les tuyaux àstdin
/stdout
. exec[v][e]
le fichier de programme à démarrer dans le processus enfant.- Dans le processus parent (celui où
fork
) renvoie le PID de l'enfant) faire une boucle qui lit à partir dustdout
de l'enfant (select(...)
oupoll(...)
,read(...)
) dans un tampon, jusqu'à ce que l'enfant se termine (waitpid(...)
). - Finalement fournir à l'enfant une entrée sur
stdin
s'il en attend. - Une fois terminé
close(...)
les tuyaux.