Annotation of os2sdk/demos/apps/terminal/terminal.c, revision 1.1.1.2

1.1       root        1: /***
                      2:  *
                      3:  * TITLE 
                      4:  *
                      5:  *     terminal.c
1.1.1.2 ! root        6:  *     Created by Microsoft Corporation 1987
1.1       root        7:  *
                      8:  * DESCRIPTION
                      9:  *
                     10:  *     This program emulates an ANSI terminal device. 
                     11:  *
                     12:  *     The device driver COM.SYS must be installed at IPL  (Initial Program
                     13:  *     Load) by specifying the following in config.sys:
                     14:  *             device = COM01.SYS
                     15:  *
                     16:  *     To run this program, type the following to the MS OS/2 prompt:
                     17:  *
                     18:  *             terminal [filename]
                     19:  *
                     20:  *     If a filename is specified, the initialisation of the COM port and
                     21:  *     the MODEM will be performed as indicated in the file (creation of this
                     22:  *     file is described in options.c). For more details on setting options
                     23:  *     pertaining to the COM port and the MODEM, see options.c
                     24:  *
                     25:  *     To exit the terminal emulator, type ALT F1.
                     26:  *
                     27:  ***/
                     28: 
1.1.1.2 ! root       29: #define INCL_DOSSIGNALS
        !            30: #define INCL_SUB
        !            31: #define INCL_DOSFILEMGR
        !            32: #define INCL_DOSPROCESS
        !            33: #define INCL_DOSDEVICES
        !            34: 
        !            35: #include       <os2def.h>
        !            36: #include       <bse.h>
1.1       root       37: #include       <stdio.h>
                     38: #include       <malloc.h>
                     39: #include       <string.h>
                     40: #include       <memory.h>
                     41: #include       <conio.h>
                     42: #include       "term.h"
                     43: 
                     44: extern void get_options(int, char *[]);   /* get com port and modem options */
                     45: extern void get_com_options(structComOptions *); /* get com options */
                     46: extern make_modem_conn(void);            /* make modem connection */
                     47: extern modem(void);       /* returns TRUE if modem connection was requested */
                     48: extern void discon_modem(void);          /* disconnect modem */
                     49: 
                     50: void init_com_port(void);                /* initialise com port */
                     51: void far read_com_port(void);            /* routine addr for a thread */
                     52: void write_com_port(void);               /* routine addr for another thread */ 
1.1.1.2 ! root       53: void APIENTRY handle_signals(USHORT,USHORT); /* BREAK signals handler */
1.1       root       54: void close_conn(void);                   /*close modem connection & com port*/
1.1.1.2 ! root       55: void far xit(void);                    /* exit routine for this program */
1.1       root       56: 
                     57: char *ErrMsg[] = {
1.1.1.2 ! root       58:                "VIOGETCONFIG",
        !            59:                "KBDSETSTATUS",
1.1       root       60:                        "OUT OF MEMORY",
1.1.1.2 ! root       61:                "DOSCREATETHREAD",
        !            62:                "DOSCLOSE COMPORT",
        !            63:                "DOSDEVIOCTL SETDCB",
        !            64:                "DOSREAD",
        !            65:                "VIOWRTTTY",
        !            66:                "DOSOPEN: check if COM driver is installed",
        !            67:                "DOSDEVIOCTL SETBAUD",
        !            68:                "DOSDEVIOCTL SETLINECHAR",
        !            69:                "DOSDEVIOCTL GETDCB",
        !            70:                "KBDCHARIN",
        !            71:                "DOSWRITE",
        !            72:                "VIOWRTCHARSTRATT",
        !            73:                "VIOWRTNCELL",
        !            74:                "DOSEXITLIST ADD_ADDR",
        !            75:                "VIOSETCURPOS",
        !            76:                "VIOGETMODE",
        !            77:                "DOSDEVIOCTL FLUSH_XMIT_RECV_QUEUE",
        !            78:                "DOSDEVIOCTL GETCOM",
        !            79:                "DOSSETSIGHANDLER",
        !            80:                "DOSDEVIOCTL SETBREAKON",
        !            81:                "DOSDEVIOCTL SETBREAKOFF",
1.1       root       82:                        "INVALID SIGNAL",
                     83:                        "do_option: invalid option type",
                     84:                        "mod_option: invalid option type",
                     85:                        "show_option: invalid option type"
                     86: };
