diff --git a/CHANGELOG.md b/CHANGELOG.md index c105de66e..e669afff5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Zowe Common C Changelog +## `2.11.0` + +- WTO printing methods have been moved to zos.c to be more available as utilities (for ex: for the Launcher) + ## `2.10.0` - Feature: The configmgr can now use the 'zos' module in YAML config templates. The 'zos' module is only added when run on ZOS. For a list of available functions, see https://github.com/zowe/zowe-install-packaging/blob/v2.x/staging/build/zwe/types/%40qjstypes/zos.d.ts (#384) diff --git a/c/metalio.c b/c/metalio.c index 320651e0e..9b6c45edf 100644 --- a/c/metalio.c +++ b/c/metalio.c @@ -55,6 +55,7 @@ #include "qsam.h" #include "metalio.h" #include "alloc.h" +#include "zos.h" static int isopen(void * dcbptr) { @@ -378,30 +379,7 @@ SYSOUT *getSYSOUTStruct(char *ddname, SYSOUT *existingSysout, char *buffer){ */ void message(char *message){ - ALLOC_STRUCT31( - STRUCT31_NAME(below2G), - STRUCT31_FIELDS( - WTOCommon31 common; - char text[126]; /* Maximum length of WTO text is 126 - ABEND D23-xxxx0005 if longer than 126 */ - ) - ); - - int len = strlen(message); - if (len>sizeof(below2G->text)) - len=sizeof(below2G->text); - - below2G->common.length = len+sizeof(below2G->common); /* +4 for header */ - memcpy(below2G->text,message,len); - - __asm(ASM_PREFIX - " WTO MF=(E,(%[wtobuf])) \n" - : - :[wtobuf]"NR:r1"(&below2G->common) - :"r0","r1","r15"); - - FREE_STRUCT31( - STRUCT31_NAME(below2G) - ); + wtoMessage(message); } /* this can only be called from authorized callers */ @@ -485,44 +463,13 @@ void sendWTO(int descriptorCode, int routingCode, char *message, int length){ } #define WTO_MAX_SIZE 126 -void wtoPrintf(char *formatString, ...){ - char text[WTO_MAX_SIZE+1]; /* Allow for trailing null character */ +void wtoPrintf(char *formatString, ...) { va_list argPointer; - int cnt; - - for (int pass=0; pass<2; pass++){ - - /* The resulting text string from vsnprintf is unpredictable if - there is an error in the format string or arguments. In that - case we will set the output text area to null, repeat the - vsnprintf, and then find the length of the null terminated - string. This avoids initializing the output text area prior - to every successful request. - */ - - va_start(argPointer,formatString); - cnt = vsnprintf(text,sizeof(text),formatString,argPointer); - va_end(argPointer); - - if (cnt<0){ - if (pass==0) - memset(text,0,sizeof(text)); /* Clear the text buffer before retrying the vsnprint request */ - else { - text[WTO_MAX_SIZE] = 0; /* Ensure strlen stops at the end of the text buffer */ - cnt = strlen(text); /* Find the end of the text string */ - } - } else - break; /* vsnprintf did not return an error - cnt was set */ - } - if (cnt>WTO_MAX_SIZE) /* If more data to format than the text buffer length */ - cnt = WTO_MAX_SIZE; /* Truncate the formatted length to the text buffer length */ - - /* We never want to include a final \n character in the WTO text */ - - if (cnt>0 && text[cnt-1] == '\n') /* If text ends with \n */ - text[cnt-1] = 0; /* Change it into a null character */ - - message(text); + va_start(argPointer, formatString); + + wtoPrintf3(formatString, argPointer); + + va_end(argPointer); } void authWTOPrintf(char *formatString, ...){ diff --git a/c/zos.c b/c/zos.c index da926e628..2a5879198 100644 --- a/c/zos.c +++ b/c/zos.c @@ -1469,6 +1469,78 @@ int safStat(int options, char *safClass, char *copy, int copyLength, int *racfSt get current TCB AC */ +/* begin WTO SECTION */ + +void wtoMessage(const char *message){ + + ALLOC_STRUCT31( + STRUCT31_NAME(below2G), + STRUCT31_FIELDS( + WTOCommon31 common; + char text[126]; /* Maximum length of WTO text is 126 - ABEND D23-xxxx0005 if longer than 126 */ + ) + ); + + int len = strlen(message); + if (len>sizeof(below2G->text)) + len=sizeof(below2G->text); + + below2G->common.length = len+sizeof(below2G->common); /* +4 for header */ + memcpy(below2G->text,message,len); + + __asm(ASM_PREFIX + " WTO MF=(E,(%[wtobuf])) \n" + : + :[wtobuf]"NR:r1"(&below2G->common) + :"r0","r1","r15"); + + FREE_STRUCT31( + STRUCT31_NAME(below2G) + ); +} + +#define WTO_MAX_SIZE 126 +void wtoPrintf3(const char *formatString, ...) { + char text[WTO_MAX_SIZE+1]; /* Allow for trailing null character */ + va_list argPointer; + int cnt; + + for (int pass=0; pass<2; pass++){ + + /* The resulting text string from vsnprintf is unpredictable if + there is an error in the format string or arguments. In that + case we will set the output text area to null, repeat the + vsnprintf, and then find the length of the null terminated + string. This avoids initializing the output text area prior + to every successful request. + */ + + va_start(argPointer,formatString); + cnt = vsnprintf(text,sizeof(text),formatString,argPointer); + va_end(argPointer); + + if (cnt<0){ + if (pass==0) + memset(text,0,sizeof(text)); /* Clear the text buffer before retrying the vsnprint request */ + else { + text[WTO_MAX_SIZE] = 0; /* Ensure strlen stops at the end of the text buffer */ + cnt = strlen(text); /* Find the end of the text string */ + } + } else + break; /* vsnprintf did not return an error - cnt was set */ + } + if (cnt>WTO_MAX_SIZE) /* If more data to format than the text buffer length */ + cnt = WTO_MAX_SIZE; /* Truncate the formatted length to the text buffer length */ + + /* We never want to include a final \n character in the WTO text */ + + if (cnt>0 && text[cnt-1] == '\n') /* If text ends with \n */ + text[cnt-1] = 0; /* Change it into a null character */ + + wtoMessage(text); +} + +/* end WTO SECTION */ /* LOCATE/CAMLIST */ diff --git a/h/metalio.h b/h/metalio.h index 7429f550a..cd78cbe53 100644 --- a/h/metalio.h +++ b/h/metalio.h @@ -70,13 +70,6 @@ typedef struct WTORPrefix31_tag{ char *replayECBAddress; } WTORPrefix31; -typedef struct WTOCommon31_tag{ - char replyBufferLength; /* 31-bit WTOR only, else 0 */ - char length; /* message length +4 */ - char mcsFlags1; - char mcsFlags2; -} WTOCommon31; - #define WTO_ROUTE_CODE_OPERATOR_ACTION 1 #define WTO_ROUTE_CODE_OPERATOR_INFORMATION 2 #define WTO_ROUTE_CODE_TAPE_POOL 3 diff --git a/h/zos.h b/h/zos.h index b8b03a331..1daba3f21 100644 --- a/h/zos.h +++ b/h/zos.h @@ -1522,6 +1522,13 @@ typedef struct IDTA_tag { char reserved[8]; } IDTA; +typedef struct WTOCommon31_tag{ + char replyBufferLength; /* 31-bit WTOR only, else 0 */ + char length; /* message length +4 */ + char mcsFlags1; + char mcsFlags2; +} WTOCommon31; + ZOWE_PRAGMA_PACK_RESET DSAB *getDSAB(char *ddname); @@ -1529,6 +1536,10 @@ DSAB *getDSAB(char *ddname); int dsabIsOMVS(DSAB *dsab); +void wtoMessage(const char *message); + +void wtoPrintf3(const char *formatString, ...); + int locate(char *dsn, int *volserCount, char *firstVolser); /*