UNIX-Systemarchitektur - 3.Signale
  
  
  
  
  
  
  
  
  
  
                               UNIX-Schnittstelle
                               ==================
  
  
             3. Signale, Signalbehandlung, Synchronisation von Threads
                      und Sonstiges
             =========================================================
  
  
  Alle Beispiel-Quellen mittels SVN unter:
  
      https://svn.informatik.hu-berlin.de/svn/unix2014/Signale








nextback          2017 - 1





  
             3.1 Signale und Signalbehandlung
             ================================
  
  Signale:   Softwareinterrupts für Prozesse
             asynchrone:   Timer, Terminalinterrupts, Pipe-Ende
             synchrone:    Programmfehler, Calls
  
  Signalbehandlung hat sich im Laufe der UNIX-Entwicklung stark 
  veräendert.
       - Bis einschließlich der Version 7 kam es zu Signalverlusten.
       - Siganlbehandlung war umständlich und fehlerhaft.
       - BSD 4.3 und AT&T V.4 machten jeweils individuelle und unterschiedliche
         Verbesserungen.
       - Standardisierung jetzt durch POSIX.1
  
  Jedes Signal hat einen Namen. Ursprünglich 15 Signale.
  Jetzt 31 Signale unterschiedlicher Funkionalität (BSD/AT&T).
  
  Signalquellen:
  
      1. Terminal erzeugt Signale: SIGINT, SIGQUIT, SIGHUP
                                      ^C     ^\     ausschalten
      2. Hardware-Ausnahmen: Division durch Null, Speicherfehler,
                             Busfehler
      3. Kill-Systemruf
      4. Spezielle Softwarezustände im System: Pipeende, Nutzerzeit
                             abgelaufen, Out-of-Band Daten u.s.w.


nextback          2017 - 2





  
  Typische Reaktionen auf Signale:
  
      1. Ignorieren (alle außer SIGKILL/SIGSTOP)
      2. Behandlung der Signale durch eingene Funktionen (Nutzer)
      3. Default-Behandlung durch Kern
            terminate
            terminate and write core
            ignore
            continue or stop work
  
  Übersicht über Signale
  ----------------------
  twc = terminate and write core    t   = terminate
  i   = ignore                      c   = continue
  ti  = terminate or ignore         s   = stop
  
  SIGABRT    6  twc  used by abort, replace SIGIOT in the  future 
  SIGALRM   14  t    alarm clock 
  SIGBUS    10  twc  bus error 
  SIGCHLD   18  i    death of a child  (old: SIGCLD)
  SIGCONT   23  c    continue if stopped 
  SIGEMT     7  twc  EMT instruction 
  SIGFPE     8  twc  floating point exception 
  SIGHUP     1  t    hangup 
  SIGILL     4  twc  illegal instruction (not reset when caught)
  SIGINFO       i    status request from keyboard
  SIGINT     2  t    interrupt (rubout) 
  SIGIO         ti   asynchronous I/O
  SIGIOT     6  twc  IOT instruction 
nextback          2017 - 3





  SIGKILL    9  t    kill (cannot be caught or ignored) 
  SIGPHONE  21  i    handset, line status change 
  SIGPIPE   13  t    write on a pipe with no one to read it 
  SIGPOLL   22  t    pollable event occured 
  SIGPROF       t    profiling time alarm
  SIGPWR    19  i    power-fail restart 
  SIGQUIT    3  twc  quit (ASCII FS) 
  SIGSEGV   11  twc  segmentation violation 
  SIGSTOP   24  s    stop signal (cannot be caught or ignored) 
  SIGSYS    12  twc  bad argument to system call 
  SIGTERM   15  t    software termination signal from kill 
  SIGTRAP    5  twc  trace trap (not reset when caught) 
  SIGTSTP   25  s    interactive stop signal 
  SIGTTIN   26  s    background read attempted 
  SIGTTOU   27  s    background write attempted 
  SIGUSR1   16  t    user defined signal 1 
  SIGUSR2   17  t    user defined signal 2 
  SIGVTALRM     t    virtual time alarm
  SIGWINCH  20  i    window change 
  SIGXCPU       twc  CPU-limit exceeded
  SIGXFSZ       twc  file size limit exceeded
  
  Zuverlässige Information über aktuelle Signale:
  
        /usr/include/sys/signal.h





nextback          2017 - 4





  
  #include <signal.h>
  
  void (*signal(int signo,void(*func)(int)))(int);
  
  typedef void (*sighandler_t)(int);
  sighandler_t signal(int signum, sighandler_t handler);
  
  
  Definition (Installation) einer Signalbehandlungsroutine  func.
  Die Signalbehandlungsroutine wird beim Auftreten eines Signals
  signo  aktiviert. Signalbehandlungsroutinen haben einen Integer-
  Parameter und keinen Rückkehrwert (bei alten Systemen keinen
  Parameter). Der Integer-Parameter enthält beim Aufruf der
  Signalbehandlungsroute die Nummer des Signals, das den Aufruf
  auslöste hat.
  
  Vordefiniert Signalbehandlungsfunktionen:
  
                  SIG_DFL   -   Standardbehandlung der Signale
  		SIG_IGN   -   Routine zum ignorieren von Signalen
  
  Rückkehrwert:
  
          Adresse der vorhergehenden Signalbehandlungsroutine.
          SIG_ERR - Fehler beim Setzen der Signalbehandlungsroutine   




nextback          2017 - 5





  Bemerkungen:
  
     exec()  :  private Signalbehandlungsroutinen werden auf SIG_DFL
                zurückgesetzt. SIG_IGN bleibt erhalten.
  
     Rücksetzen der Signalbehandlungsroutine:
  
            früher: Nach jedem Auftreten eines Signals wurde die
                     Signalbehandlungsroutine auf SIG_DFL gesetzt.
                     sig_int()
                     {   /* kritischer Bereich */
                        signal(SIGINT,sig_int);
                        ....
                     }
                     main()
                     {
                        .....
                        signal(SIGINT,sig_int);
                        .....
                     }
  
            später: Signalbehandlungsroutine bleibt bis zum expliziten
                   Umsetzen durch  signal()   installiert.
  
            heute: wie früher





nextback          2017 - 6





    Wirkung von Signalen auf "wartende Systemrufe":
      früher:  alle "wartenden" Systemrufe wurden unterbrochen,
                es erfolgte kein Restart des Systemrufs.
      heute:    systemabhängig
                AT&T   -  unterbrochen, kein Restart
                BSD 4.3 - unterbrochen, kein Restart ist Standard.
                          Restart optional möglich
                POSIX.1 - Unterbrochen, Restart möglich, nicht
                          notwendig
  
    Was kann man in Signalbehandlungsroutinen tun???
         Fast alles. Man muss nur reenterante Funktionen haben.
         Fast alle Systemcalls sind reenterant, aber nicht alle
         Bibliotheksfunktionen.
         Reenterante Systemfunktionen: 
           _exit        abort          access    alarm       chdir 
  	 chown        close          creat     dup         dup2
  	 execle       execve         exit      fcntl       fork
  	 fstat        getegid        geteuid   getgid      getgroups
  	 getpgrp      getpid         getppid   getuid      kill 
  	 link         longjmp        lseek     mkdir       mkfifo
  	 open         pathconf       pause     pipe        read 
  	 rename       rmdir          setgid    setpgid     setsig 
  	 setuid       sigaction      sigaddset sigdelset   sigemptyset
  	 sigfillset   sigislmember   signal    sigpending  sigprocmask
  	 sigsuspend   sleep          stat      sysconf     time
  	 times        umask          uname     unlink      utime
  	 wait         waitpid        write


