JCC - MVS Utilities.

These auxiliary JCC functions can be used by programs that need to interact with the MVS operating system at a lower level than C normally provides.


In addition to the functions listed below, the setjmp.h header file has been updated to include 2 new functions:

int _setjmp_stae (jmp_buf jbs, char * sdwa104);
int _setjmp_canc (void);
Use "char my_sdwa [104]" as the area of memory to pass to _setjmp_stae, if you want to retrieve the ABEND data.

Examples of using the setjmp, WTOR and _setstax functions are provided below.


From the <mvsutils.h> header file:

/*

  MVS Utils C-Library Include File for MVS-OS/390-zOS

  (C)2003,2009 Jason Paul Winter, All Rights Reserved.

*/

#ifndef __MVSUTILSH
#define __MVSUTILSH /* Prevent multiple includes */

int _CIB_STOP (void); // Returns 1 if the CIB chain contains a STOP command

int _testauth (void); // Returns 1 if authorised, else 0 is returned
int _modeset (int p);
// _modeset p values:
// ------------------
// 0 = KEY=ZERO
// 1 = KEY=NZERO (Use the TCB KEY)
// 2 = SUPER
// 3 = PROBLEM

int _setstax (long * bb);        // "long bb [2]" is required here
int _setstax_canc (long * bb);   // bb [0] == 0 on initialisation
                                 // bb [1] is for internal use
// If the attention key is pressed, bb [0] is incremented.

int _putline (char * text); // Output to terminal
char * _getline (void);         // Input from terminal (with "edit")

int _write2log (char * msg); // int returned is a combination of R0 & R15

int _write2op  (char * msg); // msgid is returned by this function
int _wri2dom   (int msgid);  // (This is used internally by _write2opr)

int _write2opr (char * msg, int maxlen, char ** result, int timeout_ms);
// _write2opr returns a copy of the ECB that may or may not be signalled.
// "char * result" (address passed above) needs to be 'free'd if non-NULL
// on return.  timeout_ms may be -1 for an infinite wait.

// These are RAW access routines, not for normal use:
int _wri2log (void * m); // only 126 chars, else truncated
int _wri2op  (void * m); // only 125 chars, else truncated
int _wri2opr (void * m); // only 121 chars, else truncated

#endif


Example WTOR usage:
int myfunc1 () {
    int    i;
    char * r = NULL; // initialise it in case WTOR fails
    
    printf ("Testing WTOR function\n");
    /*i = _write2opr ("Reply (anything)", 30, &r, -1);*/
    i = _write2opr ("Reply (anything)", 30, &r, 30000); // Use a 30 second timeout
    printf ("End Testing (id=%08X)\n", i);
    if (r) {
        printf (".reply=>%s<\n", r);
        free (r);
    }
    return (0);
}

Example _setjmp_stae usage: (The _setjmp_canc() function is shown in the correct place, but isn't executed by this example.)
int myfunc2 () {
    long  * a; // To cause an abend
    long    i;
    jmp_buf b;

    i = _setjmp_stae (b, NULL); // We don't want 104 bytes of abend data
    if (i == 0) { // Normal return

        printf ("1st setjmp return\n");

        a = NULL;
        *a = 0; // Cause an abend!  The following 2 lines will not be executed

        i = _setjmp_canc (); // Cancel the last STAE in the OS
        printf ("setjmp_canc rc=%d\n", i);

    } else if (i == 1) { // Something was caught - the STAE has been cleaned up.

        printf ("2nd setjmp return, abend caught\n");

        //*a = 0; // Cause an abend! (for real, if you want to test it.)

    } else { // can only be -1 = OS failure

        printf ("setjmp couldn't create STAE\n");
    }
    return (0);
}

Example _setstax usage: (includes the new _getline and _putline routines.)
int myfunc3 () {
    long bb [2]; // New for stax

    i = _setstax (bb);
    if (i == 0) {

        _putline ("Enter something:");
        r = _getline ();
        if (r) {
            _putline (r);
            free (r);
        }

        while ((bb [0])--)
            _putline ("Attention detected");

        _setstax_canc (bb);

    } else {

        _putline ("STAX failed");
    }
    return (0);
}