Diverse C-Fragen

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.

Diverse C-Fragen
Liebe Informatiker,

wir sind zwei hilflose Wirtschaftsinformatiker und hab ein paar C-Versändnisprobleme anlässlich der Aufgabe 7.

1.) waitpid, WNOHANG und errno

Warum kann bei folgendem Code der Fehler “No child processes” auftreten. Wir verstehen die man page so, dass wenn WNOHANG gesetzt ist, waitpid 0 zurückgibt, wenn es keine Kinder gibt… das widerspricht aber der Fehlermeldung?!

while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
	if (pid == -1) {
		if (errno == EINTR) continue;
		perror("waitpid");
		break;
	}
	...
}

2.) fork, switch und default:

Folgender Codeausschnitt funktioniert eigentlich ganz gut:

switch (pid = fork()) {
	case -1: ...;
	case 0:
		for (;;) {
			if (write(sock_new, text, strlen(text)) == -1) {
				if (errno == EINTR) continue;						perror("write");
				break;
			}
			sleep(1);
		}
	default:
		printf("new child %d", (int) pid);
}

Wenn der mit telnet geöffnete socket abgeschossen wird, erzeugt write einen Fehler (connection reset by peer), der dazu führt, dass die Dauerschleife abgebrochen wird. Soweit so gut, aber er gibt dann auch “new child 0” aus. “default:” wird durch nur durchlaufen, wenn kein anderer Fall eintritt. WTF?!

3.) fork, socket und close

Wenn ein socket geöffnet und danach der Prozess geforkt wurde. Muss close(socket_fd) dann sowohl im Kind als auch im Vater geschlossen werden oder reicht das einmal?

Vielen Dank schon mal für eure Hilfe!

A+O


Die switch Anweisung durchläuft ab dem ersten Fall der zu trifft eben jenen Fall UND auch alle drauffolgenden.(bei den drauffolgenden Fällen werden dabei nicht einmal mehr die Bedingungen geprüft,sondern direkt die Anweisung ausgeführt)
Wenn du das nicht willst musst du ein break hinmachen…dann durchläuft er nur den einen Fall…


Über den Fehler bin ich auch mal gestolpert. Soweit ich das verstanden habe, gibt waitpid() mit WNOHANG 0 zurück, wenn es im vorherigen Aufruf einen Zombie abgearbeitet hat, und nun beim aktuellen Aufruf kein Child mehr vorhanden ist. Wenn waitpid() aufgerufen wird und es überhaupt keine Zombies gibt, die abzuarbeiten sind, dann wird -1 zurückgegeben.
Wenn waitpid() ohne WNOHANG also blockieren würde, gibt es so -1 zurück und setzt errno auf ECHILD.

Die manpage ist auf den ersten Blick vielleicht etwas missverständlich formuliert:


Hi,

zu den sockets. Beim timed habe ich genau so einen Fehler gemacht und die Verbesserung ist wie folgt:

du holst dir nen socket mit fd = socket(…);

machst dann nen bind und irgendwann nen accept.

der accept Aufruft gibt dir wieder nen fd_neu zurück. Danach forkst du und arbeitest im Kinfprozess mit fd_neu. D.h. du brauchst hier den fd nicht mehr und schließt ihn mit close(fd).
Wichtig ist noch: fd_neu verwendet man dann im Normalfall um die Daten zu übertragen (fd steht für neue Verbindungen zur Verfügung), d.h. im Vaterprozess kannst du sofort close(fd_neu) ausführen, da du ihn hier nicht brauchst. Natürlich musst du im Kindprozess am Ende dann auch noch einen close(fd_neu) schreiben.

Jo, langer Rede kurzer Sinn: ja, man muss in beide Prozessen alle Sockets wieder schließen.

Ich hoffe mal, dass ich hier keinen Blödsinn erzählt habe, wenn doch, will ich noch ein paar Punkte auf timed :wink:


Danke schön, euch dreien! Nun läuft es, wie es sollte :*)