Buenas a todos os voy a enseñar una aplicación escrita en C para sistemas UNIX. Espero que pueda servir como referencia a la hora de manejar procesos hijos y tuberías.
Lo que hace fundamentalmente es:
El proceso padre crea dos procesos hijos. El proceso padre recoge lo que le pasemos por el teclado y se lo envía a los hijos, los cuales uno de ellos visualiza la información por teclado y el otro la almacena en un fichero. Si el padre recibe un "exit" o la cadena está vacía, mata ambos procesos y la aplicación finaliza.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
pid_t pidHijo1;
pid_t pidHijo2;
int tuberiaH1[2]; /* usamos tuberiaH1 para enviar información del Padre al Hijo1 */
int tuberiaH2[2]; /* usamos tuberiaH2 para enviar información del Padre al Hijo2 */
void procesoHijo1();/* Proceso que ejecuta Hijo1 */
void procesoHijo2();/*Proceso que ejecuta Hijo2 */
void procesoPadre();/* Proceso Padre */
void procesoCrearHijo2();/* Proceso que ejecuta Padre para crear Hijo2 */
/* --------------- Main ------------------ */
int main(int argc, char * argv[]){
pipe(tuberiaH1);
pidHijo1=fork();
if(pidHijo1==0){
procesoHijo1();
}else if(pidHijo1 >0 ){
procesoCrearHijo2();/* esto lo ejecuta el proceso Padre, es necesario para crear un segundo Hijo */
}else{
printf("Error, no hay procesoHijo1\n");
}
}
/* --------------- Funciones ------------------ */
void procesoHijo1(){
char buffer[255];
close(tuberiaH1[1]); /* no vamos a escribir en la tubería */
close(0); /* no vamos a leer nada por teclado */
dup(tuberiaH1[0]); /* rederigir entrada estandar a la tuberia */
printf("[H1] dice: Escribe texto que te lo visualizo por pantalla y [H2] lo almacenará en un fichero\nPara Salir solo pulsa Intro o escribe exit\n");
for(;;){
fgets(buffer,sizeof(buffer),stdin); /* leer del padre */
while(getc(stdin) != '\n'); /* descartar hasta fin de línea */
printf("[H1] %s",buffer);/* sacar por pantalla */
}
}
void procesoHijo2(){
char buffer[255];
char* cadena="[H2] ";
int f1;
/* Si el archivo no existe lo crea y si existe, lo habe en modo escritura y se pone al final */
f1=open("H2archivoCreado",O_CREAT | O_APPEND | O_WRONLY,0644);
if (f1==-1){/* control de error al abrir el fichero */
perror("Error al abrir fichero:");
exit(1);
}
close(tuberiaH2[1]); /* no vamos a escribir en la tubería */
close(0); /* no vamos a leer nada por teclado */
dup(tuberiaH2[0]); /* rederigir entrada estandar a la tuberia */
for(;;){
fgets(buffer,sizeof(buffer),stdin); /* leer del padre */
while(getc(stdin) != '\n'); /* descartar hasta fin de línea */
write(f1, cadena, strlen(cadena) ); /* escribir en fichero mensaje CADENA */
write(f1, buffer, strlen(buffer) ); /* escribir en fichero mensaje enviado por el proceso Padre */
}
close(f1);
}
char buffer[255];
char* cadena="[H2] ";
int f1;
/* Si el archivo no existe lo crea y si existe, lo habe en modo escritura y se pone al final */
f1=open("H2archivoCreado",O_CREAT | O_APPEND | O_WRONLY,0644);
if (f1==-1){/* control de error al abrir el fichero */
perror("Error al abrir fichero:");
exit(1);
}
close(tuberiaH2[1]); /* no vamos a escribir en la tubería */
close(0); /* no vamos a leer nada por teclado */
dup(tuberiaH2[0]); /* rederigir entrada estandar a la tuberia */
for(;;){
fgets(buffer,sizeof(buffer),stdin); /* leer del padre */
while(getc(stdin) != '\n'); /* descartar hasta fin de línea */
write(f1, cadena, strlen(cadena) ); /* escribir en fichero mensaje CADENA */
write(f1, buffer, strlen(buffer) ); /* escribir en fichero mensaje enviado por el proceso Padre */
}
close(f1);
}
void procesoPadre(){
char buffer[255];
char buffer2[257];
int estado;
close(tuberiaH1[0]); /* no la vamos a leer datos de la tubería */
close(2); /* cerrar la salida estándar de errores */
dup2(tuberiaH1[1],2); /* Redirigirla salida estándar de ERRORES a la tubería */
fgets(buffer,sizeof(buffer)-1,stdin);
while (strlen(buffer) !=0 && buffer[0] != '\n' && strcmp(buffer,"exit\n")){
sprintf(buffer2,"%s\n ",buffer);
fprintf(stderr,"%s",buffer2);
write(tuberiaH2[1],buffer2,strlen(buffer2));
fgets(buffer,sizeof(buffer)-1,stdin);
}
printf("[P] dice: INTRO cerrando aplicación\n");
kill(pidHijo1, SIGTERM); /* terminia con procesoHijo1 */
kill(pidHijo2, SIGTERM); /* terminia con procesoHijo2 */
int pidH1off = wait(&estado);
int pidH2off = wait(&estado);
fprintf(stdout,"Hasta otra!\n");
exit(0);
}
char buffer[255];
char buffer2[257];
int estado;
close(tuberiaH1[0]); /* no la vamos a leer datos de la tubería */
close(2); /* cerrar la salida estándar de errores */
dup2(tuberiaH1[1],2); /* Redirigirla salida estándar de ERRORES a la tubería */
fgets(buffer,sizeof(buffer)-1,stdin);
while (strlen(buffer) !=0 && buffer[0] != '\n' && strcmp(buffer,"exit\n")){
sprintf(buffer2,"%s\n ",buffer);
fprintf(stderr,"%s",buffer2);
write(tuberiaH2[1],buffer2,strlen(buffer2));
fgets(buffer,sizeof(buffer)-1,stdin);
}
printf("[P] dice: INTRO cerrando aplicación\n");
kill(pidHijo1, SIGTERM); /* terminia con procesoHijo1 */
kill(pidHijo2, SIGTERM); /* terminia con procesoHijo2 */
int pidH1off = wait(&estado);
int pidH2off = wait(&estado);
fprintf(stdout,"Hasta otra!\n");
exit(0);
}
void procesoCrearHijo2(){
pipe(tuberiaH2);
pidHijo2=fork();
if(pidHijo2==0){
procesoHijo2();
}else if(pidHijo2 >0 ){
procesoPadre(); /* Se ejecuta el procesoPadre */
}else{
printf("Error, no hay procesoHijo2\n");
}
}
pipe(tuberiaH2);
pidHijo2=fork();
if(pidHijo2==0){
procesoHijo2();
}else if(pidHijo2 >0 ){
procesoPadre(); /* Se ejecuta el procesoPadre */
}else{
printf("Error, no hay procesoHijo2\n");
}
}
No hay comentarios:
Publicar un comentario