nextback          2017 - 7





  
  Unterschiede bei der Behandlung der Signalroutine und der Wiederaufnahme 
  von Systemaufrufen nach Signalen 
  
  Funktion             |Betriebssystem   | Wiederauf-   |Blockier.| Restart
                       |                 | setzen der   |von      | des
                       |                 | Signalroutine|Signalen | Systemrufs
  ---------------------+-----------------+--------------+---------+-----------
  signal               |V7, SVR2         |      -       |    -    |   niemals
                       |SVR3, SVR4       |              |         |
  ---------------------+-----------------+--------------+---------+-----------
  sigset, sighold,     |SVR3, SVR4       |      +       |    +    |   niemals
  sigrelse, sigignore, |                 |              |         |
  sigpause             |                 |              |         |
  ---------------------+-----------------+--------------+---------+-----------
  signal, sigvec,      | 4.2 BSD         |      +       |    +    |   immer
  sigblock, sigsetmask | 4.3 BSD,4.3+BSD |      +       |    +    |   default
  sigpause             |                 |              |         |
  ---------------------+-----------------+--------------+---------+-----------
  sigaction,sigprocmask| POSIX.1         |      +       |    +    | unbestimmt
  sigpending,sigsuspend| SVR4            |      +       |    +    | optional
                       | 4.3+BSD         |      +       |    +    | optional
  ---------------------+-----------------+--------------+---------+-----------







nextback          2017 - 8





  #include <sys/types.h>
  #include <signal.h>
  
  int kill(pid_t pid, int signo);               /*immer vorhanden*/
  int raise(int signo);                         /*ANSI C, Bibliotheksroutine*/
  
  kill()  sendet das Signal  signo  an einen Prozess oder eine
  Prozessgruppe in Abhängigkeit vom Wert von  pid.
        pid  > 0   -  senden des Signals an den Prozess mit der
                     PID  pid
        pid == 0   -  an alle Prozesse der gleichen Prozessgruppe
        pid == -1  -  Nutzerprozess: Signal an alle Prozesse des
                                     Nutzers
                      Superuser: Signal an alle Prozesse ausser
                                 0  und  1
        pid < -1   -  an alle Prozesse der Prozessgruppe  abs(pid)
  Wenn  signo==0  ist, wird nur die Gültigkeit von  pid geprüft.
  Achtung: alte Systeme kennen nur pid > 0 !!!!
  raise()  sendet das Signals  signo an den eigenen Prozess.
  
  Rückkehrwerte:
         0 - Ok
        -1 - Fehler
              EINVAL  - signo ist unzulässig
              ESRCH   - kein Prozess oder Prozessgruppe mit
                        entsprechendem PID
              EPERM   - UID des aktuellen Prozesses reicht nicht aus
                        um an den spezifizierten Prozess ein Signal
                        zu senden.

nextback          2017 - 9





  
  #include <unistd.h>
  
  unsigned int alarm(unsigned int seconds);
  
  Kern soll nach  seconds  Sekunden ein Signal SIGALRM an den
  aktuellen Prozess senden.
  
  Rückkehrwert: 
          > 0 -  Anzahl der nicht verbrauchten Sekunden
                 des letzten Systemrufes  alarm.
            0 - kein Alarm-Ruf aufgesetzt
  
  
  
  
  
  #include <unistd.h>
  
  int pause(void)
  
  Pause bis zum Auftreten eines Signals für diesen Prozess.
  
  Rückkehrwert: 
      -1 - immer (Signal aufgetreten)





nextback          2017 - 10





  
  Beispiele:
  
        Signale/sigusr.c      # manuelles Aufsetzen der Interruptroutine
  
        Signale/reenter.c     # Probleme mit nicht reenteranten Funktionen
  
        Signale/tsleep1.c     # Zeitgeber
  
        Signale/tsleep2.c     # Zeitgeber
  



















nextback          2017 - 11





  
  Die vorgestellten Systemrufe lassen nur relativ einfache Signal-
  behandlungen zu. Deshalb wurde sowohl im BSD 4.3 als auch im
  AT&T V.x der Begriff der Signalmenge (32 Bit) eingeführt.
  Mit Hilfe dieser Signalmengen ist es möglich die Zulassung und
  Behandlung von Signalen genauer zu spezifizieren. Für die
  Manipulation der Signalmenge stehen sowohl im BSD 4.3 als auch
  im AT&T folgende Funktionen zur Verfügung:
  
    #include <signal.h>                         BSD 4.3  &  AT&T V.4
  
    int sigemptyset(sigset_t *set);
         alle Signale in Signalmenge  *set  löschen
    int sigfillset(sigset_t *set);
         alle Signale in Signalmenge  *set  setzen
    int sigaddset(sigset_t *set, int signo);
         Signal signo in Signalmenge  *set  setzen
    int sigdelset(sigset_t *set, int signo);
         Signal signo aus Signalmenge  *set  löschen
    int sigismember(const sigset_t *set, int signo);
         Testen ob in Signalmenge  *set  das Signal signo enthalten ist
         1 - is member,   0 - is not member








nextback          2017 - 12





                                          veraltet
  #include <signal.h>                 /*BSD 4.3, AT&T-Bibliothek*/
  
  int sigvec( int signo, struct sigvec *vec, struct sigvec *ovec);
  
  sigvec()  arbeitet analog wie  signal(). Die Signalbehandlunsroutine
  und das Signalverhalten wird in einer Struktur *vec definiert. Das
  alte Signalverhalten wird in der Struktur  *ovec entsprechend
  zurückgegeben, wenn  ovec!=NULL.
  
     struct sigvec{
          void (*sv_handler)();  /* Signalbehandlungsroutine */
          int sv_mask;          /* aktuelle Signalmaske */
          int sv_flags;         /* Options */
     }
  
  Options:
     SV_ONSTACK   - speziellen Signalstack benutzen
     SV_INTERRUPT - kein "Restart" eines Systemrufes beim Auftreten
                    des Signals nach Ausführung der Signalbehandlungs-
                    routine (alte Signalphilosophie)
     SV_RESETHAND - Rücksetzen der Signalbehandlungsroutine auf
                    SIG_DFL, wenn das Signal einmal aufgetreten ist.
                    (alte Sginalphilosophie)
  Rückkehrwert:
        0 - kein Fehler aufgetreten
       -1 - Fehler (EFAULT, EINVAL)
  
  Beispiel:  Signal/sigusrvec.c    # Rücksetzen des Signalhandlers

nextback          2017 - 13





                                                      veraltet
  #include <signal.h>                                 /*BSD 4.3*/
  
  int sigsetmask(int mask);
  
  sigsetmask()  ersetzt die aktuelle Signalmaske des Prozesses durch 
  die durch  mask  spezifierte Signalmaske. Ein Signal wird geblockt,
  wenn das korrespondierende Bit gleich 1 ist!!!
  
  Rückkehrwert:
             alte Signalmaske des Prozesses
  
  -----------------------------------------------------------------------
                                                      veraltet
  #include <signal.h>                                 /*BSD 4.3*/
  
  int sigblock(int mask);
  
  sigblock()  fügt die in  mask  als gesperrt spezifizierten Signale (korres-
  pondierende Bits gleich 1) zu der aktuellen Signalmaske des Prozesses hinzu.
  
  Rückkehrwert: 
             alte Signalmaske des Prozesses
  
  





