Wieso existiert kein Programm cd
in einem
UNIXSystem?
Warum ist das Kommando cd
als BuiltinKommando
in der Shell implementiert?
Aufgabe 2 (theoretisch, 2 Punkte)
Was genau passiert mit einem Prozeß, der exit()
ausführt? Was ist
der Unterschied zwischen dieser Funktion und _exit()
?
Aufgabe 3 (theoretisch, 2 Punkte)
Was geschieht, wenn ein Prozeß terminiert, dessen Vater schon terminiert ist? Was würde passieren, wenn einfach niemand darauf reagiert?
Aufgabe 4 (theoretisch, 2 Punkte)
Auf welche der folgenden Datenstrukturen hat ein Prozeß A schreibenden Zugriff, wenn er sich im Zustand user running bzw. kernel running befindet:
stdio
Library von Prozeß A
stdio
Library von Prozeß B ?
Aufgabe 5 (theoretisch, 3 Punkte)
Der UnixKern erreicht die UserStructure des gerade aktiven Prozesses einfach
durch Ansprechen der kernglobalen Variablen u
(z.B. u.u_error = ENOMEM
). Wie
ist es möglich, daß der Kern so immer die richtige
UserStructure trifft? Was passiert in diesem Zusammenhang bei einem
Prozeßwechsel? Wie sieht der Adreßraum eines laufenden Prozesses in
etwa aus? (Zeichnung)
Aufgabe 6 (praktisch, 10 Punkte)
Erweitert Eure Shell msh
. Die Shell soll nun in der Lage sein, auch andere als
BuiltinKommandos zur Ausführung zu bringen. Als Erweiterung ist die
Quelldatei command.c
zu schreiben, in der die Funktion do_command()
das ihr
übergebene Kommando ausführen soll. Die Funktion do_command()
liefert
keinen Rückgabewert. Zum Auffinden der Kommandos soll die Shell den in der
EnvironmentVariablen PATH
gesetzten search path benutzen. Das Auftreten
eines ampersand (&
) muß korrekt behandelt
werden.
command.c: void do_command (struct kommando *kp)Beim Start von Prozessen im Hintergrund ist deren ProzeßID auszugeben. Die Shell soll die von ihr gestarteten Hintergrundprozesse von Zeit zu Zeit aus dem zombiestate erlösen, damit die Anzahl der für einen Benutzer zulässigen Prozesse im System nicht erreicht wird oder gar die Prozeßtabelle überläuft. Diese Erlösung soll mit Hilfe des Systemcalls
wait3()
jeweils vor der Ausgabe des Prompts
geschehen. Schreibt
Euch dazu in der Datei command.c
die Funktion do_wait()
, die auf die
Termination eines KindProzesses wartet.
void do_wait (int pid, int mode)Die Funktion
do_wait()
soll auf die Termination des
angegebenen Prozesses warten und liefert keinen Rückgabewert.
Bei der Angabe des Argumentes 0
soll auf die Termination des aktuellen Vordergrundprozesses gewartet werden.
Für jeden erlösten HintergrundProzeß soll eine Meldung etwa in
der Form
pid Done ls -l command.c parser.causgegeben werden. Dazu muß eine Tabelle angelegt werden, die alle zu einem Hintergrundprozeß notwendigen Informationen aufnehmen kann. Zu diesen Informationen gehören mindestens die ProzeßID, der Name und die Argumente des gestarteten Kommandos. Der Einfachheit halber ist diese Tabelle statisch anzulegen. Sie soll aus genau 10 Einträgen bestehen. Ist die Tabelle voll, so ist die Bearbeitung von Hintergrundprozessen mit einer entsprechenden Fehlermeldung zurückzuweisen.
Fehlermeldungen von Systemcalls wie fork()
, execve()
usw. sind mit der Funktion
perror()
anzuzeigen. Pipes und Umlenken
der Ein und Ausgabe müssen erst in der nächsten
Aufgabe realisiert werden.