diff --git a/gen.pl b/gen.pl
index 3ff6584be45661dfdf4f70c0c5b4ffd352e8d0a6..0180d5f512d9be2be9e7e7ad93a52235ade3cb27 100755
--- a/gen.pl
+++ b/gen.pl
@@ -9,7 +9,8 @@ use IPC::Open2;
 use Digest::MD5 qw(md5_base64);
 
 my @hlwords  = qw/immer nie jede jedem jedes muss keine alle nicht/;
-my @markdown = qw/pandoc -f markdown+smart --html-q-tags --ascii/;
+my @markdown = qw/pandoc -f markdown+smart+fenced_code_blocks+backtick_code_blocks --html-q-tags --ascii/;
+# my @markdown = qw/cat/;
 
 my $question;
 my $single_choice;
@@ -99,11 +100,11 @@ while (<>) {
       $question =~ s/\Q($source)\E//;
       chomp $source;
     }
-  } elsif (/^[|](.+)/) {
+  } elsif (/^[|](.*)/) {
     if ($last_option{"option"}) {
-      $last_option{"option"} .= $1;
+      $last_option{"option"} .= "$1\n";
     } else {
-      $question .= $1;
+      $question .= "$1\n";
     }
   } elsif (/^@(.*)/) {
     $media = $1;
diff --git a/ss22.q b/ss22.q
index 102bdb928fd48a52ec3394c8b574f8c34285b748..9daf2ff790a300e675fd8bc6ce3c348736dab696 100644
--- a/ss22.q
+++ b/ss22.q
@@ -118,11 +118,61 @@ Nein. Hier sind beide falsch.
 - Seitennummer 0x2, Offset 0x8
 Nein. Hier ist der Offset offensichtlich falsch.
 - Seitennummer 0x8, Offset 0x2
-Nein. Da hier der Offset 10 Bit und kein Vielfaches von 4 hat, darf man nicht einfach die Hexadezimaldarstellung an der Grenze eines *nibbles* (= Halbbyte, 4 Bit, ein Zeichen in Hexadezimaldarsetllung) zerlegen.
+Nein. Da hier der Offset 10 Bit und kein Vielfaches von 4 hat, darf man nicht einfach die Hexadezimaldarstellung an der Grenze eines *nibbles* (= Halbbyte, 4 Bit, ein Zeichen in Hexadezimaldarsetllung) zerlegen. Deswegen ist hier die Seitennummer falsch.
 .
 
 0 Welche Aussage zu UNIX/Linux-Dateideskriptoren ist korrekt?
-+
--
++ Nach dem Aufruf von fork(2) teilen sich Eltern und Kindprozess die den gemeinsamen Dateideskriptoren zu Grunde liegenden Kernel-Datenstrukturen.
+Ja, vergleiche zum Beispiel `sister`, bei der ein Kindprozess für die Bearbeitung einer Anfrage zuständig war und den Dateideskriptor verwendet, der im Elternprozess von `accept(3)` zurückgegeben wurde.
+- Da Dateideskriptoren Zeiger auf Betriebssystem-Interne Strukturen sind, können diese zwischen Prozessen geteilt werden.
+Der Dateideskriptor ist lediglich ein Index in die Dateideskriptortabelle pro Prozess im *kernel space*. Da diese nicht geteilt ist, ist auch das Teilen von Dateideskriptoren im Allgemeinen nicht zielführend.
 - Der Dateideskriptor enthält die nötigen Metadaten einer Datei und ist auf der Festplatte gespeichert.
--
+Nein, das wäre die `inode`. Der Dateideskriptor ist eine Referenz (jedoch kein Pointer) auf eine Datenstruktur im Betriebssystem, die u. a. auch die Position des Prozesses in der Datei enthält.
+- Das Flag `FD_CLOFORK` eines Dateideskriptors sorgt dafür, dass der Dateideskriptor bei einem Aufruf von `fork(2)` automatisch geschlossen wird.
+Nein, dieses Flag existiert nicht. Angespielt wird hier auf `FD_CLOEXEC`, was die beschriebene Wirkung bei einem Aufruf von `exec(3)` zeigt.
+.
+
+0 Welche Aussage über die Koordinierung von kritischen Abschnitten unter Unix ist richtig?
++ Für die Synchronisation zwischen dem Hauptprogramm und einer Signalbehandlungsfunktion sind Schlossvariablen (Locks) ungeeignet.
+Ja. Signalbehandlung stellt asymmetrische Nebenläufigkeit dar. Der aktuelle Ausführungsstrang wird also unterbrochen, um zum *signal handler* zu springen. Wenn dieser nun versucht, ein *lock* zu sperren, das schon vom Hauptprogramm gesperrt wurde, so wartet dieser auf das Hauptprogramm, welches jedoch durch die Signalbehandlung unterbrochen ist. Es kommt zu einer Verklemmung (*deadlock*).
+- Ein Unix-Prozess kann durch das Sperren von Unterbrechungen (Interrupts) den Speicherzugriff in einem kritische Abschnitte [sic!] synchronisieren.
+Nein. Einerseits ist das Sperren von Interrupts, die ja nicht notwendigerweise im Zusammenhang mit dem Prozess stehen müssen, eine privilegierte Operation, die dem Betriebssystem vorenthalten ist. Andererseits würde dies bei manchen Formen von Nebenläufigkeit nicht den gewünschten Effekt erzielen, da z. B. auf einem Multiprozessorsystem mehrere leichtgewichtige Prozesse (*kernel-level threads*) echt nebenläufig Speicherzugriffe durchführen können, ohne dass einer der Prozesse durch einen Interrupt verdrängt wird.
+- In einem Unix-Prozess kann es keinen kritischen Abschnitt geben, da immer nur ein Aktivitätsträger pro Prozess aktiv ist.
+Nein. Die Ressourcen eines schwergewichtigen Prozesses können zwischen verschiedenen leichtgewichtigen Prozessen geteilt sein, die nebenläufig einen Aktivitätsstrang ausführen.
+- Kritische Abschnitte können unter Unix nur mit Semaphoren synchronisiert werden.
+Nein. es gibt vielerlei Synchronisationsmechanismen für verschiedene Arten von Nebenläufigkeit, für kritische Abschnitte kann insbesondere auch `pthread_mutex` verwendet werden.
+.
+
+1 Welche der Aussagen zum folgenden Programmfragment sind richtig?
+|
+|
+|~~~~~
+|static int a = 2022;
+|void f1 (const int *y) {
+|    static int b;
+|    int c;
+|    char *d = malloc(0x802);
+|    void (*e)(const int *) = f1;
+|    y++;
+|    //...
+|}
+|~~~~~
+|
+
++ `e` liegt im Stacksegment und zeigt in das Textsegment.
+Ja. `e` ist ein Zeiger auf die Funktion `f1`. Funktionen liegen im Textsegment. Zudem ist `e` eine lokale Variable, liegt also im Stacksegment.
+- `c` ist mit dem Wert 0 initialisiert.
+Nein, denn nur globale Variablen werden mit 0 initialisiert, wenn sie nicht anderweitig initialisiert werden. `c` ist uninitialisiert.
+- Die Anweisung `y++` führt zu einem Laufzeitfehler, da `y` konstant ist.
+Ja. Das Ziel von `y` ist hier `const`, `y` selbst jedoch nicht. Pointerarithmetik auf `y` ist also erlaubt. Eine Merkregel hierfür lautet "`const` bezieht sich auf das Schlüsselwort links davon, außer es steht ganz links. Dann bezieht sich `const` auf das Schlüsselwort rechts davon." Hier bezöge sich const also auf `int`, nicht auf `*`.
++ `d` ist ein Zeiger, der in den Heap zeigt.
+Ja. Mit `malloc(3)` wird Heapspeicher allokiert.
++ `a` liegt im Datensegment.
+Ja. `a` ist eine globale Variable. Globale Variablen liegen im Datensegment. `a` liegt im Datensegment.
+? `y` liegt im Stacksegment.
+Gemäß der x86_64-POSIX-ABI liegen Funktionsparameter wie `y` in einem Register, das ist jedoch nicht plattformunabhängig garantiert. Ich vermute trotzdem, die erwartete Antwort hier ist "ja".
+- `b` liegt im Stacksegment.
+Durch die Verwendung von `static` innerhalb einer Funktion erzeugt man eine Variable, die zwar nur in diesem Gültigkeitsbereich sichtbar ist, jedoch die Semantik einer globalen Variable besitzt. Demnach liegt `b` im Datensegment.
+- Die Speicherstelle, auf die `d` zeigt, verliert beim Rücksprung aus der Funktion `f1()` ihre Gültigkeit.
+Nein, da diese Speicherstelle im Heap liegt und - im Gegensatz zu Stackspeicher - erst durch den Aufruf von `free(3)` ungültig wird.
+.
diff --git a/ws19.q b/ws19.q
index f9d603088443a4db00feb1d7321d9de4254a96da..0cfecfd83b7d56ba03d31dce7800535746abf918 100644
--- a/ws19.q
+++ b/ws19.q
@@ -51,21 +51,22 @@
   Nein, ein Zeiger wird immer noch als Wert an eine Funktion übergeben, d. h. es wird eine Kopie des Zeigers in das entsprechende Register
   oder auf den Stack abgelegt. Das ein Zeiger eine Referenz auf eine Speicherstelle *ist*, spielt hierbei keine Rolle.
   Beispiel: Würde die Aussage stimmen, so würde das folgende Programm "10" ausgeben. Es gibt jedoch "5" aus.
-  ```c
-  #include <stdio.h>
-  static int b = 10;
 
-  static void pointers_are_values_too(int* arg) {
-    arg = &b; // arg zeigt hier auf b, ptr in main bleibt aber unverändert.
-  }
+~~~
+#include <stdio.h>
+static int b = 10;
 
-  int main(void) {
-    int a = 5;
-    int* ptr = &a; // ptr zeigt auf a.
-    pointers_are_values_too(ptr);
-    printf("%d\n", *ptr); // ptr zeigt immer noch auf a.
-  }
-  ```
+static void pointers_are_values_too(int* arg) {
+  arg = &b; // arg zeigt hier auf b, ptr in main bleibt aber unverändert.
+}
+
+int main(void) {
+  int a = 5;
+  int* ptr = &a; // ptr zeigt auf a.
+  pointers_are_values_too(ptr);
+  printf("%d\n", *ptr); // ptr zeigt immer noch auf a.
+}
+~~~
 .
 
 0 Welche Aussage zu Programmbibliotheken ist richtig? (2020-02)