1.1.1.2 ! root       87: HFILE          FileHndl = NULL;    /* COM port file handle */
1.1       root       88: 
                     89: static char    ExitPgm = FALSE;    /* indicate if program should terminate */
                     90: static int     ErrorNumber = -1,   /* used as index to ErrMsg array */
                     91:                ReturnCode  = -1;   /* retcode from system/subsystem call */
                     92: 
                     93: 
                     94: 
                     95: 
                     96: /***   main - entry point to TERMINAL program
                     97:  *
                     98:  *     This routine obtains the com port and the modem options from the file
                     99:  *      (specified in the command line) or directly from the user. It opens and
                    100:  *     initialises the com port. It sets up the modem connection (if one was
                    101:  *     requested). It creates a thread which loops continuously waiting to 
                    102:  *     receive data from the com port and writing it out to the display. It 
                    103:  *     loops continuosly waiting for an input from the keyboard and writing 
                    104:  *     it out to the com port. Both the loops terminate when the user presses 
                    105:  *     ALT-F1. It closes the modem connection (if one was made), and the com 
                    106:  *     port and then terminates.
                    107:  *
                    108:  *     main(argc, argv)
                    109:  *
                    110:  *     ENTRY   
                    111:  *             argc - number of command line arguments
                    112:  *             argv - pointer to an array of pointers (to command line args)
                    113:  *
                    114:  *     EXIT
                    115:  *             the program terminates
                    116:  *
                    117:  *     WARNING
                    118:  *
                    119:  *     EFFECTS
                    120:  *
                    121:  ***/
                    122:  
                    123: main(argc,argv)
                    124: int    argc;
                    125: char   *argv[];
                    126: {
1.1.1.2 ! root      127:        UCHAR           *Stack1;             /* stack for a thread */
        !           128:        TID             ThreadID;
        !           129:        unsigned        RetCode,             /* return code */
1.1       root      130:                        Result = TRUE;
1.1.1.2 ! root      131:        USHORT          NumBytes;            /* number of bytes to be written */
        !           132:        PFNSIGHANDLER   PrevAddress;
        !           133:        USHORT          PrevAction;
        !           134:        static KBDINFO OurKbdStatus =
1.1       root      135:                                    {sizeof(OurKbdStatus),KBD_BITMASK,};
                    136: 
                    137:        /* get COM port and modem options */
                    138:        get_options(argc, argv);        
                    139: 
                    140:        /* open and initialise COM port */
                    141:        init_com_port();                        
                    142: 
                    143:        /* establish xit() as the exit routine */
1.1.1.2 ! root      144:        if ((RetCode = DosExitList(EXLST_ADD, (void (far *)(USHORT))xit)) != 0)
1.1       root      145:          error(ERR_DOSEXITLIST, RetCode);
                    146: 
                    147:        /* make modem connection if requested */
                    148:        if (modem())
                    149:          Result = make_modem_conn();   
                    150: 
                    151:        if (Result) {
                    152:          /* allocate memory for separate thread execution */
                    153:          if (!(Stack1 = (char *) _nmalloc(STACKSIZE)))
                    154:            error(ERR_OUTOFMEMORY, NO_RETCODE);
                    155: 
                    156:          /* create a thread that will execute the read_com_port() */
                    157:          Stack1 += STACKSIZE;
1.1.1.2 ! root      158:          if ((RetCode = DosCreateThread(read_com_port, &ThreadID,
1.1       root      159:                                          Stack1)) != 0)
                    160:            error(ERR_DOSCREATETHREAD, RetCode);
                    161: 
                    162:          /* set the keyboard status */
1.1.1.2 ! root      163:          if ((RetCode = KbdSetStatus(&OurKbdStatus,
1.1       root      164:                                       RESERVED)) != 0) 
                    165:            error(ERR_KBDSETSTATUS, RetCode);
                    166: 
                    167:          /* set signal handler for BREAK signal */
1.1.1.2 ! root      168:          if ((RetCode = DosSetSigHandler(handle_signals,
1.1       root      169:                         &PrevAddress,
                    170:                         &PrevAction,
                    171:                         RECV_CTRL, BREAK)) != 0)
                    172:            error(ERR_DOSSETSIGHANDLER, RetCode);
                    173: 
                    174:          /* display "connected" message */
                    175:          printf("connected... \n");
                    176: 
                    177:          /* read chars from the keyboard and write to COM port */
                    178:          write_com_port();
                    179:        }       /* if (Result) */
                    180: }
                    181: 
                    182: 
                    183: 
                    184: 