nextback          2017 - 14





                                                      veraltet
  #include <signal.h>                                 /*BSD 4.3*/
  
  int siggetmask(void);
  
  siggetmask()  holt die aktuelle Signalmaske eines Prozesses -
  anzeige der blockierten Signale.
  
  Rückkehrwert:
             alte Signalmaske des Prozesses
  
  -----------------------------------------------------------------------
                                                      veraltet
  #include <signal.h>                                 /*BSD 4.3*/
  
  int sigmask(int signum);
  
  sigmask()  liefert als Ergebnis eine Signalmaske, in der das spezifizierte
  Signal als blockiert ( =1) gesetzt ist.
  
  Rückkehrwert: 
             Signalmaske mit gesperrtem Signal
  
  






nextback          2017 - 15





  #include <signal.h>                               /*POSIX, BSD 4.3*/
  
  int sigprocmask(int how, sigset_t *set, sigset_t *oset);
  
  sigprocmask() erlaubt das Besichtigen und Ändern der aktuellen Signal-
  maske des Prozesses. Ist  set!=NULL, wird die aktuelle Signalmaske
  entsprechend  how  verändert. Ist oset!= NULL, wird die unveränderte
  Signalmaske in  *oset abgelegt.  how kann folgende Werte annehmen:
       SIG_BLOCK   - in *set gesetzte Signale werden in der aktuellen
                     Signalmaske als gesperrt gesetzt.
       SIG_UNBLOCK - in *set gesetzte Signale werden in der aktuellen
                     Signalmaske als nicht gesperrt gesetzt.
       SIG_SETMASK - aktuelle Signalmaske ergibt sich aus  *set
  
  Rückkehrwert:
       0 - ok
      -1 - Fehler (EFAULT, EINVAL)
  -----------------------------------------------------------------------
                                                      veraltet
  #include <signal.h>                                 /*BSD 4.3*/
  
  int sigpause(int sigmask);
  
  sigpause()  ersetzt die aktuelle Signalmaske des Prozesses durch die 
  Signalmenge sigmask  (blockierte Signale) und wartet auf das Eintreffen 
  eines Signals. Beim Eintreffen eines Signals wird die ursprüngliche 
  Signalmaske wieder gesetzt.  sigmask==0 zeigt an, dass alle Signal 
  akzeptiert werden.
  
  Rückkehrwert:  immer -1
nextback          2017 - 16





  #include <signal.h>                                 /*POSIX, BSD 4.3*/
  
  int sigsuspend(const sigset_t *sigmaskp);
  
  sigsuspend() setzt die aktuelle Signalmaske des Prozesses auf *sigmaskp
  und wartet auf das Eintreffen eines Signals. Anschließend wird die
  ursprüngliche Signalmaske wieder gesetzt.
  
  Rückkehrwert: 
           -1 - immer
  
  
  -------------------------------------------------------------------
  
  
  #include <signal.h>                              /*POSIX, BSD 4.3*/
  
  int sigpending(sigset_t *set);
  
  sigpending() schreibt in *set die Signale aus der aktuellen 
  Signalmaske, die blockiert sind und für die ein Signal anliegt.
  
  Rückkehrwert: 
              0  -ok
             -1 - Fehler (falsche Adresse)





nextback          2017 - 17





  #include <signal.h>                                 /*BSD 4.3*/
  
  int sigstack(struct sigstack *ss, struct sigstack *oss);
  
  sigstack()  erlaubt dem Nutzer einen alternativen Stack für die
  Signalbehandlung einzurichten. Dieser wird beim auftreten von Sigalen
  benutzt und kann vom Nutzer im den Signalbehandlungsroutinen geändert
  werden. Ist ss!=NULL wird ein neuer Stack eingerichtet. Ist oss!=NULL
  werden die Informationen über den alten Stack nach *oss  geschrieben. 
  
      struct sigstack {
             char *ss_sp;     /*signal stack pointer */
             int  ss_onstack; /* current status, 0 - unused, !=0 used*/
      }
  
  Rückkehrwert:
         0 - ok
        -1 - Fehler (EPERM - Modifizierung eines aktiven Stack)
  
  -------------------------------------------------------------------
                                                            /*BSD 4.3*/
  int killpg(int pgrp, int sig);*/
  
  killpg()  sendet ein Signal  sig an alle Prozesse der 
  Prozessgruppe  pgrp.
  
  Rückkehrwert:
         0 - ok
        -1 - Fehler (EINVAL, EPERM, ESRCH)

nextback          2017 - 18





  #include <signal.h>                       /*POSIX,AT&T V.4, BSD 4.3*/
  int sigaction(int sig, const struct sigaction *act,
                struct sigaction *oact);
  
  sigaction()  arbeitet analog wie  signal(). Die Signalbehandluns-
  routine und das Signalverhalten wird in einer Struktur *act 
  definiert. Das alte Signalverhalten wird in der Struktur  *oact
  entsprechend zurückgegeben, wenn  ovec!=NULL.
     struct sigaction{
          void (*sv_handler)();  /* Signalbehandlungsroutine */
          sigset_t sa_mask;     /* aktuelle Signalmaske */
          int sa_flags;         /* Options */
     }
  Options:
     SA_ONSTACK   - speziellen Signalstack benutzen
     SA_RESTART   - kein "Restart" eines Systemrufes beim Auftreten
                    des Signals nach Ausführung der Signalbehandlungs-
                    routine (alte Signalphilosophie)
     SA_RESETHAND - Rücksetzen der Signalbehandlungsroutine auf
                    SIG_DFL, wenn das Signal einmal aufgetreten ist.
                    (alte Sginalphilosophie)
     SA_NODEFER   - Signal wird beim Auftreten vom Kern nicht blockiert
     SA_NOCLDWAIT - für SIGCHLD. Kindprozess erzeugt kein Zombie bei
                    exit()
     SA_NOCLDSTOP - für SIGCHLD. Kindprozess sendet kein SIGCHLD,
                    wenn er gestoppt wird.
     SA_SIGINFO   - zusätzliche Informationen werden an die
                    Signalbehandlungsroutine beim Auftreten eines
                    Signals übergeben (weiterer Parameter)
  Rückkehrwert: 0 - ok,  -1 - Fehler (EINVAL)
nextback          2017 - 19





  
  Beispiele:
  
  
     Signal/sigusract.c
  
























