home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_07 / 8n07033a < prev    next >
Text File  |  1990-06-19  |  5KB  |  182 lines

  1.  
  2. /****************************************************************************/
  3. /*                                        */
  4. /* ROUTEMSG.C - OS/2 utility to invoke a child process and route its STDOUT */
  5. /*        and STRERR streams to both the video display as well as an  */
  6. /*        ASCII file.                            */
  7. /*                                        */
  8. /****************************************************************************/
  9. /*                  Modification Log                    */
  10. /****************************************************************************/
  11. /*  --Date--   ----Programmer----  -------------Comments------------------- */
  12. /*                                        */
  13. /*  06/10/89   Bob Withers       Program originally complete            */
  14. /*                                        */
  15. /****************************************************************************/
  16.  
  17. #pragma check_stack(off)
  18.  
  19. #define INCL_DOS
  20. #define INCL_VIO
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdarg.h>
  26. #include <os2.h>
  27.  
  28. #define STDOUT_HANDLE             1
  29. #define STDERR_HANDLE             2
  30. #define STATIC              static
  31.  
  32. #ifndef FILE_NORMAL
  33. #define FILE_NORMAL          0x0000
  34. #define FILE_CREATE          0x0010
  35. #define FILE_TRUNCATE          0x0002
  36. #define OPEN_ACCESS_WRITEONLY      0x0001
  37. #define OPEN_SHARE_DENYWRITE      0x0020
  38. #define OPEN_FLAGS_NOINHERIT      0x0080
  39. #endif
  40.  
  41. STATIC VOID     NEAR _CDECL      ErrorMsg(CHAR *str, ...);
  42.  
  43.  
  44. static HFILE              fh_stdout = STDOUT_HANDLE;
  45. static HFILE              fh_stderr = STDERR_HANDLE;
  46. static CHAR              acBuffer[1024];
  47. static CHAR              szPgmName[128];
  48.  
  49.  
  50. INT _CDECL main(INT argc, CHAR **argv)
  51. {
  52.     register SHORT       i;
  53.     register CHAR      *p;
  54.     auto     SHORT       sLen;
  55.     auto     HFILE       fh_output;
  56.     auto     HFILE       fh_piperead, fh_pipewrite;
  57.     auto     USHORT       usRetCode, usAction;
  58.     auto     RESULTCODES   rc;
  59.     auto     CHAR       szFailName[64];
  60.  
  61.     /* (A) verify we have the minimum number of command line arguments        */
  62.     if (argc < 3)
  63.     {
  64.     ErrorMsg("Usage: %s <filename> <pgmname> [<args> ...]\n", argv[0]);
  65.     DosExit(EXIT_PROCESS, 1);
  66.     }
  67.  
  68.     /* (B) open the output file, truncate it if it exists otherwise create  */
  69.     usRetCode = DosOpen(argv[1], &fh_output,
  70.             &usAction, 0L,
  71.             FILE_NORMAL,
  72.             FILE_CREATE | FILE_TRUNCATE,
  73.             OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE
  74.                           | OPEN_FLAGS_NOINHERIT,
  75.             0L);
  76.     if (usRetCode)
  77.     {
  78.     ErrorMsg("Unable to open file %s (Error status = %u)\n",
  79.          argv[1], usRetCode);
  80.     DosExit(EXIT_PROCESS, 2);
  81.     }
  82.  
  83.     /* (C) create the pipe to be inherited by the child process         */
  84.     usRetCode = DosMakePipe(&fh_piperead, &fh_pipewrite, 0);
  85.     if (usRetCode)
  86.     {
  87.     DosClose(fh_output);
  88.     ErrorMsg("Unable to create pipe (Error status = %u)\n", usRetCode);
  89.     DosExit(EXIT_PROCESS, 3);
  90.     }
  91.  
  92.     /* (D) no longer need original STDOUT and STDERR so close them        */
  93.     DosClose(fh_stdout);
  94.     DosClose(fh_stderr);
  95.  
  96.     /* (E) redirect STDOUT and STDERR to the pipe's write file handle       */
  97.     DosDupHandle(fh_pipewrite, &fh_stdout);
  98.     DosDupHandle(fh_pipewrite, &fh_stderr);
  99.  
  100.     /* (F) set pipe read handle to NOINHERIT so that it will not reduce the */
  101.     /*       number of handles available to the child process            */
  102.     DosSetFHandState(fh_piperead, OPEN_FLAGS_NOINHERIT);
  103.  
  104.     /* (G) the pipe write handle has been redirected, no longer needed        */
  105.     DosClose(fh_pipewrite);
  106.  
  107.     /* (H) format the program name to execute as the child process        */
  108.     if (NULL == strchr(strupr(strcpy(szPgmName, argv[2])), '.'))
  109.     strcat(szPgmName, ".EXE");
  110.  
  111.     /* (I) format the command line to be passed to the child process        */
  112.     strcpy(acBuffer, argv[2]);
  113.     p = acBuffer + strlen(acBuffer) + 1;
  114.     for (i = 3; i < argc; ++i)
  115.     {
  116.     sLen = strlen(argv[i]);
  117.     memcpy(p, argv[i], sLen);
  118.     p   += sLen;
  119.     *p++ = ' ';
  120.     }
  121.     *p++ = '\0';
  122.     *p     = '\0';
  123.  
  124.     /* (J) try to execute the child process                    */
  125.     usRetCode = DosExecPgm(szFailName, sizeof(szFailName),
  126.                EXEC_ASYNC,
  127.                acBuffer,
  128.                NULL,
  129.                &rc,
  130.                szPgmName);
  131.     if (usRetCode)
  132.     {
  133.     ErrorMsg("Unable to bid child %s (Error status = %u [%s])\n",
  134.          szPgmName, usRetCode, szFailName);
  135.     DosExit(EXIT_PROCESS, 4);
  136.     }
  137.  
  138.     /* (K) no longer need the pipe write handles so close them now        */
  139.     DosClose(fh_stdout);
  140.     DosClose(fh_stderr);
  141.  
  142.     /* (L) read data from the pipe and route it to screen and file        */
  143.     while (TRUE)
  144.     {
  145.     auto     USHORT     usBytesRead, usBytesWritten;
  146.     static     BOOL        bError = FALSE;
  147.  
  148.     usRetCode = DosRead(fh_piperead, acBuffer,
  149.                 sizeof(acBuffer), &usBytesRead);
  150.     if (usRetCode || 0 == usBytesRead)
  151.         break;
  152.  
  153.     VioWrtTTY(acBuffer, usBytesRead, 0);
  154.     if (!bError)
  155.     {
  156.         DosWrite(fh_output, acBuffer, usBytesRead, &usBytesWritten);
  157.         if (usBytesWritten != usBytesRead)
  158.         {
  159.         ErrorMsg("Unable to write to output file, disk full?\n");
  160.         bError = TRUE;
  161.         }
  162.     }
  163.     }
  164.  
  165.     /* (M) close the pipe read handle and the output file handle        */
  166.     DosClose(fh_piperead);
  167.     DosClose(fh_output);
  168.     return(0);
  169. }
  170.  
  171.  
  172. STATIC VOID NEAR _CDECL ErrorMsg(CHAR *str, ...)
  173. {
  174.     auto     va_list       va;
  175.  
  176.     va_start(va, str);
  177.     VioWrtTTY(acBuffer, vsprintf(acBuffer, str, va), 0);
  178.     va_end(va);
  179.     return;
  180. }
  181. 
  182.