#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <string.h>

#define USAGE "usage: %s <tmpfile>\n"

#define MAPSIZE 1024

extern int errno;
static volatile sig_atomic_t sflag;
static sigset_t signal_neu, signal_alt, signal_leer;
void sigfunc1(int);
void sigfunc2(int);

void signale_mmap(void)
{
  if(signal(SIGSEGV, sigfunc1) == SIG_ERR)
   {
     fprintf(stderr, "Konnte signalhandler für SIGSEGV nicht einrichten\n");
     exit(0);
   }
  if(signal(SIGBUS, sigfunc2) == SIG_ERR)
   {
    fprintf(stderr, "Konnte signalhandler für SIGBUS nicht einrichten\n");
    exit(0);
   }

/*Wir entfernen alle Signale aus der Signalmenge*/
  sigemptyset(&signal_leer);
  sigemptyset(&signal_neu);
/*Wir fügen die zwei Signal SIGSEGV und SIGBUS zur Signalmenge hinzu*/
  sigaddset(&signal_neu, SIGSEGV);
  sigaddset(&signal_neu, SIGBUS);
/*Jetzt setzen wir signal_neu und sichern die noch */
/*aktuelle Signalmaske in signal_alt*/
  if(sigprocmask(SIG_BLOCK, &signal_neu, &signal_alt) < 0)
     exit(0);
}

void sigfunc1(int sig)
{
  printf("SIGSEGV: Versuch auf einen unerlaubten Speicherbereich zu schreiben\n");
  exit(0);
}

void sigfunc2(int sig)
{
  printf("SIGBUS: Der Speicherbereich ist nicht mehr gültig\n");
  exit(0);
}

int main(int argc, char *argv[])
{
  int fd;
  pid_t pid;
  time_t now;
  char buf[MAPSIZE];
  char *mapped, *omap;
  char *timestring;

  if(argc!=2)
   {
     fprintf(stderr,USAGE,*argv);
     exit(1);
   }

  signale_mmap() ;

  if((fd=open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0777))<0)
    {
      perror("open");
      exit(1);
    }

  pid=fork();
  if(pid==-1)
   {
     perror("fork");
     exit(1);
   }
  if(pid==0)
   { /* father, writing*/
  if((mapped=(char*)mmap(NULL,2*MAPSIZE,PROT_WRITE,MAP_SHARED,fd,0)) ==(void*)-1)
     {
       perror("mmap: ");
       exit(1);
     }
  omap=mapped;
  lseek(fd, MAPSIZE, SEEK_CUR);
  write(fd,"hallo",6);
  while(1)
   {
     now=time(NULL);
     timestring=ctime(&now);
     strcpy(mapped, timestring);
     mapped+=strlen(timestring);
     msync(omap,2*MAPSIZE,MS_SYNC);
     puts("Eltern schreiben in Hauptspeicher\n");
     sleep(1);
    }
  exit(0);
   }
  else
    { /* child, reading */
  if((mapped=(char*)mmap(NULL,2*MAPSIZE,PROT_READ,MAP_SHARED,fd,0))==(void*)-1)
    {
      perror("mmap: ");
      exit(1);
    }
  while(1)
    {
      sleep(1);
      strcpy(buf, mapped);
      mapped+=strlen(buf);
      printf("Kind ließt aus dem Hauptspeicher : %s\n",buf);
    }
    exit(0);
   }
 exit(0); /*Hier kommen wir niemals an*/
}