#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

extern int errno;

void status(struct flock *lock)
{
  printf("Status: ");
  switch(lock->l_type)
   {
     case F_UNLCK:  printf("F_UNLCK\n"); break;
     case F_RDLCK:  printf("F_RDLCK (pid: %d)\n", lock->l_pid); break;
     case F_WRLCK:  printf("F_WRLCK (pid: %d)\n", lock->l_pid); break;
     default               :  break;
   }
}


void schreibsperre(char *prozess, int fd, off_t von, off_t bis)
{
  struct flock lock;

  lock.l_type = F_WRLCK;
  lock.l_start=von;
  lock.l_whence = SEEK_SET;
  lock.l_len=bis;
  lock.l_pid = getpid();
  if (fcntl(fd, F_SETLKW, &lock) < 0)
    {
     printf("%s : fcntl(fd, F_SETLKW, F_WRLCK) failed (%s)\n",prozess,strerror(errno));
     printf("\nDEADLOCK erkannt (%s - prozess)!!!!!!!!!\n\n",prozess);
     exit(0);
     }
  else
     printf("%s : fcntl(fd, F_SETLKW, F_WRLCK) succeeded\n",prozess);

  status(&lock);
}


int main()
{
  int fd, i;
  pid_t pid;

  if(( fd=creat("dead.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) <0)
   {
     fprintf(stderr, "Fehler bei creat......\n");
     exit(0);
    }

/*Beschreiben dead.txt mit 50 Bytes mit dem Buchstaben X*/
  for(i=0; i<50; i++)
     write(fd, "X", 1);

  if((pid = fork()) <0)
    {
      fprintf(stderr, "Fehler bei fork()......\n");
      exit(0);
    }
  else if(pid == 0) //Kindprozess
    {
      schreibsperre("Kind ", fd, 20, 0);
      sleep(3);
      schreibsperre("Kind" , fd, 0, 20);
    }
  else //Elternprozess
    {
      schreibsperre("Eltern ", fd, 0, 20);
      sleep(1);
      schreibsperre("Eltern " , fd, 20, 0);
    }
  exit(0);
}