MainframeSupports
tip uge 17/2011:

For 5 år siden i uge 18/2006 skrev jeg et tip om at finde et DD navn via TIOT arealet. I en TIOT entry er der også en pointer til JFCB'en, som beskriver det dataset, der er tilknyttet DD navnet. De første 44 tegn af en JFCB er selve datasetnavnet. Desværre er pointeren et såkaldt swa token (i tippet kaldet jfcbtoken) på tre bytes.

Den første udgave af MVS operativsystemet adresserede kun med 24 bit og derfor fyldte en adresse kun 3 bytes. Af årsager, jeg ikke kender, valgte IBM at undlade at udvide JFCB adressen i TIOT arealet til fire bytes, da 31 bits adressering blev introduceret med MVS/XA. I flere år kunne man bare flytte de tre bytes over i de sidste tre bytes af en pointer, hvor den første byte var sat til lutter binære nuller. Det holdt pludselig op med at virke på et tidspunkt, fordi IBM flyttede JFCB arealet over 16 megabyte grænsen. I stedet blev de tre bytes til adressering af en JFCB omdannet til en såkaldt swa token. Dette token kunne så omdannes til en rigtig 31 bits adresse ved hjælp af en assembler macro.

Der blev rundt omkring på alverdens mainframe installationer lavet små assembler rutiner til at konvertere swa token til en adresse. Desværre er det nu således, at meget få installationer har dokumenteret deres swa konvertering og endnu færre ved, hvor de kan finde dokumentationen. Derfor har nogen fundet ud af at kode det direkte i COBOL og PLI. Du kan finde et COBOL program, der blandt andet konverterer swa token her. Jeg har også fundet en stump PLI kode, der gør det samme, men den virker desværre ikke, så jeg oversatte noget af COBOL koden fra ovenstående link til en PLI procedure:

swa2addr: PROC(swa) RETURNS(POINTER);

DCL   swa CHAR(3);
DCL   svas CHAR(4);
DCL   svap POINTER BASED(addr(svas));
DCL   svab FIXED BIN(31) BASED(addr(svas));
DCL   myQmatP POINTER;
DCL   myQmatB FIXED BIN(31) BASED(addr(myQmatP));
DCL   jfcbPointer POINTER BASED(svaP);
DCL   psaPointer POINTER STATIC INIT(sysNull());
DCL 1 psa BASED(psaPointer)
  , 2 * CHAR(536)
  , 2 tcbPointer POINTER
  ;
DCL 1 tcb BASED(tcbPointer) UNALIGNED
  , 2 * CHAR(180)
  , 2 jscbPointer POINTER
  , 2 * CHAR(116)
  , 2 ownerPointer POINTER
  ;
DCL 1 jscb BASED(jscbPointer) UNALIGNED
  , 2 * CHAR(244)
  , 2 qmplPointer POINTER
  ;
DCL 1 qmpl BASED(qmplPointer) UNALIGNED
  , 2 * CHAR(24)
  , 2 qmatPointer POINTER
  ;
DCL 1 qmat BASED(myQmatP) UNALIGNED
  , 2 * CHAR(12)
  , 2 nextQmatP POINTER
  ;
svaS = '00'X !! swa;
IF mod(svaB, 16) = 15
THEN DO;
  myQmatP = qmatPointer;
  DO WHILE(svab > 65536);
    myQmatP = nextQmatP;
    svab = svab - 65536;
  END;
  svaB = svaB + 1 + myQmatB;
  svaP = jfcbPointer;
END;
svaB = svaB + 16;
RETURN(svaP);

END swa2addr;

Hvis du i et PLI-program står med et jfcb swa token og gerne vil have fat i dataset navnet, så laver du en CHAR(44) BASED(jfcbPointer) erklæring og laver en jfcbPointer = swa2addr(jfcbToken). Herefter er datasetnavnet direkte tilgængeligt i din datasetnavne variabel. Bemærk, at ikke alle DD navne har valide datasetnavne. Enten aflurer du de forskellige datasetnavne, der anvendes til de forskellige typer dataset, eller også finder du en beskrivelse af JFCB'en og tyder dens indhold for at få styr på tingene.

Forrige danske tip        Last tip in english        Tip oversigten