nextback          2017 - 20





  #include <signal.h>                /*AT&T V.4, BSD 4.3 Bibliothek*/
  
  void (*sigset(int sig, void (*disp)(int)))(int);
  
  sigset()  arbeitet genauso wie  signal() (Setzen einer Signal-
  behandlungsroutine. Lediglich wird beim Auftreten eines 
  Signals  sig  dieses Signal in die Signalmaske des aktuellen 
  Prozesses aufgenommen, so dass ein erneutes Auftreten des 
  Signals  sig  unterdrückt wird.
  
  Vordefiniert Funktionen:
                  SIG_DFL   -   Standardbehandlung der Signale
  		SIG_IGN   -   Routine zum ignorieren von Signalen
  
  Rückkehrwert:
          Adresse der vorhergehenden Signalbehandlungsroutine.
          SIG_ERR - Fehler beim Setzen der Signalbehandlungsroutine   
  
  Beispiel: Signal/sigsetusr.c    #  sigset benutzen
  ---------------------------------------------------------------
  #include <signal.h>                                  /*AT&T V.4*/
  
  int sighold(int sig);
  
  sighold()  fügt  das Signal sig in die Signalmaske des aktuellen
  Prozesses hinzu, so dass das Signal in Zukunft gesperrt ist.
  
  Rückkehrwert:
            0 - ok
           -1 - Fehler (EINTR, EINVAL)
nextback          2017 - 21





  #include <signal.h>                                  /*AT&T V.4*/
  
  int sigrelse(int sig);
  
  sigrelse() entfernt das Signal  sig aus der Signalmaske des
  aktuellen Porzesses, so dass das Signal in Zukunft wieder auftreten
  kann.
  
  Rückkehrwert:
            0 - ok
           -1 - Fehler (EINTR, EINVAL)
  
  ------------------------------------------------------------------
  
  #include <signal.h>                                  /*AT&T V.4*/
  
  int sigignore(int sig);
  
  sigignore() setzt die Signalbehandlungsroutine für das Signal sig
  für den aktuellen Prozess auf  SIG_IGN.
  
  Rückkehrwert:
            0 - ok
           -1 - Fehler (EINTR, EINVAL)






nextback          2017 - 22





  #include <signal.h>                                  /*AT&T V.4*/
  
  int sigpause(int sig);
  
  sigpause()  entfernt das Signal  sig  aus der Signalmaske des 
  aktuellen Prozesses und wartet anschliessend auf das eintreffen 
  eines Signals.
  
  Rückkehrwert:  
           -1 - immer
  -----------------------------------------------------------------
  
  #include <signal.h>                            /*POSIX,AT&T V.4*/
  
  int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
  
  sigprocmask() erlaubt das Besichtigen und Ändern der aktuellen 
  Signalmaske des Prozesses. Ist  set!=NULL, wird die aktuelle 
  Signalmaske entsprechend  how  verändert. Ist oset!= NULL, wird 
  die unveränderte Signalmaske in  *oset abgelegt.  how kann 
  folgende Werte annehmen:
       SIG_BLOCK   - in *set gesetzte Signale werden in der aktuellen
                     Signalmaske als gesperrt gesetzt.
       SIG_UNBLOCK - in *set gesetzte Signale werden in der aktuellen
                     Signalmaske als nicht gesperrt gesetzt.
       SIG_SETMASK - aktuelle Signalmaske ergibt sich aus  *set
  
  Rückkehrwert:
       0 - ok
      -1 - Fehler
nextback          2017 - 23





  
  #include <signal.h>                                  /*AT&T V.4*/
  
  int sigalstack(const stack_t *ss, stack_t *oss);
  
  sigalstack()  erlaubt dem Nutzer einen alternativen Stack für die
  Signalbehandlung einzurichten. Dieser wird beim auftreten von Sigalen
  benutzt und kann vom Nutzer im den Signalbehandlungsroutinen 
  manipuliert werden. Ist ss!=NULL wird ein neuer Stack eingerichtet. 
  Ist oss!=NULL werden die Informationen über den alten Stack nach  
  *oss  geschrieben. 
  
      struct sigalstack {
               int *ss_sp;     /*signal stack pointer */
               long ss_size;   /* stacksize in bytes */
               int  ss_flags;  /* current status */
      }
  ss_flags:  SS_DISABLE    - Stack nicht benutzt
             SS_ONSTACK    - Prozess benutzt den Stack momentan
  
  Rückkehrwert:
               0 - ok
              -1 - Fehler







nextback          2017 - 24





  
  #include <signal.h>                                 /*POSIX,AT&T V.4*/
  
  int sigpending(sigset_t *set);
  
  sigpending() schreibt in *set die Signale aus der aktuellen Signalmaske,
  die blockiert sind und für die ein Signal anliegt.
  
  Rückkehrwert:
         0 -ok
        -1 - Fehler (falsche Adresse)
  
  -----------------------------------------------------------------------
  
  #include <signal.h>                                 /*POSIX, AT&T V.4*/
  
  int sigsuspend(const sigset_t *set);
  
  sigsuspend()  setzt die aktuelle Signalmaske des Prozesses auf *set
  und wartet auf das Eintreffen eines Signals. sigsuspend()  kehrt
  nach Abarbeitung einer Signalbehandlungsroutine zurück. Die ursprügliche
  Signalmaske wird wieder gesetzt.
  
  Rückkehrwert:
          -1 - immer





nextback          2017 - 25





  
  #include <sys/types.h>                               /*AT&T  V.4*/
  #inlcude <sys/siganl.h>
  #include <sys/procset.h>
  
  int sigsend(idtype_t idtype, id_t id, int signo);
  
  int sigsendset(procset_t *psp, int signo);
  
  Senden eines Signals  signo  an den/die spezifizierten  Prozess(e).
  idtype  spezifiziert den  Typ des nachfolgenden  ID  id.
  
        idtype            id          Ziel des Signals
        P_PID             pid         Prozess
        P-PGID            pgid        Prozesse der Prozessgruppe
        P_SID             sid         Prozesse der Session
        P_UID             uid         Prozesse der Nutzers
        P_GID             gid         Prozesse der Gruppe
        P_ALL              -          Alle Prozesse
        P_TASKID          tid         Prozesse der Task
        P_PROJID          prid        Prozesse des Projekts
        P_CID             cid         Prozesse der Scheduler-Class
        P_CTID            ctid        Prozesse der Contract-Class
        P_MY              -           id des aktuellen Prozesse
  





nextback          2017 - 26





  
  Bei sigsendset wird das Signal  signo  an eine Menge von Prozessen
  gesendet, die aus  *psp   berechnet wird.
  
  stuct procset_t {
               idop_t   p_op;   /*
                       POP_DIFF - Alle Prozesse aus der L-Menge und 
                                  nicht aus der R-Menge ( logische diff )
                       POP_AND  - Alle Prozesse aus der L-Menge und 
                                  aus der R-Menge  ( logisch und )
                       POP_OR   - Alle Prozesse aus der L-Menge oder 
                                  aus der R-Menge ( logisches oder )
                       POP_XOR  - Alle Prozesse die entweder in der L-Menge 
                                  sind oder der R-Menge sind ( logisch xor )
                               */
               idtype p_lidtype; id_t p_lid;  /* 1.Prozessmenge*/
               idtype p_ridtype; id_t p_rid;  /* 2.Prozessmenge*/
  }
  
  Rückkehrwert:
       0 - ok
      -1 - Fehler (EINVAL, EPERM, ESRCH, EFAULT)
  
  
  Beispiele:
  
      Signale/critical.c 
  


nextback          2017 - 27





  
                       3.2 Synchronisation mit POSIX-Threads
                       =====================================
  
  3.2.1. Thread-Operationen - eine Übersicht
  ------------------------------------------
  Präfix für verschiede Threadbibliotheken:
    SOLARIS-Threads - thr_
    SOLARIS-Pthread, Linux - pthread_
    altes DIGITAL-Interface - cma_ -Wird ab UNIX 4.0c nicht mehr
            unterstützt. Achtung: immer als Erstes cma_init aurufen!!!!
  
  1. Syncronisationshilfen
  
     Mutex: Objekte für die Syncronisation mehrerer Threads
             mutex - mutual exclusion (gegenseitiger Ausschluss)
  
     Type: Fast Mutex - genau einmal pro Thread lock und unlock Synchronisation
           über den Zugriff zum Mutexobjekt bei Mehrfachnutzung -> Deadlock
  
       SOLARIS: mutex_init, mutex_destroy, mutex_lock,
                mutex_trylock, mutex_unlock
       LIN/SOL: pthread_mutex_init, pthread_mutex_destroy,
                pthread_mutex_lock, pthread_mutex_trylock,
                pthread_mutex_unlock
       SOLARIS: pthread_mutex_getprioceiling, pthread_mutex_getprioceiling




nextback          2017 - 28





     Type: Bedingter Mutex - recursiver Zugriff erlaubt
           Synchronisation erfolgt über den Wert des Mutexobjektes
           
       SOLARIS: cond_init, cond_destroy, cond_wait,
                cond_signal, cond_broadcast, cond_timedwait
       LIN/SOL: pthread_cond_init, pthread_cond_destroy,
                pthread_cond_wait, pthread_cond_signal,
                pthread_cond_broadcast, pthread_cond_timedwait
  
     Semaphore-Operationen
       SOLARIS: sema_init, sema_destroy, sema_wait,
                sema_trywait, sema_post
  
     Mehrfach lesbare und einzeln schreibbare Locks 
       SOLARIS: rwlock_init, rwlock_destroy, rw_rdlock,
                rw_wrlock, rw_trylock, rw_trywrlock,
                rw_unlock
  
     Signalbehandlung für Threads
       SOLARIS:      thr_sigsetmask, thr_kill, pthread_kill,
       LIN/Solaris:  pthread_sigmask, pthread_testcancel,
                     pthread_setcancelstate, pthread_setcanceltype
  
     Handling von private Thread-Daten
       SOLARIS: thr_keycreate, thr_setspecific, thr_getspecific
       LIN/SOLARIS: pthread_key_create, pthread_key_delete,
                    pthread_getspecific, pthread_setspecific



nextback          2017 - 29





  2. Manipulation von Attributen für Variable
  
       LIN/SOLARIS:
                pthread_mutexattr_init, pthread_mutexattr_destroy,
                pthread_mutexattr_gettype, pthread_mutexattr_settyp
                pthread_condattr_init, pthread_condattr_destroy,
       SOLARIS:
                pthread_mutexattr_getprioceiling,
                pthread_mutexattr_setprioceiling,
                pthread_mutexattr_getprotocol,
                pthread_mutexattr_setprotocol,
                pthread_mutexattr_getpshared,
                pthread_mutexattr_setpshared,
                pthread_condattr_getshared, 
                pthread_condattr_setshared















nextback          2017 - 30





  3.2.2. Thread Bibliotheksrufe (SOLARIS/DEC/LINUX/POSIX) 
  -------------------------------------------------------
  Include-File: thread.h  (pthread.h für POSIX-Threads)
  
     typedef unsigned int thread_t;
     typedef unsigned int thread_key_t;
     size_t		thr_min_stack(void);
     #define	THR_MIN_STACK	thr_min_stack()
     /*  thread flags (one word bit mask) */
     #define	THR_BOUND		0x00000001
     #define	THR_NEW_LWP		0x00000002
     #define	THR_DETACHED		0x00000040
     #define	THR_SUSPENDED		0x00000080
     #define	THR_DAEMON		0x00000100
     thread_t	thr_self();
     void		thr_yield(void);
     ...
  Bemerkungen zur Compilierung:
  
  SOLARIS/LIN:
       pthreads:
  
         gcc [ flag ... ] file ...  -lpthread [ library ... ]
  
  SOLARIS:
       thread:
  
         gcc [ flag ... ] file ...  -lthread [ library ... ]
  

nextback          2017 - 31





  1. Syncronisationshilfen      
  
  Operationen mit Mutexobjekten (Mutex)
    Mutex's werden dazu benutzt die Abarbeitung von Threads zu
    Serialisieren. Sie stellen sicher, das immer nur ein Thread in
    einem kritischen Bereich ist (Mehrfachausschluss). Wenn man
    Mutex's in SharedMemory-Bereichen plaziert, kann man damit auch
    Threads von verschiedenen Prozessen synchronisieren. Über Mutex's
    werden Threads bezüglich des Zugriffs auf kritische Daten 
    synchronisiert. Ein Mutex sollte immer nur für einen kritischen 
    Bereich benutzt werden.
  
  Mutexobjekt erzeugen
  
    SOLARIS:
      int mutex_init(mutex_t *mp, int type, void *arg);
    LIN/SOLARIS:
      int pthread_mutex_init(pthread_mutex_t *mp,
                              pthread_mutexattr_t attr);
   
      [pthread_]mutex_init() erzeugt und initialisiert ein Mutexobjekt mp.
  
      type kann folgende Werte annehmen:
        USYNC_PROCESS - Synchronisation von mehreren Prozessen, einer
                        darf nur mutex_init() abarbeiten, arg ignoriert
        USYNC_THREAD  - Synchronisaton von Threads in einem Prozess,
                        arg ignoriert.
         Bemerkung: potentiell können weitere Typen spezifiziert werden,
         dann wird arg zur Initialisierung von  mp  benutzt.

nextback          2017 - 32





  
      attr spezifiziert ebenfalls den Type eines Mutexobjektes 
      (pthread_mutexattr_init()). 
        Default-Werte für attr: NULL (SOLARIS/LIN)
  
    Rückkehrwerte:
           0  -  Ok
           EINVAL - falsches Argument
           EFAULT - mp oder arg zeigen auf unzulässige Adressen
  
    Vereinfachung:
       #include <pthread.h>
       pthread_mutex_t mutexobjekt=PTHREAD_MUTEX_INITIALIZER;
              entspricht:
       pthread_mutex_t mutexobjekt;
       pthread-mutex_init(mutexobjekt,NULL);
  
  
  Mutexobjekt streichen
  
    SOLARIS:
      int mutex_destroy(mutex_t *mp);
    LIN/SOLARIS:
      int pthread_mutex_destroy(pthread_mutex_t *mp);
  
      [pthread_]mutex_destroy() hebt alle Zustände bezüglich des 
      spezifizierten Mutexobjektes mp auf.
  
    Rückkehrwerte:
           wie [pthread_]mutex_init()
nextback          2017 - 33





  Mutexobjekt sperren
  
    SOLARIS:
      int mutex_lock(mutex_t *mp);
    LIN/SOLARIS:
      int pthread_mutex_lock(pthread_mutex_t *mp);
  
      Sperren des Mutexobjektes auf das mp zeigt. Wenn das Mutexobjekt
      bereits gesperrt war, wartet der aktuelle Thread bis das 
      Mutexobjekt freigegeben wird.
    Rückkehrwerte:
          wie [pthread_]mutex_init()
  
  Mutexobjekt prüfen und sperren
  
    SOLARIS:
      int mutex_trylock(mutex_t *mp);
    LIN/SOLARIS:
      int pthread_mutex_trylock(pthread_mutex_t *mp);
  
      [pthread_]mutex_trylock versucht das Mutexobjekt auf das mp zeigt zu
      sperren. Dazu wird als erstes geprüft ob das Mutexobjekt bereits 
      gesperrt war. Ist dies der Fall, kehrt [pthread_]mutex_trylock() mit
      EBUSY zurück, andernfalls wird der Thread Eigentümer des Mutexobjektes,
      das Mutexobjekt wird gesperrt und der Thread setzt die Arbeit fort.
    Rückkehrwert:
         0  -  Ok
         EINVAL - falsches Argument
         EFAULT - mp oder arg zeigen auf unzulässige Adressen
         EBUSY  - Mutex war bereits gelockt
nextback          2017 - 34





  Mutexobjekt entsperren
  
    SOLARIS:
      int mutex_unlock(mutex_t *mp);
    LIN/SOLARIS:
      int pthread_mutex_unlock(pthread_mutex_t *mp);
  
      [pthread_]mutex_unlock() gibt nach einem [pthread_]mutex_lock() bzw.
      erfolgreichem [pthread_]mutex_trylock() das Mutexobjekt wieder frei.
    Rückkehrwert:
         0  -  Ok
         EINVAL - falsches Argument
         EFAULT - mp oder arg zeigen auf unzulässige Adressen
  
  Zur Verwaltung der Attribute von Mutexobjekten stehen folgende
  Systemrufe zur Verfügung:
    LIN/SOLARIS: 
      int pthread_mutexattr_init(pthread_mutexattr_t *attr);
      int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
    SOLARIS:
      int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,
                     int process-shared);
      int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr,
                int *process-shared);
      nicht unterstützt
           pthread_mutexattr_getprioceiling
           pthread_mutexattr_getprotocol
           pthread_mutexattr_setprioceiling
           pthread_mutexattr_setprotocol