1.1.1.2 ! root      185: /***   init_com_port - open the COM port and initialise line characteristics
1.1       root      186:  *
                    187:  *     This routine opens the com port. It sets the com port options 
                    188:  *     BaudRate, DataBits, Parity and the StopBits. It sets the read timeout.
                    189:  *     It enables the automatic transmit and receive flow control.
                    190:  *
                    191:  *     init_com_port()
                    192:  *             
                    193:  *     ENTRY
                    194:  *             
                    195:  *     EXIT
                    196:  *             FileHndl = handle to com port
                    197:  *
                    198:  *     WARNING
                    199:  *
                    200:  *     EFFECTS
                    201:  *
                    202:  ***/
                    203: 
                    204: void init_com_port()
                    205: {
1.1.1.2 ! root      206:        USHORT          ActionTaken; /* action: file existed,created,replaced */
        !           207:        unsigned        RetCode;
1.1       root      208:        structLineChar  sLineChar;      /* line characteristics */
                    209:        structDCB       sDCB;           /* device control block information */
                    210:        structComOptions sComOptions;
                    211: 
                    212:        get_com_options(&sComOptions);
                    213: 
                    214:        /* open the com port */
1.1.1.2 ! root      215:        if ((RetCode = DosOpen(sComOptions.pPortName, &FileHndl,
1.1       root      216:                                &ActionTaken, 0L, 0, 0x0001, 0x0042, 0L)) != 0)
                    217:          error(ERR_DOSOPEN, RetCode);
                    218: 
                    219:        /* set the baud rate */
1.1.1.2 ! root      220:        if ((RetCode = DosDevIOCtl(0L, &(sComOptions.iBaudRate),
1.1       root      221:                                   SETBAUD, SERIAL, FileHndl)) != 0)
                    222:          error(ERR_IOCTLSETBAUD, RetCode);
                    223: 
                    224:        /* set Data Bits, Stop Bits, Parity */
                    225:        sLineChar.DataBits = sComOptions.chDataBits; 
                    226:         sLineChar.Parity   = sComOptions.chParity; 
                    227:        sLineChar.StopBits = sComOptions.chStopBits;
1.1.1.2 ! root      228:        if ((RetCode = DosDevIOCtl(0L, &sLineChar, SETLINECHAR,
1.1       root      229:                                   SERIAL, FileHndl)) != 0)
                    230:          error(ERR_IOCTLSETLINECHAR, RetCode);
                    231: 
                    232:        /* get device control block info */
1.1.1.2 ! root      233:        if ((RetCode = DosDevIOCtl(&sDCB, 0L, GETDCB, SERIAL,
1.1       root      234:                                    FileHndl)) != 0)
                    235:          error(ERR_IOCTLGETDCB, RetCode);
                    236: 
                    237:        sDCB.Flags2 |= 0x03;    /* enable auto Xmit and recv flow control */
                    238:        sDCB.Flags3 &= 0xf9;    /* clear read timeout flags */
                    239:        sDCB.Flags3 |= 0x04;    /* set wait for something read timeout */
                    240:        sDCB.ReadTimeOut = READTIMEOUT; /* set read timout value */
                    241: 
                    242:        /* set device control block info */
1.1.1.2 ! root      243:        if ((RetCode = DosDevIOCtl(0L, &sDCB, SETDCB, SERIAL,
1.1       root      244:                                    FileHndl)) != 0)
                    245:          error(ERR_IOCTLSETDCB, RetCode);
                    246: }
                    247: 
                    248: 
                    249: 
                    250: 
                    251: /***   write_com_port  - read chars from the keyboard and write to COM port
                    252:  *
                    253:  *     This routine loops continuosly waiting for a keyboard input and
                    254:  *     writing it out to the com port. The loop terminates when the user
                    255:  *     presses the ALT-F1.
                    256:  *
                    257:  *     write_com_port()
                    258:  *
                    259:  *     ENTRY
                    260:  *
                    261:  *     EXIT
                    262:  *
                    263:  *     WARNING
                    264:  *
                    265:  *     EFFECTS
                    266:  *
                    267:  ***/
                    268: 
                    269: void write_com_port()
                    270: {
1.1.1.2 ! root      271:        USHORT          NumBytes;       /* number of bytes actually written */
        !           272:        unsigned        RetCode;
1.1       root      273:        char            OutBuffer;      /* output buffer */
1.1.1.2 ! root      274:        KBDKEYINFO      OurKeyData;     /* struc to read a char from kbd */
1.1       root      275: 
                    276: 
                    277:        while (!ExitPgm) {
                    278:          /* read input from the keyboard */
1.1.1.2 ! root      279:          if ((RetCode = KbdCharIn(&OurKeyData,
1.1       root      280:                                    IOWAIT, RESERVED)) != 0) 
1.1.1.2 ! root      281:            error(ERR_KBDCHARIN, RetCode);
        !           282:          OutBuffer = OurKeyData.chChar;
1.1       root      283:          if ((OutBuffer == 0) || (OutBuffer == 0xE0)) {
1.1.1.2 ! root      284:            OutBuffer = OurKeyData.chScan;
1.1       root      285:            switch (OutBuffer) {
                    286:              case DEL_SCAN  : OutBuffer = DEL_ASCII;
                    287:                                break;
                    288:              case ALT_F1    : ExitPgm = TRUE;
                    289:                                break;
                    290:               default        : break;
                    291:             };
                    292:             if (OutBuffer != ALT_F1) 
                    293:              /* write the input from the keyboard to the com port */
1.1.1.2 ! root      294:              if ((RetCode = DosWrite(FileHndl, &OutBuffer, 1,
1.1       root      295:                                       &NumBytes)) != 0)
1.1.1.2 ! root      296:                error(ERR_DOSWRITE, RetCode);
1.1       root      297:          }
                    298:           else {
                    299:            /* write the input from the keyboard to the com port */
1.1.1.2 ! root      300:            if ((RetCode = DosWrite(FileHndl, &OutBuffer, 1,
1.1       root      301:                                     &NumBytes)) != 0)
                    302:              error(ERR_DOSWRITE, RetCode);
                    303:          };
                    304:        };
                    305: }
                    306: 
                    307: 
                    308: 
                    309: 
                    310: /***   read_com_port - read chars from com port and display on CRT screen 
                    311:  *
                    312:  *     This routine is executed by a thread. It loops continuously waiting
                    313:  *      to receive data from the com port and writing it out to the display.
                    314:  *     The loop terminates when the user presses ALT-F1.
                    315:  *
                    316:  *     read_com_port()
                    317:  *
                    318:  *     ENTRY
                    319:  *             FileHndl (handle to com port) setup
                    320:  *
                    321:  *     EXIT
                    322:  *
                    323:  *     WARNING
                    324:  *
                    325:  *     EFFECTS
                    326:  *
                    327:  ***/
                    328:  
                    329: void far read_com_port()
                    330: {
1.1.1.2 ! root      331:        USHORT          NumBytes;       /* number of bytes actually read */
        !           332:        unsigned        RetCode;
1.1       root      333:        struct CharsInQue {     /*data ret'ned by get num chars in que IOCTL*/
                    334:                        unsigned        NumCharsInQue;
                    335:                        unsigned        SizeQue;
                    336:        } sCharsInQue;
                    337:        char            InBuffer[INBUFLENGTH];  /* input buffer  */
                    338: 
                    339:        while (!ExitPgm) {
                    340:          /* get number of characters in receive queue */
1.1.1.2 ! root      341:          if ((RetCode = DosDevIOCtl(&sCharsInQue, 0L, GETNUMCHARS,
1.1       root      342:                                      SERIAL, FileHndl)) != 0)
                    343:            setup_error_msg(ERR_IOCTLSETDCB, RetCode);
                    344: 
                    345:          if (sCharsInQue.NumCharsInQue == 0)
                    346:             sCharsInQue.NumCharsInQue++;
                    347: 
1.1.1.2 ! root      348:          if ((RetCode = DosRead(FileHndl, InBuffer, sCharsInQue.NumCharsInQue,
1.1       root      349:                                  &NumBytes)) != 0)
                    350:            setup_error_msg(ERR_DOSREAD, RetCode);
                    351:        
                    352:          if (NumBytes) {
                    353:            /* write to the tty display */
1.1.1.2 ! root      354:            if ((RetCode = VioWrtTTy(InBuffer, NumBytes, RESERVED)) != 0)
1.1       root      355:              setup_error_msg(ERR_VIOWRTTTY, RetCode);
                    356:          }
                    357:        }
                    358: }
                    359: 
                    360: 
                    361: 
                    362: 
                    363: /***   handle_signals  - handle BREAK signal
                    364:  *
                    365:  *     This routine is the handler for the BREAK signal. When the user presses
                    366:  *     the BREAK key, this routine sends a BREAK on the com line.
                    367:  *
                    368:  *     handle_signals(SigArg, SigNumber)
                    369:  *
                    370:  *     ENTRY
                    371:  *             SigArg - not used
                    372:  *             SigNumber - signal number being processed
                    373:  *
                    374:  *     EXIT
                    375:  *
                    376:  *     WARNING
                    377:  *
                    378:  *     EFFECTS
                    379:  *         Since this is a signal handler it must be declared FAR.
                    380:  *
                    381:  ***/
                    382: 
