#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

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ürgen 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: Es wurde versucht 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, n=0;
  void *speicherberreich;
  struct stat attr;

  signale_mmap();

  while(argv[++n] != NULL)
    {
       if(( fd=open(argv[n], O_RDONLY)) < 0)
         {
          fprintf(stderr, "Konnte %s nicht öffnen!!!\n",argv[n]);
          continue; /*Wieder hoch zu while*/
         }
       if(fstat(fd, &attr) == -1)
         {
           fprintf(stderr,"Fehler bei fstat.......\n");
           continue; /*Wieder hoch zu while*/
         }

/*Achtung jetzt legen wir die Datei die wir mit fd speziviert haben in den Arbeitsspeicher*/
     speicherberreich=mmap(0, attr.st_size+5, PROT_READ, MAP_SHARED, fd, 0);
     if(speicherberreich == ((caddr_t) -1))
       {
         fprintf(stderr, "%s: Fehler bei mmap mit der Datei %s\n",strerror(errno), argv[n]);
         continue; /*Hoch zu while*/
       }
      close(fd);
/*Jetzt versuchen wir mit Absicht in den mapped-Speicher zu schreiben trotzt PROT_READ*/
     strcat((char *)speicherberreich, "test");
   }/*Ende while*/
  exit(0);
}