nextback          2017 - 35





  Bedingte Mutexobjekte
    Bedingte Mutexobjekte erlauben einen mehrfachen Zugriff auf 
    ein Mutexobjekt.  Die Synchronisation erfolgt über Bedingungen,
    die an ein Mutexobjekt gebunden sind.
  
  Initialisieren eines bedingten Mutexobjektes
    SOLARIS:
      int cond_init(cond_t *cvp, int type, void *arg);
    LIN/SOLARIS:
      int pthread_cond_init(pthread_cond_t *cond,
                    const pthread_condattr_t *attr);
      Initialisieren eines bedingten Mutexobjektes *cond mit den Werten
      des Attributes attr. Defaultwerte für attr sind:
        SOLARIS:  NULL     und LIN: pthread_condattr_default
      Bedingte Mutexobjekte sollten global addressiert werden.
    Rückkehrwerte:
         0   -  OK
        EFAULT - Illegale Adresse      EINVAL - unzulässiger Wert
  
  Streichen eines bedingten Mutexobjektes
    SOLARIS:
       int cond_destroy(cond_t *cond);
    LIN/SOLARIS:
       int pthread_cond_destroy(pthread_cond_t *cond);
  
      Freigeben eines bedingten Mutexobjektes. Das Verhalten des
      Systems ist unbestimmt, wenn noch ein Thread dieses 
      Objekt benutzt([pthread_]cond_timedwait, [pthread_]cond_wait).
  
    Rückkehrwerte: siehe pthread_cond_init
