Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
Miniklausur 14.06.2010
Hallo, ich wuerde gerne mal wissen, wie denn zu der Aufgabe 2 der Miniklausur am 14.06.10 die optimale Loesung aussieht?
Bzw ich habe keine Ahnung, wie ich folgendes erreiche (unter gegebenen Voraussetzungen):
Wie kann man das args Array direkt sortieren, wenn dort ein NULL am Ende sitzt? strcmp schlaegt da fehl.
Wie bekommt der Vater mit, dass alle Childs durch sind und was sie fuer Rueckgabewerte hatten, ohne wait(pid)/sems benutzen zu duerfen?
Was meinst man mit dem dritten Hinweis?
Das hat mit [m]strcmp()[/m] gar nichts zu tun. [m]strcmp()[/m] vergleicht zwei Zeichenketten die jeweils mit 0 terminiert sind. Du bekommst ein Array das mit 0 terminiert ist, welches auf Zeichenketten zeigt, die mit 0 terminiert sind.
Das sieht z.B. so aus:
args[0] = 0x1000; // an 0x1000 steht 'h', 'e', 'l', 'l', 'o', 0
args[1] = 0x2000; // an 0x2000 steht 'w', 'o', 'r', 'l', 'd', 0
args[2] = 0x3000; // an 0x3000 steht '!', 0
args[3] = NULL; // oder 0, ist dasselbe
[m]qsort()[/m] bekommt [m]args[/m] als Argument und die Anzahl der Elemente, hier 3 und deren Groesse, hier [m]sizeof(char *)[/m]. Es sieht die NULL also gar nicht. Die ist nur da, damit du das Ende des Arrays entdecken kannst, ohne die Laenge explizit zu uebergeben (eben analog zu Strings).
[m]strcmp()[/m] bekommt dann 0x1000, 0x2000 und 0x3000 (als [m]const char *[/m]) uebergeben und vergleicht dann die Strings, die an der Stelle im Speicher stehen.
Wieso solltest du hier kein [m]waitpid()[/m] verwenden duerfen? Natuerlich macht man das mit [m]waitpid()[/m].
man [m]execlp()[/m]
Deine erste Schleife ist kaputt, du zaehlst das erste Element doppelt. Danach verwendest du immer counter - 1, besser einfach gleich richtig zaehlen. Ein while ist da einfacher, z.B.
Lass argcop weg und du siehst, dass es weiterhin funktioniert. Allerdings wird damit Speicher des Aufrufers veraendert, was aber nach Angabe erlaubt ist („Das Array args darf direkt sortiert werden.“).
Du rufst [m]execl()[/m] nicht korrekt auf! Das erste Argument ist der Pfad zum Programm, das zweite Argument ist [m]argv[0][/m], was auch wieder der Programmname ist (was meist der Dateiname des Programms ist). Das muss also so aussehen: [m]execl(prg, prg, args, NULL);[/m] (oder wie gefordert mit [m]execlp()[/m]).
Im Kind darfst du kein return machen, sondern exit(1) - sonst laeuft das Kind selbst auch in die main()! Nach dem [m]execlp()[/m] noch auf das Kind mit [m]waitpid()[/m] warten und den Statuscode pruefen ([m]WIFEXITED[/m] und [m]WEXITSTATUS[/m]). Du brauchst noch ne Variable in der du den return-Wert speicherst. Denn falls ein Kind mit != 0 terminiert, soll -1 zurueckgegeben werden; es werden aber trotzdem noch die folgenden Programme gestartet.
War ein Fehler in der Klausur. Da waren keine includes für sys/stat.h und sys/wait.h.
In der Klausur von 2012 ist das auch so: Da fehlt unistd.h obwohl man für das Programm getcwd() braucht.
Ich hätte in der Klausur, falls es mir auffällt, das einfach dazugeschrieben.
Wie darkyke schon schrieb, in so einem Fall einfach die Header hinschreiben (oder einfach so die Funktion verwenden). Ich wuerde (und hab in SP) die Header einfach ignorieren (solange du keine extra angeben musst) und alle Funktionen verwenden die nicht verboten sind.
Sieht gut aus. Ggf. koennte man noch darueber diskutieren, was man machen soll, wenn [m]WIFEXITED()[/m] false ist. Denn dann hat sich das Programm sicher nicht erfolgreich terminiert.
PS: Bitte die Quotes auf die relevanten Teile kuerzen.