Sie sind nun wieder eingeladen, die Diskussion spezieller technischer Probleme mit zu verfolgen. Bitte schicken Sie Fragen, Anregungen oder Antworten zu den vorgestellten Themen – ebenso wie Ihre Kritik – an unsere e-Mail-Adressen: dieter.bender@MidrangeMagazin.de oder Redaktion@MidrangeMagazin.de

Frage:

Wir haben die gleichen Programme in unterschiedlichen Ständen in verschiedenen Bibliotheken. Wie kann man in einem Programm zur Laufzeit feststellen, aus welcher Bibliothek dieses Programm geladen wurde?

Antwort:

Die einfache Antwort, die man hier häufig zu hören bekommt, ist, mit dem CL Befehl RTVOBJD oder mit APIs zu arbeiten. Doch diese Lösung funktioniert nicht in jedem Fall. Egal ob ich hier das entsprechende API oder die CL-Variante wähle, ich bekomme immer nur zurück, in welcher Bibliothek der Bibliotheksliste ein bestimmtes Objekt zuerst gefunden wurde. Das auf diesem Weg gefundene Programmobjekt muss nicht immer identisch mit dem gerade laufenden sein. Fehler beim Binden oder Änderungen an der Bibliotheksliste nach der Aktivierung eines Programms können hier zu entscheidenden Abweichungen führen.

Für RPG-Programme ist die gewünschte Information relativ leicht zu bekommen: Die so genannte Programmstatus-Datenstruktur enthält diese neben zahlreichen anderen. Die Programmstatus-Datenstruktur muss im Programm deklariert werden und wird vom System automatisch gefüllt. Für die Deklaration muss in der Stelle „23“ der D-Bestimmungen ein „S“ eingetragen werden; die Deklarationsart ist „DS“ für Datenstruktur und es muss ein Name vergeben werden.

Die Deklaration dieser Datenstruktur mit ihren Unterfeldern speichert man am besten in einer Copy-Strecke, die man mit den Compiler-Anweisungen /DEFINE und /IF /ENDIF gegen „Doppeltkopieren“ schützen kann. Die Einbindung erfolgt dann mit der altbekannten /COPY-Anweisung.

* einbinden der Copy-Strecke in das RPG Modul

* in den globalen D-Bestimmungen

/COPY QRPGLEH,PSTATUS

Das Feld von Stelle 81 bis 90 – hier im Beispiel ProgramLibrary – enthält dann die Bibliothek des Programms oder des Service-Programms, welches dann das aktuelle Modul enthält. Diese Lösung funktioniert auch analog für OPM RPG. Hier enthält dieses Feld die Programm-Bibliothek, lediglich die Deklaration erfolgt nach OPM-Art.

Für CL-Programme ist dieses Verfahren nicht verwendbar. Das Umgraben des Call Stacks oder das Durchsuchen der Job-Informationen mit APIs lässt sich hier allerdings nur durch ein leicht trickreiches Verfahren umgehen: Die Grundidee basiert darauf, dass der CL-Befehl DMPCLPGM die Fehlermeldung CPF0570 sendet, und zwar dann wenn der Dump nicht ausführbar ist und diese Fehlermeldung die Angabe des Programms sowie der Bibliothek enthält.
Wenn man nun in dem CL-Programm sicherstellt, dass der Dump nicht ausgeführt werden kann, braucht man sich nur die Information aus der gesendeten Nachricht zu holen und hat damit das Gewünschte.

In diesem kleinen Programmausschnitt wird der Dump verhindert durch das Überschreiben der von DMPCLPGM verwendeten Druckerdatei mittels einer Datenbankdatei. Der Dump-Befehl sendet daraufhin die Nachricht CPF0570, die mit MONMSG abgefangen wird. Der sofort anschließend ausgeführte RCVMSG-Befehl stellt die Parameter der Fehlernachricht in die Variable &MSGDTA ein. Aus dieser Variable kann die Bibliothek mit der CL-Funktion %SST extrahiert werden. Nachdem die Information im Programm zur Verfügung steht, sollte man nicht vergessen, die Überschreibung der Druckerdatei wieder zu löschen, damit keine unerwünschten Nebenwirkungen auftreten können.
Diese Variante ist sowohl für OPM-Programme als auch für ILE-Programme verwendbar. Bei OPM-Programmen wird wieder die Bibliothek das Programms geliefert und bei ILE-Programmen die Bibliothek des Programms oder des Service-Programms des Modules, das die ausgeführte Prozedur enthält.

Den Autor Dieter Bender erreichen Sie unter der e-Mail-Adresse: dieter.bender@midrangemagazin.de