1.1.1.2 ! root      383: void APIENTRY handle_signals(SigArg, SigNumber)
        !           384: USHORT SigArg,
1.1       root      385:        SigNumber;
                    386: {
1.1.1.2 ! root      387:        unsigned        RetCode,
1.1       root      388:                        Status;
                    389:        char            OutBuffer;
                    390: 
                    391:        switch (SigNumber) {
                    392:        case BREAK :/* send BREAK to the com port */
1.1.1.2 ! root      393:                    if ((RetCode = DosDevIOCtl(&Status, 0L,
1.1       root      394:                                        SETBREAKON, SERIAL, FileHndl)) != 0)
                    395:                      error(ERR_IOCTLSETBREAKON, RetCode);
1.1.1.2 ! root      396:                    DosSleep(1L);
        !           397:                    if ((RetCode = DosDevIOCtl(&Status, 0L,
1.1       root      398:                                        SETBREAKOFF, SERIAL, FileHndl)) != 0)
                    399:                      error(ERR_IOCTLSETBREAKOFF, RetCode);
                    400:                    break;
                    401:        default    :
                    402:                    error(ERR_INVALIDSIGNAL, NO_RETCODE);
                    403:                    break;
                    404:        }
                    405: }
                    406: 
                    407: 
                    408: 
                    409: 
                    410: /***   close_conn - close modem connection and the com port 
                    411:  *
                    412:  *     This routine closes the modem connection if one was made and then
                    413:  *     closes the com port.
                    414:  *
                    415:  *     close_conn()
                    416:  *
                    417:  *     ENTRY
                    418:  *
                    419:  *     EXIT
                    420:  *
                    421:  *     WARNING
                    422:  *
                    423:  *     EFFECTS
                    424:  *
                    425:  ***/
                    426: 
                    427: void close_conn()
                    428: {
                    429:        int             RetCode;
                    430:        static char     CloseMsg[] = "exiting terminal...";
                    431: 
                    432:        /* send closing message to the display */
1.1.1.2 ! root      433:        if ((RetCode = VioWrtTTy(CloseMsg, sizeof(CloseMsg), RESERVED)) != 0)
1.1       root      434:          print_err_msg(ErrMsg[ERR_VIOWRTTTY], RetCode);
                    435: 
                    436:        /* if modem connection was made, close it */
                    437:        if (modem())
                    438:          discon_modem();
                    439: 
                    440:        /* close the com port */
1.1.1.2 ! root      441:        if ((RetCode = DosClose(FileHndl)) != 0)
1.1       root      442:          print_err_msg(ErrMsg[ERR_DOSCLOSECOMPORT], RetCode);
                    443: }
                    444: 
                    445: 
                    446: 
                    447: 
                    448: /***           ERROR HANDLING
                    449:  *
                    450:  *     There are two error handling routines:
                    451:  *             - error() which is invoked from the main thread
                    452:  *             - setup_err_msg() which is invoked from the thread executing 
                    453:  *               the read_com_port() routine
                    454:  *     The two routines perform different functions (described below). This
                    455:  *     is done so that if an error is encountered "simultaneously" in both 
                    456:  *     the threads, there will be no race condition in error reporting.
                    457:  *     
                    458:  *     The following routines are also part of the error handling:
1.1.1.2 ! root      459:  *             - xit() is a DosExitList routine
1.1       root      460:  *             - print_err_msg() does the actual printing of the error message
                    461:  *     
                    462:  *     All the routines discussed above are defined below.
                    463:  *
                    464:  ***/
                    465: 
                    466: 
                    467: 
                    468: /***   error
                    469:  *
                    470:  *     This routine is invoked when there is an error. It prints an
1.1.1.2 ! root      471:  *     an error message and calls DosExit.
1.1       root      472:  *
                    473:  *     error(ErrNum, RetCode)
                    474:  *
                    475:  *     ENTRY
                    476:  *             ErrNum - error number (used as index to error message array)
                    477:  *             RetCode - return code from a DOS system/subsystem call
                    478:  *
                    479:  *     EXIT
                    480:  *             global variables ErrorNumber & ReturnCode still contain the
1.1.1.2 ! root      481:  *             initial value of -1. At program termination (via DosExit call)
        !           482:  *             the DosExitList routine xit() is invoked (described below).
1.1       root      483:  *             On return from xit(), this program will terminate.
                    484:  *
                    485:  *     WARNING
                    486:  *
                    487:  *     EFFECTS
                    488:  *
                    489:  ***/
                    490: 
                    491: error(ErrNum, RetCode)
                    492: int  ErrNum;
                    493: int  RetCode;
                    494: {
                    495:        print_err_msg(ErrMsg[ErrNum], RetCode);
1.1.1.2 ! root      496:        DosExit(EXIT_PROCESS, 1);
1.1       root      497: }
                    498: 
                    499: 
                    500: 
                    501: 
                    502: /***   setup_error_msg - setup error message
                    503:  *
1.1.1.2 ! root      504:  *     Sets up the global ErrorNumber and ReturnCode. It then calls DosExit.
1.1       root      505:  *
                    506:  *     setup_error_msg(ErrNum, RetCode)
                    507:  *
                    508:  *     ENTRY
                    509:  *             ErrNum - error number (used as index to error message array)
                    510:  *             RetCode - return code from a DOS system/subsystem call
                    511:  *
                    512:  *     EXIT
                    513:  *             global variables ErrorNumber & ReturnCode are setup. At 
1.1.1.2 ! root      514:  *             program termination (via DosExit call) the DosExitList
1.1       root      515:  *             routine xit() is invoked (described below). xit() will print
                    516:  *             an error message. On return from xit(), this program will 
                    517:  *             terminate.
                    518:  *
                    519:  *     WARNING
                    520:  *
                    521:  *     EFFECTS
                    522:  *
                    523:  ***/
                    524: 
                    525: setup_error_msg(ErrNum, RetCode)
                    526: int    ErrNum,
                    527:        RetCode;
                    528: {
                    529:        ErrorNumber = ErrNum;
                    530:        ReturnCode  = RetCode;
1.1.1.2 ! root      531:        DosExit(EXIT_PROCESS, 1);
1.1       root      532: }
                    533: 
                    534: 
                    535: 
                    536: 
                    537: /***   xit     - exit function executed at program termination
                    538:  *
1.1.1.2 ! root      539:  *     This is a DosExitList routine. It prints an error message if
1.1       root      540:  *     the global variable ErrorNumber is non-negative.
                    541:  *
                    542:  *     xit()
                    543:  *
                    544:  *     ENTRY
                    545:  *
                    546:  *     EXIT
                    547:  *             If ErrorNumber is non-negative, an error message is printed.
                    548:  *             The program will then terminate.
                    549:  *
                    550:  *     WARNING
                    551:  *
                    552:  *     EFFECTS
                    553:  *
                    554:  ***/
                    555: 
