Handling OS/2 Error Codes

From OS2World.Com Wiki
Revision as of 01:25, 16 October 2023 by Martini (talk | contribs) (Created page with "by Nico Mak [LISTING ONE] <pre> OS2ERR.H version 1.0, March, 1989: Include this file after including OS2.H or OS2DEF.H: #ifdef OS2ERR USHORT APIENTRY xos2chk(PSZ, USHORT, PSZ, USHORT); USHORT APIENTRY xos2(PSZ, USHORT, PSZ, USHORT); VOID APIENTRY xpoperr(VOID); #define os2chk(ErrCode) (xos2chk(__FILE__, __LINE__, #ErrCode, ErrCode)) #define os2(ErrCode) (xos2(__FILE__, __LINE__, #ErrCode, ErrCode)) #define poperr() (xpoperr()) #...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

by Nico Mak

[LISTING ONE]

/* OS2ERR.H version 1.0, March, 1989 */
/* Include this file after including OS2.H or OS2DEF.H */

#ifdef OS2ERR
    USHORT APIENTRY xos2chk(PSZ, USHORT, PSZ, USHORT);
    USHORT APIENTRY xos2(PSZ, USHORT, PSZ, USHORT);
    VOID   APIENTRY xpoperr(VOID);
    #define os2chk(ErrCode) (xos2chk(__FILE__, __LINE__, #ErrCode, ErrCode))
    #define os2(ErrCode) (xos2(__FILE__, __LINE__, #ErrCode, ErrCode))
    #define poperr() (xpoperr())
#else
    #define os2chk(ErrCode) (ErrCode)
    #define os2(ErrCode) (ErrCode)
    #define poperr()
#endif

[LISTING TWO]

/* OS2ERR.C version 1.1, April 1989 by Nico Mak */
/* These functions are called by the macros in OS2ERR.H */
/* Compile this program with the options you use for the rest of */
/* your application, and link your application with OS2ERR.OBJ */
 
#define MAX_SAVE_ENTRIES 7 /* maximum number of threads that will use OS2ERR */
 
#include <stdio.h>      /* definitions/declarations for standard I/O routines */
#define INCL_BASE       /* to include all of OS/2 base */
#include "os2def.h"     /* include OS/2 common definitions */
#include "bse.h"        /* include OS/2 base definitions */
#define OS2ERR          /* to include OS2ERR declarations and macros */
#include "os2err.h"     /* include OS2ERR declarations */
 
typedef struct _SAVEINFO {                  /* save */
    TID tid;
    PSZ pszFileName;
    USHORT usLineNumber;
    PSZ pszLineSource;
    USHORT usErrCode;
    } SAVEINFO, FAR *PSAVEINFO;
 
SAVEINFO save[MAX_SAVE_ENTRIES];
USHORT cSavedEntries = 0;   /* number of threads that have used OS2ERR */
BOOL fOverFlow = 0;         /* 1 when all entries in "save" table are full */
 
/* DosErrClass error classifications */
PSZ pszClass[] = {
    "",
    "Out of Resource",
    "Temporary Situation",
    "Permission problem",
    "Internal System Error",
    "Hardware Failure",
    "System Failure",
    "Application Error",
    "Not Found",
    "Bad Format",
    "Locked",
    "Media Failure",
    "Collision with Existing Item",
    "Unknown/other",
    "Can't perform requested action",
    "Time-out",
    };
 
/* DosErrClass recommended actions */
PSZ pszAction[] = {
    "",
    "Retry immediately",
    "Delay and retry",
    "User error, get new values",
    "Abort in orderly manner",
    "Abort immediately",
    "Ignore this error",
    "Retry after user intervention",
    };
 
/* DosErrClass locus */
PSZ pszLocus[] = {
    "",
    "Unknown",
    "Disk",
    "Network",
    "Serial device",
    "Memory parameter",
    };
 
CHAR szWaitMsg[] = "\nPress Esc to abort process or any other key to continue";
CHAR szErrTID[] = "\npoperr() error: no information saved for this thread\n\r";
CHAR szErrOverFlow[] = "\npoperr() error: thread storage area overflowed\n\r";
CHAR szBuffer[400];
 
USHORT PASCAL PszLen(PSZ psz); /* function returns length of a far string */
PSAVEINFO PASCAL FindSaveEntry(TID); /* function returns PSAVEINFO for TID */

/* xos2chk - handle error (if any) and return error code */
USHORT APIENTRY xos2chk(PSZ pszFileName, USHORT usLineNumber,
 PSZ pszLineSource, USHORT usErrCode)
    {
    if (xos2(pszFileName, usLineNumber, pszLineSource, usErrCode))
        xpoperr();
    return usErrCode;
    }
 
/* xos2 - save error information and return error code */
USHORT APIENTRY xos2(PSZ pszFileName, USHORT usLineNumber,
 PSZ pszLineSource, USHORT usErrCode)
    {
    PSAVEINFO psave;
    PIDINFO pidi;
 
    if (usErrCode)
        {
        DosGetPID(&pidi);
        if ((psave = FindSaveEntry(pidi.tid)) == NULL)
            {
            DosEnterCritSec();
            if (cSavedEntries < MAX_SAVE_ENTRIES)
                psave = save + cSavedEntries++;
            else
                fOverFlow = 1;
            DosExitCritSec();
            }
        if (psave)
            {
            psave->tid = pidi.tid;
            psave->pszFileName = pszFileName;
            psave->usLineNumber = usLineNumber;
            psave->pszLineSource = pszLineSource;
            psave->usErrCode = usErrCode;
            }
        }
    return usErrCode;
    }
 
/* xpoperr - display pop-up screen with error information, return error code */
VOID APIENTRY xpoperr(VOID)
    {
    KBDKEYINFO kbci;
    PIDINFO pidi;
    PSZ psz;
    USHORT usClass, usAction, usLocus, usWait, usEnviron, usOffsetCmd, cbMsg;
    PSAVEINFO psave;
 
    /* open a pop-up screen */
    usWait = VP_WAIT | VP_OPAQUE;
    VioPopUp(&usWait, 0);
 
    DosGetPID(&pidi);
    if ((psave = FindSaveEntry(pidi.tid)) == NULL)
        {
        VioWrtTTY(szErrTID, sizeof(szErrTID), 0);
        if (fOverFlow)
            VioWrtTTY(szErrOverFlow, sizeof(szErrOverFlow), 0);
        }
    else
        {
        /* display error code, command name, and command tail */
        sprintf(szBuffer, "Error Code:   %u\n\r", psave->usErrCode);
        VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
        DosGetEnv(&usEnviron, &usOffsetCmd);
        for (psz = MAKEP(usEnviron, 0); *psz; psz += PszLen(psz) + 1)
           ;
        psz += 1;
        sprintf(szBuffer, "Command:      %Fs\n\r", psz);
        VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
        psz += PszLen(psz) + 1;
        psz += PszLen(psz) + 1;
        sprintf(szBuffer, "Command tail: %Fs\n\r", psz);
        VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
 
        /* display process id, thread id, and DosErrClass information */
        sprintf(szBuffer, "Process ID:   %u\n\rThread ID:    %u\n\r",
         pidi.pid, pidi.tid);
        VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
        DosErrClass(psave->usErrCode, &usClass, &usAction, &usLocus);
        sprintf(szBuffer,
         "Action:       %Fs\n\rLocus:        %Fs\n\rClass:        %Fs\n\r",
         pszAction[usAction], pszLocus[usLocus], pszClass[usClass]);
        VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
 
        /* display source filename, line number, and source code */
        sprintf(szBuffer, "Source name: %Fs\n\rSource line: %d (%Fs)\n\r\n\r",
         psave->pszFileName, psave->usLineNumber, psave->pszLineSource);
        VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
 
        /* display system message (if any) */
        if (!DosGetMessage(0, 0, szBuffer, sizeof(szBuffer), psave->usErrCode,
          "OSO001.MSG", &cbMsg))
            VioWrtTTY(szBuffer, cbMsg, 0);
        }
 
    /* wait for a keypress */
    VioWrtTTY(szWaitMsg, sizeof(szWaitMsg), 0);
    do {
        KbdCharIn(&kbci, IO_WAIT, 0);
        } while (!(kbci.fbStatus & 0x40));
 
    /* close the pop-up screen and abort if requested */
    VioEndPopUp(0);
    if (kbci.chChar == 27 && kbci.chScan == 1)
        DosExit(EXIT_PROCESS, 1);
    }
 
/* PszLen - return length of a far string */
USHORT PASCAL PszLen(PSZ psz)
    {
    PSZ pszSearch = psz;
 
    while (*pszSearch)
        pszSearch++;
    return pszSearch - psz;
    }
 
/* FindSaveEntry - return pointer to SAVEINFO for a thread ID */
PSAVEINFO PASCAL FindSaveEntry(TID tid)
    {
    PSAVEINFO psave;
 
    for (psave = save; psave < save + cSavedEntries; ++psave)
        if (psave->tid == tid)
            return psave;
    return NULL;
    }


[Example 1: Examples of OS/2chk() macro]

os2err(DosClose(hanConfig));    /* display pop-up screen w/error info */
os2err(VioGetFont(&viofi, 0));  /* if system calls return error codes */


[Example 2: Examples of OS/2() and poperr() macros]

SubCommandProcess()
    {

    if (!setjmp(jmpbuf)) {                         /* set up error handler */

        /* ... processing ... */

        err == os2(VioGetFont(&viofi, 0));        /* get current font info */
        if (err == ERROR_VIO_EXTENDED_SG)    /* if running in a VIO window */
            InVioWindow = YES;                 /* remember we're in window */
        else if (err)                     /* if any other VioGetFont error */
            poperr();             /* display pop-up screen with error info */

        /* ... more processing ... */

        if (os2(DosClose(hanConfig)) /* if DosClose returns an error code */
            longjmp(jmpbuf);       /* skip to application's error handler */

        /* ... yet more processing ... */

        }
    else
        poperr(); /* error handler - display pop-up screen with error info */
    }