simbolo - programa para compilar c++
Ejecutar programa desde dentro de un programa C (6)
Creo que puedes usar
freopen
para esto .
¿Cómo debería ejecutar otro programa desde mi programa C
? Necesito poder escribir datos en STDIN
del programa lanzado (y tal vez leer desde su STDOUT
)
No estoy seguro si esta es una función C estándar. Necesito la solución que debería funcionar bajo Linux.
Puede usar la llamada al sistema, leer la página del manual para el sistema (3)
Hace un tiempo escribí un código C de ejemplo para otra persona que muestra cómo hacerlo. Aquí está para ti:
#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);
}
No estoy de acuerdo con Nathan Fellman; la otra pregunta no es un duplicado de esto, aunque el tema está relacionado.
Para una comunicación unidireccional simple, popen () es una solución decente. Sin embargo, no sirve para la comunicación bidireccional.
IMO, imjorge (Jorge Ferreira) dio la mayoría de la respuesta (¿80%?) Para la comunicación bidireccional, pero omitió algunos detalles clave.
- Es crucial que el proceso principal cierre el extremo de lectura del conducto que se utiliza para enviar mensajes al proceso hijo.
- Es crucial que el proceso secundario cierre el extremo de escritura del conducto que se utiliza para enviar mensajes al proceso secundario.
- Es crucial que el proceso primario cierre el extremo de escritura del conducto que se utiliza para enviar mensajes al proceso padre.
- Es crucial que el proceso secundario cierre el extremo de lectura del conducto que se utiliza para enviar mensajes al proceso padre.
Si no cierra los extremos no utilizados de las tuberías, no obtendrá un comportamiento sensato cuando uno de los programas finalice; por ejemplo, el niño podría estar leyendo desde su entrada estándar, pero a menos que el extremo de escritura de la tubería esté cerrado en el niño, nunca obtendrá EOF (cero bytes de lectura) porque todavía tiene la tubería abierta y el sistema piensa que En algún momento podría escribir sobre ese tubo, aunque actualmente esté colgado esperando que se lea algo de él.
Los procesos de escritura deben considerar si se maneja la señal SIGPIPE que se da cuando se escribe en una tubería donde no hay proceso de lectura.
Debe tener en cuenta la capacidad de la tubería (depende de la plataforma, y puede ser tan poco como 4 KB) y diseñar los programas para evitar un interbloqueo.
- Cree dos tubos con
pipe(...)
, uno parastdin
, uno parastdout
. -
fork(...)
el proceso. - En el proceso secundario (aquel en el que
fork(...)
devuelve 0)dup (...)
las tuberías astdin
/stdout
. -
exec[v][e]
el archivo de programa que se va a iniciar en el proceso hijo. - En el proceso principal (aquel en el que el
fork
) devuelve el PID del niño) haga un ciclo que lea de lastdout
del niño (select(...)
opoll(...)
,read(...)
) en un buffer, hasta que el hijo termina (waitpid(...)
). - Eventualmente, proporcione al niño información sobre
stdin
si espera algo. - Cuando termine,
close(...)
las tuberías.
Quieres usar popen
. Le proporciona una tubería unidireccional con la que puede acceder a stdin y stdout del programa.
popen es estándar en unix moderno y un sistema operativo unix, de los cuales Linux es uno :-)
Tipo
man popen
en una terminal para leer más al respecto.
EDITAR
Si popen
produce tubos unidireccionales o bidireccionales depende de la implementación. En Linux y OpenBSD , popen
produce conductos unidireccionales, que son de solo lectura o de solo escritura. En OS X , FreeBSD y NetBSD popen
producen conductos bidireccionales.