Ein Blick in die Dokumentation zu
»DBD::Pg
«
[1]
offenbart die Lösung des zweiten Problems. Der Treiber stellt nämlich die PID des Datenbankprozesses in
»$dbh->{pg_pid}
«
zur Verfügung. Ein Problem gibt es allerdings, wenn die Datenbank auf einem anderen Rechner läuft. Selbst wenn der CGI-Prozess die nötigen Rechte hätte, dem Datenbankprozess ein Signal zu schicken, kann er ihn nicht auf einem anderen Rechner beenden. Hier hilft die PostgreSQL-Dokumentation
[2]
weiter. Die Datenbank stellt nämlich zu diesem Zweck die Funktion
»pg_cancel_backend(int)
«
bereit.
Listing 3
zeigt das fertige Programm
»burn1.pl
«
. Neu sind die Zeilen 5 und 13 bis 25. Zeile 24 installiert die Funktion
»sig
«
als Signal-Handler für SIGTERM. Kommt das Signal an, öffnet Zeile 14 eine neue Verbindung zur Datenbank und ruft die Funktion
»pg_cancel_backend
«
auf. Danach beendet sich das Programm. Der Aufruf von
Listing 3
burn1.pl
$ curl http://localhost/cgi/burn1.pl\?120
kehrt jetzt nach fünf Sekunden zurück und der Datenbankprozess ist auch verschwunden.
Doch diese Lösung hat gravierende Nachteile. Zuerst ist da ein Sicherheitsproblem. Nur der Administrator der Datenbank darf
»pg_cancel_backend
«
aufrufen. Deswegen meldet sich das Programm für die zweite Verbindung als Benutzer
»postgres
«
an. Unter dem Gesichtspunkt der Sicherheit ist es aber unglücklich, wenn ein CGI-Programm Administratorrechte für die Datenbank besitzt.
Darüber hinaus handelt man sich mit der Art der Signal-Behandlung die gleichen Probleme wieder ein, weshalb die sicheren Signale erst eingeführt wurden. Im gegebenen Fall ist das wahrscheinlich irrelevant, denn wenn das Signal eintrifft, wird der Prozess sehr wahrscheinlich in einem
»read
«
-,
»recv
«
- oder ähnlichen Systemaufruf feststecken und auf Daten warten. Außerdem beendet der Signal-Handler das Programm. Das heißt, mit dem Signal werden keine kritischen Bereiche unterbrochen, wie beispielsweise in
»malloc
«
, die zu einem Fehler in der Speicherverwaltung mit anschließendem Absturz führen. Auch gibt es keine Speicherlöcher, da sich das Programm sowieso beendet. Generell ist jedoch von
»POSIX::sigaction
«
in Perl-Programmen abzuraten.
Ein drittes Problem entsteht durch die Notwendigkeit, eine zweite Datenbankverbindung zu öffnen, nur um eine bestehende zu beenden. Da wird mit Kanonen auf Spatzen geschossen. Außerdem besteht die Möglichkeit, auch in dieser Hinsicht an ein Limit zu stoßen, sodass die Verbindung nicht aufgebaut werden kann.