nextback          2017 - 36





  Warten auf eine Signalisierung 
     SOLARIS:
       int cond_wait(cond_t *cond, mutex_t *mp);
     LIN/SOLARIS:
       int pthread_cond_wait(pthread_cond_t *cond,
                       pthread_mutex_t *mp);
  
       Warten auf ein Signale für das spezifizierte bedingte Mutexobjekt
       cond . Das zuvor mit [pthread_]mutex_lock() gesperrte Mutexobjekt
       mp  wird für die Zeit des Wartens freigegeben. 
       [pthread_]cond_wait()  wird durch [pthread_]cond_signal() oder 
       [pthread_]cond_broadcast() aktiviert. 
     Rückkehrwerte: siehe pthread_cond_init
  
  Warten auf eine Signalisierung mit Timelimit
    SOLARIS:
       int cond_timedwait(cond_t *cond, mutex_t *mp,
            timestruc_t *abstime);
    LIN/SOLARIS:
       int pthread_cond_timedwait(pthread_cond_t *cond,
                       pthread_mutex_t *mp,
                       const struct timespec *abstime);
  
      Warten auf ein Signal für das spezifizierte bedingte Mutexobjekt
      cond . Das zuvor mit [pthread_]mutex_lock() gesperrte Mutexobjekt
      mp  wird für die Zeit des Wartens freigegeben. Es wird ein Fehler
      zurückgegeben, wenn die spezifizierte Absolute Zeit  *abstime 
      abgelaufen ist, ohne das [pthread_]cond_timedwait() durch 
      [pthread_]cond_signal() oder cond_broadcast() aktiviert wurde.
    Rückkehrwerte: siehe pthread_cond_init
nextback          2017 - 37





  Senden eines Signals für eine Bedingung
    SOLARIS:
       int cond_signal(cond_t *cond);
    LIN/SOLARIS:
       int pthread_cond_signal(pthread_cond_t *cond);
  
      [pthread_]cond_signal() sendet ein Signal an das Bedingungsobjekt
      *cond.  Wenn ein Thread mit [pthread_]cond_wait() oder
      [pthread_]cond_timedwait() wartet wird dieser aktiviert und das 
      zugehörige Mutexobjekt gesperrt.  Wenn mehrere Threads warten, 
      wird entsprechend der Schedulingstrategie, der nächste Thread 
      aktiviert.
   
    Rückkehrwerte: siehe pthread_cond_init()
  
  Sendes Broadcast Signals für eine Bedingung
    SOLARIS:
      int cond_broadcast(cond_t *cond);
    LIN/SOLARIS:
      int pthread_cond_broadcast(pthread_cond_t *cond);
  
      [pthread_]cond_broadcast() sendet ein Signal an das Bedingungsobjekt 
      *cond.  Wenn ein Thread mit [pthread_]cond_wait() oder 
      [pthread_]cond_timedwait() wartet wird dieser aktiviert und das 
      zugehörige Mutexobjekt gesperrt.  Wenn mehrere Threads warten, 
      werden alle Threads aktiviert.
  
    Rückkehrwerte: siehe pthread_cond_init


nextback          2017 - 38





  Zur Verwaltung der Attribute von bedingten Mutexobjekten stehen
  folgende Sytemfunktionen zur Verfügung:
    LIN/SOLARIS:
      int pthread_condattr_create(pthread_condattr_t *attr);
      int pthread_condattr_delete(pthread_condattr_t *attr);
    SOLARIS:
      int pthread_condattr_init(pthread_condattr_attr *attr);
      int pthread_condattr_destroy(pthread_condattr_t *attr);
      int pthread_condattr_getpshared(pthread_condattr_t *attr,
           int *process-shared);
      int pthread_condattr_setpshared(pthread_condattr_t *attr,
           int process-shared);
  
  
  
  Weiter ältere Synchronisationsfunktionen (Solaris)
  
     Signalbehandlung für Threads
       thr_sigsetmask, thr_kill
  
     Handling von private Thread-Daten
       thr_keycreate
       thr_setspecific
       thr_getspecific
  





nextback          2017 - 39





  
  Beispiele:
  
          Signale/simple_mutex
          Signale/sig1
          Signale/sig2
          Signale/stat_sigwait























nextback          2017 - 40





  
               3.3. Sonstiges
               ==============
  
  #include <ucontext.h>                         /*AT&T V.4, BSD 4.3*/
  
  int getcontext(ucontext_t *ucp);
  
  int setcontext(ucontext_t *ucp);
  
  Die Funktion  getcontext()  ermöglicht das Erfassen des aktuellen
  Prozesszustandes in der Struktur  ucontext_t. Mit der Funktion 
  setcontext()  kann der zuvor gerettet Prozesszustand wieder her-
  gestellt werden.  Mit Hilfe dieser Funktionen ist sowohl ein 
  schnelles Umschalten innerhalb des Prozesses möglich als auch
  das Setzen der Prozessumgebung innerhalb einer Signalbehandlungs-
  routine.
  
  Rückkehrwert:
        0 - ok (setcontext()  kehrt nicht zurück)
       -1 - Fehler, ucp keine gültige Adresse
  








