#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

#define FNAME "locki.lck"

void status(struct flock *lock)
{
  printf("Status: ");
  switch(lock->l_type)
   {
     case F_UNLCK:  printf("F_UNLCK (Sperre aufgehoben)\n");
                    break;
     case F_RDLCK:  printf("F_RDLCK (pid: %d) (Lesesperre)\n", lock->l_pid);
                    break;
     case F_WRLCK:  printf("F_WRLCK (pid: %d) (Schreibsperre)\n", lock->l_pid);
                    break;
     default     :  break;
    }
}


int main(int argc, char **argv)
{
  struct flock lock;
  int fd;
  char puffer[100];

  fd = open(FNAME, O_WRONLY|O_CREAT|O_APPEND, S_IRWXU);

  memset(&lock, 0, sizeof(struct flock));
  fcntl(fd, F_GETLK, &lock);

  if(lock.l_type==F_WRLCK || lock.l_type==F_RDLCK)
    {
      status(&lock);
      memset(&lock,0,sizeof(struct flock));
      lock.l_type = F_UNLCK;
      if (fcntl(fd, F_SETLK, &lock) < 0)
        printf("Fehler : fcntl(fd, F_SETLK, F_UNLCK)  (%s)\n",strerror(errno));
      else
        printf("Erfolgreich gesetzt : fcntl(fd, F_SETLK, F_UNLCK)\n");
    }

  status(&lock);
  write(STDOUT_FILENO,"\nEingabe machen : ", sizeof("\nEingabe machen : "));
  while((read(1,puffer,100))>1)
  write(fd,puffer,100);


  memset(&lock, 0, sizeof(struct flock));
  lock.l_type = F_WRLCK;
  lock.l_start=0;
  lock.l_whence = SEEK_SET;
  lock.l_len=0;
  lock.l_pid = getpid();
  if (fcntl(fd, F_SETLK, &lock) < 0)
     printf("Fehler bei : fcntl(fd, F_SETLK, F_WRLCK)(%s)\n",strerror(errno));
  else
     printf("Erfolgreich mit : fcntl(fd, F_SETLK, F_WRLCK)\n");
  status(&lock);

  switch(fork())
    {
      case -1 :  exit(0);
      case 0  :  if(lock.l_type == F_WRLCK)
                  {
                   printf("Kind:Kann nicht in die Datei schreiben (F_WRLCK)\n");
                   exit(0);
                  }
                 else
                   printf("Kindprozess ist bereit zum schreiben in die Datei\n") ;
                 exit(0);
     default  :  wait(NULL);  break;
    }

  close(fd);
  return 0;
}
