Betriebssysteme Letschert - Übung 3

Aufgabe 1

  1. Was ist ein CGI-Skript? Warum sind CGI-Skripte oft in Perl geschrieben? Was ist "Perl"?

    CGI-Skripte sind Skripte, die auf einem Webserver laufen und dort dynamisch Webinhalte, normalerweise HTML-Seiten, erzeugen. CGI-Skripte können Benutzereingaben aus HTML-Formularen verarbeiten.
    CGI-Skripte werden gerne in Perl geschrieben, weil Larry Wall so ein netter Mensch ist oder einfach weil man in Perl sehr einfach Strings verarbeiten und mit Dateien umgehen kann.
    Perl ist eine Skriptsprache, die vor allem wegen der kryptischen, aber mächtigen Regulären Ausdrücke gefürchtet ist. Hat man die einmal verstanden, wird man Perl schnell nicht nur für Web-Seiten verwenden, sondern auch zum Parsen, Durchsuchen, Formatieren und Konvertieren von Text, Quellcode usw.

  2. Wann ist eine Datei "ausführbar"?

    Unter Unix, wenn sie als ausführbar markiert ist, z.B. mit chmod [augo]+x <Datei>. Unter Windows muss eine Ausführbar, wenn Sie die Endung .exe hat.

  3. Was sind die Standard-Deskriptoren für Eingabe, Ausgabe und Fehler?

      C++ C File Handle
    Eingabe cin STDIN_FILENO 0
    Ausgabe cout STDOUT_FILENO 1
    Fehler cerr STDERR_FILENO 2

  4. Was ist ein Filter, was versteht man unter Ein- und Ausgabeumleitung?

    Eingabeumleitung:
    Die Standardeingabe (das, was normalerweise auf der Tastatur eingegeben wird) kommt aus einer Datei. Beispiel:

    sort < Datei
    
    gibt Datei sortiert am Bildschirm aus

    Ausgabeumleitung:
    Die Standardausgabe wird in eine Datei umgeleitet. Davon gibt es allerdings zwei: die Standardausgabe (cout) und die Standardfehlerausgabe (cerr). will man beispielsweise diese html-Seite sortieren und das Ergebnis in eine Datei schreiben, lautet der Befehl:

    sort < index.html > totales_chaos.html
    
    Oder man ist der vielen Fehlermeldungen überdrüssig und schickt mit
    befehl 2> /dev/null
    
    alle Fehlermeldungen ins Nirvana.

    Ein Filter filtert die Standardausgabe. Zum Beispiel kann man die Ausgabe von ls sortieren lassen:

    ls | sort
    
    oder bei der Ausgabe von ls alle as durch es ersetzen:
    ls | perl -p -e 's/a/e/g;'
    

  5. Was ist ein Pipe? Welche Art von Software ist sie: eine Funktion, ein Programm, Prozess, Klasse, Objekt, ...?

    Ein Pipe ist ein Kommunikationskanal zwischen verwandten Prozessen. Es gubt zwei verschiedene Arten von Pipes: benannte und unbenannte. Unbenannte Pipes werden mit dem Systemaufruf pipe erzeugt. Benannte Pipes, sog. FIFOs, werden als Pseudodateien im Dateisystem erzeugt mit

    mkfifo <fifo>
    

  6. Wie benutzt ein Prozess eine Pipe und was versteht man unter "blockieren"? Kann ein Prozess bei der Benutzung einer Pipe blockieren?

    Eine Pipe wird mit dem Befehl pipe erzeugt. Die zurückgegebenen file handles werden wie Dateien benutzt.

    Blockieren heisst offenbar, dass der Schreiberprozess schlafen gelegt wird, wenn die Pipe voll ist bzw. der Leserprozess schlafen gelegt wird, wenn die Pipe leer ist. Bitte kommentieren!

  7. Welche Wirkung hat das Kommando
    cat < dat-1.txt 2>&1 | sort > dat-2.txt
    

    Die Datei dat-1.txt inklusive Fehlermeldungen sortiert in dat-2.txt geschrieben.

  8. Was ist ein Dateisystem?

  9. Was versteht man unter dem öffnen einer Datei? Wie wird die Datei verändert?

    Die Datei wird für einen Prozess zugreifbar gemacht, so dass er mit Befehlen wie read oder write darauf zugreifen kann. Die Datei selbst wird dabei nicht verändert, möglicherweise aber einige Dateiattribute, meistens atime ("access time").

  10. Können zwei unterschiedliche Prozesse die gleiche Datei öffnen?

    Ja. Bei gleichzeitigem lesendem Zugriff gibt es keine Probleme, sobald ein Schreiber dabei ist, wird es schwierig.

    Beispiel 1: tail

    Der Befehl tail -f <Datei> zeigt die letzten paar Zeilen einer Date an und zeigt ausserdem alle Zeilen an, die der Datei (von einem anderen Prozess) angehängt werden. Sehr beliebt ist tail bei Logdateien, z.B. tail -f /var/log/messages oder tail -f /etc/httpd/log/error_log. Die sog. Follow-Funktion von tail ist wie folgt implementiert (stark gekürzt und umsortiert; in voller länge bitte selber im tail-Quellcode nachschauen):

    static void tail_forever (struct File_spec *f, int nfiles)
    {
      while (1)
      {
        struct stat stats;
    
        if (fstat (f[i].fd, &stats) < 0) {
          error (0, errno, "%s", pretty_name (&f[i]));
          break;
        }
    
        if (stats.st_size == f[i].size)
        {
          sleep (sleep_interval);
        }
        else
        {
          while (1)
          {
            long n = MIN (n_remaining, (off_t) BUFSIZ);
            bytes_read = safe_read (fd, buffer, n);
            if (bytes_read <= 0)
              break;
            xwrite (STDOUT_FILENO, buffer, bytes_read);
            n_remaining -= bytes_read;
            n_written += bytes_read;
          }
          f[i].size += n_written;
        }
      }
    }
    

    Beispiel 2: konkurrierendes schreiben

    Folgendes Beispiel demonstriert, dass Linux kein problem damit hat, denn zwei Prozesse gleichzeitig in eine Datei schreiben. Das Ergebnis ist allerdings etwas sonderbar.
    Hier das Programm: continuous_write.cc
    Und das Shellskript zum Ausprobieren: continuous_write.sh

    Eine mögliche (von mit aber nicht ausprobierte) Lösung ist das Öffnen der Datei mit dem Flag O_EXCL.

  11. Warum muss das Betriebssystem pro Prozess eine Datenstruktur für jede von diesem Prozess geöffnete Datei anlegen? Warum reicht nicht eine systemweite Datenstruktur pro Datei?

  12. Erläutern Sie den Unterschied zwischen dem Öffnen einer Datei vor bzw. nach einem fork.

  13. Was ist ein Inode

    Ein I-Node ist ein Dateideskriptor im Dateisystem.

  14. Was versteht man unter einem "X-Client" und einem "X-Server"?

    Ein X-Client ist ein Anwenungsprogramm, das unter X läuft.
    Der X-Server ist für die Grafikausgabe und die Eingabe (Tastatur, Maus usw.) zuständig
    Server und Client kommunizieren über einen Socket, entweder direkt oder über Netzwerk