nextback          2017 - 41





  
  #include <sys/time.h>                        /*BSD 4.3, AT&T V.4*/
  
  int getitimer (int which, struct itimerval *value);
  
  int setitimer (int which, struct itimerval *value, 
                            struct itimerval *ovalue);
  
  BSD unterstützt für jeden Prozess drei Intervaltimer:
  
    1. Realtime-Intervalltimer        - SIGALRM
    2. virueller Intervalltimer       - SIGVTALRM
    3. Intervalltimer für Profiling - SIGPROF
  
  getitimer()  fragt jeweils einen der Intervalltimer ab.
  setitimer()  setzt einen der Intervalltimer. Durch  which  wird
  der jeweilige Intervalltimer bestimmt:
  
       ITIMER_REAL    - Realtime-Intervalltimer
       ITIMER_VIRTUAL - virtueller Intervalltimer
       ITIMER_PROF    - Profiling Timer
  
  *oval!=NULL - alter Wert des jeweiligen Timers.
  
  Rückkehrwert:
       0 - ok
      -1 - Fehler   
            EFAULT - falsche Adresse,  EINVAL - falscher Wert


nextback          2017 - 42





  Zeit- und Prioritätsverwaltung
  -------------------------------
  
  int acct(char *path) 
  
  Ein- bzw. Ausschalten des Accountsystems des UNIX.
  *path - Filename des Accountfiles. Einschalten des Accountsystems.
  *path == NULL - Ausschalten des Accountsystems.
  
  Rückkehrwert:
     0 - ok
    -1 - Fehler
           EACCES, EFAULT, EINVAL, EIO, ELOOP, ENOENT,
           ENOTDIR, EPERM EROFS EBUSY, ENOENT
  
  ---------------------------------------------------------
  
  #include <sys/time.h>
  
  int adjtime(struct timeval *delta, struct timeval *olddelta);
  
  adjtime()  dient zur kontinuierlichen Synchronisation der Zeit.
  Dabei wird die Systemzeit schrittweise um die in *delta angegebenen
  Mikrosekunden korregiert (positiv - vorgestellt, negativ - rückgestellt).
  *olddelta enthält die Angaben der restliche Mikrosekunden von der
  letzten Änderung.
  
  Rückkehrwert:
     0 - ok
    -1 - Fehler
nextback          2017 - 43





  include <sys/time.h>
  
  int settimeofday(struct timeval *tp, struct timezone *tzp);
  int gettimeofday(struct timeval *tp, struct timezone *tzp);
  
  settimeofday()  setzt den Systemzeitgeber.
  gettimeofday()  liest den Systemzeitgeber.
     struct timeval { 
                        long tv_sec;  /* Sekunden seit 1.1.1970 */
                        long tv_usec; /* und Mikrosekunden */
                    }
     struct timezone {
                       int tz_minuteswest; /* minuten westlich
                                               von Greenwich */
                       int tz_dsttime;    /* Type DST */
                     }
  Rückkehrwert:
       0 - ok
      -1 - Fehler
  
  -------------------------------------------------------
  
  #include <sys/typese.h>
  #inlcude <time.h>
  
  int stime(const time_t *tp);
  
  stime()  setzt den Systemzeitgeber auf den Wert *tp, der die
  Zahl der Sekunden seit 1.1.1970 00:00:00 Uhr angibt. Nur für SU.

nextback          2017 - 44





  
  #include <sys/typese.h>
  
  #inlcude <time.h>
  
  time_t time(time_t *tlock)      (veraltet, heute gettimeofday)
  
  time()  gibt den die Zeit in Sekunden zurück, die seit dem 1.1.1970
  00:00:00 Uhr vergangen ist. Rückgabe erfolgt sowohl in *tlock als
  auch als Rückkehrwert. 
  
  ---------------------------------------------------------
  
  #include <sys/types.h>
  #include <sys/times.h>
  
  clock_t times(struct tms *buffer);
  
  times gibt die verbrauchte CPU-Zeit in Ticks in der Struktur *buffer
  zurück.
         struct tms {
                clock_t   tms_utime;  /* Nutzerzeit */
                clock_t   tms_stime;  /* Systemzeit */
                clock_t   tms_cutime;  /* Nutzerzeit Kind*/
                clock_t   tms_cstime;  /* Systemzeit Kind*/
         }
  
  Der Rückkehrwert ist die vergangene Zeit seit dem Systemstart in
  Ticks.

nextback          2017 - 45





  #include <sys/label.h>
  #include <sys/audit.h>
  
  int auditsvc(inf fd, int limit);
  
  int auditon(int condition);
  
  int audit(audit_record_t *record)
  
  auditsvc() spezifiziert den Filedescritor und den Speicherplatz für
  das Audit-Log des Kerns. limit  spezifiziert den freien Platten-
  speicherplatz in Prozent und fd ist der Filedescriptor eines zum 
  Schreiben eröffneten Files.
  auditon() ein- bzw. ausschalten des Audit-Log.
  audit() schreiben eines Datensatzes in das Audit-Log-File.
  
  Rückkehrwert:
      0 - ok
     -1 - Fehler
  










nextback          2017 - 46





  
  #include <sys/label.h>
  #include <sys/audit.h>
  
  int setuseraudit(int uid, audit_state_t *state);
  int setaudit (audit_state_t *state);
  
  Festlegen des UID für die Audit-Sätze geschrieben werden 
  sollen. setaudit()  UID  des aktuellen Prozesses.
  
  Rückkehrwert:
     0 - ok
    -1 - Fehler
  
  ------------------------------------------------------------------------
  
  int profile(short *buf, int bufsiz, void (*offset)(), int scale);
  
  Einschalten des Profiling. buf - Adresse des Puffers für Statistik.
  bufsize  -  Länge des Puffers in Byte, offset ist der Beginn des zu
  testenden Bereich. scale  dient der Skalierung (0xffff - 1:1 Abbildung,
  0x2 - 1 Eintrag, 0,1 - ausschalten).
  
  Rückkehrwert:
     0 -  ok
    -1 -  Fehler




