geFORK()tes Kind schliesst fremde sockets

Lutz Donnerhacke lutz at iks-jena.de
Mon Sep 15 10:41:28 CEST 2003


* martin.heyer at gmx.de wrote:
>> Der Kind-Prozeß kann keine FDs seines Vaters mehr schließen.

Fast richtig, er hat Dupletten, die er schon schließen kann und das ist bei
Netzwerkkram schon interessant, ob da jemand einseitig den Kanal dicht
gemacht hat (FINs sendet).

>> Vater				| Kind 
>> --------------------------------+------------- 
>> socket();			| 
>> bind();				| 
>> listen();			| 
>> while(1) {			| 
>> 	accept();		| 
>> 	fork();			| 
>> 				| do_some_work(); 
>> 				| exit(); 
>> 	do_some_more_work();	| 
>> 	close();		| 
>> }				| 
>>
>> Sowas macht man gemeinhin nicht:)

Doch:
Man sende den offene Filedescriptor über UNIX-Domain Socket zurück zum Elt.

> Wenn der Child-Prozess ueber exit() aussteigt, dann scheints zu gehen.
> Es sieht aber irgendwie sauberer aus, wenn er das return der main()-Funktion
> nimmt.

C Programme beginnen bei der Routine "_start", die im Prinzip folgendes tut:

void _start(void) {
  int argc;
  char **argv;
  init_libc();
  set_argc_argv(&argc, &argv);
  exit(main(argc, argv, env));
}

Es gibt also keinen Unterschied zwischen return und exit in main.

> Der geforkte client-Prozess soll alles für den Client machen, aber nicht
> am server-Socket (listen) spielen.

elt:
  fctnl(listen_sock, F_SETFD, FD_CLOEXEC);

> Ich dachte jetzt, die beiden Prozesse greifen über den socketFd auf ein und
> dasselbe Socket zu, wenn der eine das schliesst hat der andere Pech.

Der Doppelzugriff erfolgte mit dup(2), ist also ein anderer Desciptor des
gleichen Sockets.

> Oder wird das Socket erst geschlossen, wenn der letzte ein shutdown/close
> gemacht hat?

Wenn einer von beiden explizit shutdown macht, ist Pumpe. Ein close wirkt
erst beim letzten der Descriptoren.