Fehlerüberprüfung bei execvp
-
rüdiger schrieb:
Siehe man: wait(2) und WEXITSTATUS.
Das bringt mir nichts, denn wenn ich das richtig verstanden habe, kann ich das nur abfragen, wenn der Prozess beendet wurde. Ich will aber nur wissen, ob er richtig gestartet wurde, sprich, ob execvp erfolg hatte.
-
Anscheinend gibt es keine einfache Lösung zu meinem Problem.
Auszug aus den Manpages zu start-stop-daemon Programm von Debian:
man start-stop-daemon schrieb:
-b|--background
Typischerweise verwendet für Programme die sich nicht
selbständig ablösen. Diese Option zwingt start-stop-daemon vor
dem Start des Prozesses einen Fork durchzuführen, und zwingt ihn
in den Hintergrund. WARNUNG: start-stop-daemon kann nicht den
Rückgabewert überprüfen, falls der Prozess aus irgendeinem Grund
nicht startet. Dies ist ein letztes Mittel und ist nur für Pro‐
gramme gedacht, bei denen das selbstständige Forken keinen Sinn
macht oder wo es nicht sinnvoll ist, den Code hierfür
hinzuzufügen.Auch die Shell erweist sich nicht als sehr hilfreich...
if sh -c 'nich-da &'; then echo "erfolg"; else echo "doof"; fi
Das gibt mir immer "erfolg" aus.
Bleibt mir wohl nichts anderes übrig, als im Fehlerfall ein Signal an den Elternprozess zu senden.
Falls trozdem jemand etwas besseres einfällt...
-
Wenn execvp fehlschlägt, dann beendest du doch den Prozess und kannst entsprechend den Exitwert auslesen. Verstehe das Problem nicht.
-
rüdiger schrieb:
Wenn execvp fehlschlägt, dann beendest du doch den Prozess und kannst entsprechend den Exitwert auslesen. Verstehe das Problem nicht.
Wenn ich aber mit wait warte, dass sich der Prozess beendet, dann läuft mein Programm nicht weiter, wenn kein Fehler auftritt.
Warte ich nicht, auf einen Rückgabewert, bekomme ich nicht mit, wenn execvp nicht funktioniert.
-
wait musst du ja so oder so irgend wann aufrufen, wenn du nicht mit Zombieprozessen enden willst. Am besten macht man so was eben im SIGCHLD-Handler.
-
rüdiger schrieb:
wait musst du ja so oder so irgend wann aufrufen, wenn du nicht mit Zombieprozessen enden willst. Am besten macht man so was eben im SIGCHLD-Handler.
Das ist ja nicht das Problem. Spätestens wenn die Klasse zerstört wird, wird wait aufgerufen.
Den Prozess, den ich starte, soll quasi so lange laufen, wie mein Programm läuft. Mein Programm ist nicht viel mehr, als ein Frontend dafür. Es wäre irgendwie nicht schlecht gewesen, wenn ich hätte feststellen können, dass das Programm erfolgreich gestartet wurde. Wenn es dafür keinen einfachen weg gibt, muss ich halt entweder bei SIGCHLD oder in regelmäßigen abständen schauen, ob der Prozess nocht läuft.
Ich hab noch eine Frage zu SIGCHLD. Wenn ich mit Signalen arbeite, kann es da nicht zu den gleichen Problemen, wie mit Threads kommen? Wenn ich z.B. eine global Variable im Signal-Handler setzen möchte, dass der Prozess beendet wurde. Treten da nicht die gleichen Probleme auf, wie bei mehreren Threads?
-
In Signalhandlern darfst du keine Threadfunktionen aufrufen. Auch sonst darfst du nur ganz wenige Funktionen aufrufen. Am sichersten ist es, wenn du nur Variablen vom Typ sig_atomic_t veränderst.
Bei deinem ursprünglichen Problem stellt sich auch die Frage, was ein erfolgreicher Start eines Programms ist. Wenn ein Programm startet, aber bereits nach 0.0001 s sich verabschiedet ist der Start doch immer noch erfolgreich.
-
Ponto schrieb:
In Signalhandlern darfst du keine Threadfunktionen aufrufen. Auch sonst darfst du nur ganz wenige Funktionen aufrufen. Am sichersten ist es, wenn du nur Variablen vom Typ sig_atomic_t veränderst.
Sowas hab ich mir eigentlich schon gedacht. Ist ja nun auch keine schöne Möglichkeit. Gibts dazu noch irgendwo weitere Informationen zu? In dem Buch "C und Linux" steht zum Thema Sicherheit bei Signal-Handlern nichts drin. Wäre aber nicht schlecht zu wissen.
Das mit dem sig_atomic_t ist schonmal ein guter Hinweis. Werd mich mal schlau machen. Danke.
Ponto schrieb:
Bei deinem ursprünglichen Problem stellt sich auch die Frage, was ein erfolgreicher Start eines Programms ist. Wenn ein Programm startet, aber bereits nach 0.0001 s sich verabschiedet ist der Start doch immer noch erfolgreich.
Ja... bzw. ob das EXIT_FAILURE nun desswegen kam, weil das Programm nicht gestartet werden konnte, oder weil das Programm einen Fehler melden will. Man könnte natürlich einen anderen Wert zurück geben, aber das Programm könnte zufällig ja genau den gleichen Wert zurück geben.
Edit: Ich hab dazu noch das hier gefunden: Link
-
Das Buch "Advanced Programming in the Unix Environment" ist ganz gut. Genauso die "Unix Network Programming" Bücher. Das Buch "Linux/Unix Systemprogrammierung" ist auch gut und sollte sowas drin haben.
"man 2 signal" gibt dir eine Liste von erlaubten Funktionen im Signalhandler.
In einem signalhandler kann man viel falsch machen. Zum Beispiel beim Aufruf von waitpid sollte man aufpassen.
-
Ponto schrieb:
Das Buch "Advanced Programming in the Unix Environment" ist ganz gut. Genauso die "Unix Network Programming" Bücher. Das Buch "Linux/Unix Systemprogrammierung" ist auch gut und sollte sowas drin haben.
Ich werd mal schauen, ob ich mir davon eins zulegen werde.
Ponto schrieb:
"man 2 signal" gibt dir eine Liste von erlaubten Funktionen im Signalhandler.
In einem signalhandler kann man viel falsch machen. Zum Beispiel beim Aufruf von waitpid sollte man aufpassen.
Ach verdammt. Ich hab in den Umgebungsvariablen die Sprache auf Deutsch stehen. Hab mich gewundert, warum da dazu nichts drin steht. Die deutsche Version ist vom 10. Juni 1996. Hab jetzt gerade in die englische Version geschaut. Die ist vim 28. April 2000. Und da steht tatsächlich auch so einiges mehr drin.
Das ist ja schon fast grob fahrlässig, die deutsche Version der Man-Pages zu nehmen, wenn die schon so lange nicht mehr übersetzt wurden...
Ich danke schonmal für die Hilfe. Ich werd mir überlegen, ob sich das Problem irgendwie umgehen lässt. Da das Programm eh so lange, wie mein Programm laufen soll, werde ich wohl einfach einen Timer setzen und jede Sekunde prüfen, ob es noch läuft. Ist nur leider nicht so schön.