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.