ENUNCIADO
El programa admitirá un parámetro, el nombre de un fichero.
El programa constará de dos procesos, padre e hijo,
comunicados por una tubería sin nombre. El hijo escribirá
en la tubería cada 10 segundos
"[[x segundos]]
",
siendo x el número de segundos que han transcurrido.
El programa padre atenderá a la entrada estándar y a
la tubería. Por cualquier medio que le llegue algo,
escribirá lo que le llegue en el fichero que se le
ha pasado por la línea
de órdenes. Cuando el usuario presione CTRL+D
,
el programa
acabará, no sin antes haber matado todos los procesos.
Se puede usar sleep
en el hijo. Haced todo
el programa en un único fichero fuente .c
.
COMENTARIOS
En esta ocasión fueron Ecco y Ecco quienes consiguieron el premio:
#define _HPUX_SOURCE
#include<sys/time.h>
#include<unistd.h>
#include<fcntl.h>
#include<signal.h>
void hijo(int tuberia);
void padre(int tuberia,char *fichero,int pidhijo);
int main(int argc,char * argv[])
{
int tuberia[2],valor_devuelto;
if (argc==1)
{
perror("Pocos argumentos");
/* Esto es un error: perror, si
hay pocos argumentos no puede informar
de nada porque no ha habido ninguna
llamada al sistema que haya fallado. */
return 1;
}
if(pipe(tuberia)==-1)
{
perror("Error en tuberia");
return 2;
}
valor_devuelto=fork();
switch(valor_devuelto)
{
case -1:
perror("Error en fork");
return 3;
case 0:
/*tuberia de escritura para el hijo*/
hijo(tuberia[1]);
break;
default:
/*tubería de lectura para el padre*/
padre(tuberia[0],argv[1],valor_devuelto);
break;
}
return 0;
}
void hijo(int tuberia)
{
char cadena[100];
int i;
for(i=1;i<=10;i++)
{
sleep(10);
sprintf(cadena,"[[%d segundos]]",i*10);
if(write(tuberia,cadena,strlen(cadena))==-1)
{
perror("error en write");
exit(4);
}
}
}
void padre(int tuberia,char *fichero,int pidhijo)
{
fd_set conjunto;
int num_conj, descriptor,tamano;
char buffer[100];
descriptor=open(fichero,O_CREAT|O_WRONLY|O_TRUNC,0666);
if((descriptor)==-1)
{
perror("error al abrir el fichero");
exit(5);
}
do
{
FD_ZERO(&conjunto); /* limpia el conjunto*/
FD_SET(0,&conjunto); /* entrada estandar*/
FD_SET(tuberia,&conjunto); /*tuberia*/
if(select(tuberia+1,&conjunto,NULL,NULL,NULL)==-1)
{
perror("error de select");
exit(6);
}
if(FD_ISSET(0,&conjunto)!=0)/*lectura de entrada estandar*/
{
tamano=read(0,buffer,100);
if(tamano==-1)
{
perror("error en read");
exit(7);
}
if(write(descriptor,buffer,tamano)==-1)
{
perror("error en write");
exit(8);
}
}
if(FD_ISSET(tuberia,&conjunto)!=0)/*lectura de tuberia*/
{
tamano=read(tuberia,buffer,100);
if(tamano==-1)
{
perror("error en read");
exit(9);
}
if(write(descriptor,buffer,tamano)==-1)
{
perror("error en write");
exit(10);
}
}
} while(tamano>0);/*CRTL-D hace que read lea el valor 0*/
/* Mejor dicho: CTRL-D es el carácter
de "fin de fichero" por defecto y hace que
la tubería se cierre y, por consiguiente,
read devuelva 0, por alcanzar el "final
del fichero. */
if(close(descriptor)==-1)
{
perror("error en close");
exit(11);
}
if(kill(pidhijo,SIGTERM)==-1)/*asesinato vil del hijo*/
{
perror("error en kill");
exit(12);
}
}
© 2001 Guillermo González Talaván.