#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

#define SEM_HIJO 0
#define SEM_PADRE 1

int main (int argc, char *argv[])
{
  int i=10, semid, pid;
  struct sembuf operacion;
  key_t llave;

  /* Petición de un identificador con 2 semáforos */
  llave=ftok(argv[0],'K');
  if ((semid = semget(llave, 2, IPC_CREAT | 0600)) == -1 ){
    perror ("semget");
    exit (-1);
  }
  /* Inicialización de los semáforos, cerramos el del hijo y abrimos el del padre */
  semctl(semid,SEM_HIJO,SETVAL,0);
  semctl(semid,SEM_PADRE,SETVAL,1);

  /* Creamos el hijo */
  if ((pid = fork()) == -1){
    perror("fork");
    exit(-1);
  } else if (pid == 0){  // Código del hijo
      while (i) {
        /* Cerramos el semaforo del hijo */
        operacion.sem_num = SEM_HIJO;
        operacion.sem_op = -1;
        operacion.sem_flg = 0;
        semop (semid, &operacion, 1);

        printf("PROCESO HIJO: %d\n", i--);
        /* Abrimos el del padre */
        operacion.sem_num = SEM_PADRE;
        operacion.sem_op = 1;
        operacion.sem_flg = 0;
        semop (semid, &operacion, 1);
      }
      semctl (semid, 0, IPC_RMID, 0);
  }
  else{  // Código del padre

      operacion.sem_flg = 0;

      while(i){
        /* Cerramos el padre */
        operacion.sem_num = SEM_PADRE;
        operacion.sem_op = -1;
        semop (semid, &operacion, 1);

        printf("PROCESO PADRE: %d\n", i--);

        /* Abrimos el hijo */
        operacion.sem_num = SEM_HIJO;
        operacion.sem_op = 1;
        semop (semid, &operacion, 1);
      }

    /* Borrado del semaforo */
      semctl(semid, 0, IPC_RMID, 0);
  }

  return 0;
}