nextback          2017 - 47





  #include <signal.h>          /*BSD*/
  #include <sys/ptrace.h>          /*BSD*/
  #include <sys/wait.h>          /*BSD*/
  #include <unistd.h>         /*V4.x*/
  #include <sys/types.h>         /*V4.x*/
  
  int ptrace(enum ptracereq request, int pid, char *addr, int data
             [,char *addr2]);
  
  ptrace() erlaubt dem aktuellen Prozess die Abarbeitung eines anderen
  Prozesses  pid  zu steuern und in ihm Veränderungen vorzunehmen.
  Nur für SU.
  
  Rückkehrwert:
        0 - ok
       -1 - Fehler (EIO, EPERM, EPERM)
  
  ------------------------------------------------------------------------
  
  int nice(int incr);
  
  Änderung der aktuellen Priorität. incr > 0 Verringerung der Priorität.
  incr < 0 Erhöhung der Priorität (nur SU).
  
  Rückkehrwert:  
         >=0 -  neuer nice-Wert (ok
         -1  -  Fehler



nextback          2017 - 48





  #include <sys/time.h>                            /*BSD*/
  #include <sys/resource.h>
  
  int getpriority(int which, int who);
  int setpriority(int which, int who, int niceval);
  
  Holen bzw. setzen der Prozesspriorität.
          which                who
        PRIO_PROCESS           PID         Prozess
        PRIO_PGRP              PPGRID      Prozessgruppe
        PRIO_USER              UID         Nutzer
  niceval   -  Priorität (-20  .. 19)
  Rückkehrwert:
           setpriority :  0  - ok       getpriority: Nicewert
                         -1  - Fehler
  -----------------------------------------------------------------------
  #include <sys/types.h>                  /*AT&T V.4*/
  #include <sys/priocntl.h>
  #include <sys/rtpriocntl.h>
  #include <sys/tspriocntl.h>
  
  long priocntl(idtype_t, idtype, id_t id, int cmd,  ... /*arg*/);
  long priocntlset(procset_t *psp, int cmd, ... /*arg*/);
  
  Holen bzw. setzen der Prozesspriorität. cmd  spezifiziert die Funktion.
  Die Argumente werden entsprechend dem Kommando spezifiziert und enthalten
  bestimmte Prioritätsangaben.
  Rückkehrwert:
         0 - ok
        -1 - Fehler(EAGAIN, EFAULT, EINVAL, ENOMEM, EPERM, ERANGE, ESRCH)
nextback          2017 - 49





  
  
  Systemsteuerung und Systeminformationen
  ---------------------------------------
  
  
  int getdomainname(char *name, int namelen);
  
  getdomainname gibt den NIS-Domainname in *name zurück.
  namelen  ist die maximale Lenge. Domainname darf maximal 64
  Zeichen lang sein.
  Rückkehrwert:
       0 - ok
      -1 - Fehler
  
  
  -------------------------------------------------------------
  
  
  int setdomainname(char *name, int namelen);
  
  setdomainname erlaubt das Setzen des NIS-Domainname *name mit
  der Länge  namelen.
  Rückkehrwert:
       0 - ok
      -1 - Fehler
  



nextback          2017 - 50





  
  int gethostname(char *name, int namelen);
  
  Holen des Host-Name in *name mit der maximalen Länge namelen.
  Rückkehrwert:
       0 - ok
      -1 - Fehler 
  
  Beispiel:  Signal/gethost.c   # Hostnamen auslesen
  
  
  
  
  int sethostname(char *name, int namelen);
  
  Setzen des Host-Namen *name mit der Länge namelen.
  Rückkehrwert:
       0 - ok
      -1 - Fehler
  
  
  
  
  long gethostid(void);
  Auslesen des Host-ID's (32-Bit-Zahl).
  
  Beispiel:     Signal/hostid.c     #  Host-ID auslesen



nextback          2017 - 51





  #include <sys/utsname.h>
  int uname(struct utsname *name);
  
  Holt in der Struktur utsname den Namen und weitere Angaben über das
  System.
      struct utsname {
             char sysname[9];   /*OS-Name*/
             char nodename[9];  /*Host-Name*/
             char nodeext[65-9];/*langer Host-Name*/
             char release[9];
             char version[9];
             char machine[9];
       }
  Rückkehrwert:
          0 - ok
         -1 - Fehler














nextback          2017 - 52





  
  #include <sys/systeminfo.h>                  /*AT&T V.4*/
  
  long sysinfo(int cmd, char *buf, long count);
  
  Kopieren von Informationen über das aktuelle System auf dem der
  Prozess läuft in den Puffer  *buf mit der Länge count.
  cmd  spezifiziert die gewünschte Information.
  
     SI_SYSNAME           -  OS-Name
     SI_HOSTNAME          -  Hostname
     SI_SET_HOSTNAME      -  setzen Hostname
     SI_RELEASE           -  Release
     SI_VERSION           -  Version
     SI_MACHINE           -  Maschinentype 
     SI_ARCHITECTURE      -  Architektur
     SI_HW_PROVIDER       -  Hersteller
     SI_HW_SERIAL         -  Seriennummer
     SI_SRPC_DOMAIN       -  Domainname
     SI_SET_SRPC_DOMAIN   -  setzen Domainname










nextback          2017 - 53





  
  #include <sys/time.h>
  #include <sys/resource.h>
  
  int getrlimit(int resource, struct rlimit *rlp);
  int setrlimit(int resource, struct rlimit *rlp);
  
  Lesen und setzen von Ressourcenlimits.
  
    resource:  RLIMIT_CPU   -  CPU-Zeit in Sekunden
               RLIMIT_FSIZE -  Grösste Filelänge
               RLIMIT_DATA  -  Grösse Datensegment
               RLIMIT_STACK -  Grösse Stacksegment
               RLIMIT_CORE  -  Grösste Länge eines Core-Files
               RLIMIT_RSS   -  Grösster blegter HS
               RLIMIT_NOFILE-  Anzahl der Deskriptoren
  
    struct rlimit {
              int rlim_cur;   /*current (soft)limit */
              int rlim_max;   /*hard limit */
     }
  
  Rückkehrwert:
         0 - ok
        -1 - Fehler        
  
  Beispiel:  Signal/getres.c



nextback          2017 - 54





  
  #include <sys/time.h>
  #include <sys/resource.h>
  
  int getrusage(int who, struct rusage *rusage);
  
  Auslesen der verbrauchten Ressourcen für den aktuellen Prozess
  (who==RUSAGE_SELF) bzw für die Kindprozesse (who==RUSAGE_CHILDREN).
  
    struct rusage {
             structt timeval ru_utime;  /* user time */
             struct timeval ru_stime;   /*sys time */
             int ru_maxrss; /* max an residenten Seiten */ int ru_ixrss;
             int ru_idrss;  /* durchschn. Seitenzahl*/     int ru_isrss;
             int ru_minflt; /* Page faults, no I/O */
             int ru_majflt; /* Page faults with I/O */
             int ru_nswap;  /* spaps */
             int ru_inblock;/* Block inputs */
             int ru_oublock;/* Block outputs */
             int ru_msgsnd; int ru_msgrcv; int ru_nsignals;
             int ru_nvcsw;  /* contextswitchings for wait */
             int ru_nivcsw; /* contextswitchings for nice */
  }







nextback          2017 - 55





  #include <sys/reboot.h>                              /* BSD */
  
  int reboot(int howto, char *bootargs);
  
  System neu starten.
    howto:
       RB_HALT      - halt
       RB_ASKNAME   - Standardkernel booten
       RB_SINGLE    - reboot und in Single-User-Mode gehen
       RB_DUMP      - coredump anlegen vor dem Reboot
       RB_STRING    - Übergabe spezieller Informationen in
                      *bootargs
  
  -------------------------------------------------------------
  
  #include <sys/uadmin.h>                /* AT&T V.4 */
  
  int uadmin(int cmd, int fcn, int mdep);
  
  Ausführen spezieller Systemsteueroperationen.
       cmd - Kommando
            A_SHUTDOWN
            A_REBOOT
            A_REMOUNT
       fcn - Unterkommandos
            AD_HALT
            AD_BOOT
            AD_IBOOT


nextback          2017 - 56





  #include <sys/syscall.h>
  
  int syscall(int number,.../*arg*/);
  
  syscall erlaubt die Übergabe eines beliebigen Systemrufes an
  den Kernel.
  
  
  -------------------------------------------------------------
  
  #include <unistd.h>
  
  long sysconf(int name);
  
  sysconf()  erlaubt die Bestimmung spezieller Systemkonstanten
  wärend der Laufzeit.
  z.B.
       name                  Bedeutung
       _SC_ARG_MAX           maximale Zahle der Argumente
       _SC_CHILD_MAX         maximale Zahl der Prozesse pro UID
       _SC_CLK_TCK           Ticks pro Sekunde
       _SC_OPEN_MAX          maximale Zahl der Files pro Prozess
       _SC_JOB_CONTROL       Jobcontrol unterstützt
       _SC_SAVED_IDS         Saved ID's unterstützt
       _SC_VERSION           POSIX-Version
                                                         
  Beispiel:  Signal/sysconf.c



back               2017 - 57

Zurück zur Gliederung
Mittwoch, 5. Februar 2020 um 11:10:10 Uhr CET J-P Bell