/*  
    Elaborado por: Mario H Tiburcio Z
    Fecha: Junio 2004
    (El programa podra ser copiado, y destribuido libremente siempre y cuando
     se otorgen los creditos correspondientes a su autor).
    (No se ofrece ninguna garantia por el buen o mal funcionamiento
     de este programa).

    Programa que ilustra el uso de la funcion fork() haciendo correr
    un proceso padre que genera un proceso hijo. El proceso padre permite
    trabajar al hijo por el tiempo en segundos denotado por la constante
    TIEMPO (para este ejemplo 30 segundos), al termino de los cuales el
    proceso padre mata al proceso hijo y finaliza la ejecucion del programa.

    Funciones empleadas:

    fork()      Genera un proceso identico al padre. Esta funcion devuelve
                un 0 si se trata del proceso hijo o devuelve el PID del 
                proceso hijo generado si se trata del padre.

    getpid()    Devuelve el valor del PID del proceso que invoca la funcion.

    kill(PID,9) Mata el proceso especificado por el PID dado como argumento.
                El numero 9 es la señal que permite matar un proceso.
*/    


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>
#define TIEMPO 30
double tiempo_actual_segundos();

int main (int argc, char *argv[])
{
        int i,pid;
        static double t0;
        double ta; 
        if ( (pid = fork()) != 0) 
        /* Proceso Padre */
        {
          t0=tiempo_actual_segundos();
          for(;;)
          {
            ta=tiempo_actual_segundos();
            /* El padre manda un mensaje a los 10 y 20 seg. de ejecucion */
            if ((ta-t0)==10 || (ta-t0==20))
            {
              printf("Yo soy el proceso padre PID=%d y mi hijo PID=%d\n",getpid(),pid); 
              sleep(1);
            }
            /* El padre verifica si es momento de terminar la ejecucion */
            if (ta-t0>TIEMPO)
            {
              printf("TIEMPO FUERA Proceso padre matando al hijo %d !!!\n",pid);
              kill(pid,9);
              break;
            }   
          }
        }
        else 
        /* Proceso hijo */
        for(i=1;;)
        {
         printf("Soy proceso hijo %d y estoy trabajando %d !!!\n",getpid(),i++);
         sleep(1);
        }
}

double tiempo_actual_segundos() {
  /* Regresa tiempo del sistema expresado en segundos */
  struct timeval tiempo;
  int diff;
  gettimeofday(&tiempo,0);
  return ((double) tiempo.tv_sec);
}