1.1.1.2 ! root      556: void far xit(void)
1.1       root      557: {
                    558:        if (ErrorNumber != -1) 
                    559:          print_err_msg(ErrMsg[ErrorNumber], ReturnCode);
                    560:        close_conn();           /* close modem connection and the com port */
1.1.1.2 ! root      561:        DosExitList(XFER, 0L);
1.1       root      562: }
                    563: 
                    564: 
                    565: 
                    566: 
                    567: /***   print_err_msg - print error mesage
                    568:  *
                    569:  *     This routine prints an error message and the returncode.
                    570:  *
                    571:  *     print_err_msg(Msg, Retcode)
                    572:  *
                    573:  *     ENTRY
                    574:  *             Msg - error message string
                    575:  *             Retcode - returncode from DOS system/subsystem call
                    576:  *
                    577:  *     EXIT
                    578:  *
                    579:  *     WARNING
                    580:  *
                    581:  *     EFFECTS
                    582:  *
                    583:  ***/
                    584: 
                    585: print_err_msg(Msg, RetCode)
                    586: char   *Msg;
                    587: int    RetCode;
                    588: 
                    589: {
                    590:        printf("*** ERROR %s *** ", Msg);
                    591:        if (RetCode != -1)
                    592:          printf("ReturnCode = %d ", RetCode);
                    593:        printf("\n");
                    594: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.