Wie kann ich alle offene Pipes für den Chilprozess nach einem fork() schliessen?
-
Hallo, ich habe das Problem, dass ich einen Server programmiere, der allerdings nicht mit mehreren Prozessen, sondern Multithreaded arbeitet. Dabei kommunizieren nun die Clients via TCPIP-Sockets mit dem Server, wobei verschiedene Threads die offenen Filediskriptoren zur Kommunikation mit den Clients verwenden. Nun kann ein Thread vom Client das Kommando bekommen, dass er ein bestimmtes Programm starten soll. Innerhalb des Threads habe ich bisher folgenden Code dafür geschrieben:
[1] int a_result; [2] [3] a_result = fork(); [4] if(a_result == 0) { // child process [5] close(0); close(1); // damit habe ich schon mal STDIN/STDOUT abgetrennt [6] ... [7] execle(<Programm>, ...); [8] exit(EXIT_FAILURE); [9] }
Das Problem ist nun, dass "Zeile [5]" nicht ausreicht. Jeder offene Filediscriptor hängt nun in der Luft, bis einer der beiden Prozesse nach einem fork() ihn geschlossen hat. Das Problem ist nun, dass ich an dieser Stelle keinen Überblick darüber habe, wieviele (und speziell welche!) Verbindungen (, Pipes, ...(evtl. auch Semaphoren?) ) der Server insgesamt verwaltet. Eigentlich möchte ich "nur", dass der Kindprozess alles, was geerbt wurde und offen sein könnte schliesst. Er soll quasi vollkommen losgelöst vom erstellendem Prozess laufen. Wenn ich Zeile [7] entferne und statt dessen das entsprechende Programm von einer anderen Konsole zur richtigen Zeit mit den richtigen Parametern starte, funktioniert es einwand frei. Dafür muss es doch bestimmt eine Lösung geben, alles was offen ist zu schliessen.
Kann mir da jemand weiter helfen? Muss ich dafür vielleicht so etwas wie einen Deamon Prozess erstellen?Danke und Gruß,
Wischmop
-
auf einigen Unixen gibt es wohl eine Funktion closeall oder so was. Aber diese ist leider nicht standardisiert.
der übliche weg ist dann folgender
for(int fd=0;fd<255;++fd) close(fd);
-
Original erstellt von kingruedi:
**der übliche weg ist dann folgenderfor(int fd=0;fd<255;++fd) close(fd);
**
Nagut, dann wählen ich besser den üblichen Weg
Scheint nun auch wirklich zu funkitonieren (ok, jetzt habe ich natürlich andere Fehler im Programm), also schon mal vielen Dank für den Tip!
Allerdings frage ich mich nun, ob dieser Weg wirklich der richtige ist. Bekommt man vom System denn immer nur Filediskriptoren zwischen 0 und 255 zurück? In einen int passt ja etwas mehr rein... Andererseits wäre es natürlich auch sehr ineffizient die gesamte Menge an möglichen int-Werten zu schliessen. Ja, ist das nun so, dass man stets nur FD's zwischen 0 und 255 hat?Danke und Gruß,
Wischmop
-
theoretisch kann man natürlich auch FDs haben, die größer sind als 255. Deswegen ist die Methode ja auch nicht so gut
-
schau mal in deine limits.h
für linux zB /usr/include/linux/limits.h
#define OPEN_MAX 256 /* # open files a process may have */
-
Original erstellt von stahl:
**schau mal in deine limits.hfür linux zB /usr/include/linux/limits.h
#define OPEN_MAX 256 /* # open files a process may have */ ```**
Gute Idee, habe bei mir aber leider kein OPEN_MAX definiert, nachdem ich limits.h included habe, heist glaube ich _POSIX_OPEN_MAX. Habe aber noch ne andere Möglichkeit gefunden, so gehts auch:
int fdlimit = sysconf(_SC_OPEN_MAX); for(int fd=0;fd<fdlimit;++fd) close(fd);
Nagut, dann läufts ja jetzt. Trotzdem ist das ja irgend wie ein relativ krüppeliger Code. Naja, wenn's nicht anders geht... Ist nur schade, dass Linux für diesen Zweck nicht schon eine Funktion besitzt, die genau diesen Fall abdeckt. Ich könnte mir vorstellen, dass dieser Fall von vielen Programmieren behandelt werden muss... Egal, jetzt läufts, JUCHUH und Danke!!!