home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / wf_expl / doscl1.c < prev    next >
Text File  |  1992-05-03  |  11KB  |  268 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*                                                                          */
  5. /* COPYRIGHT IBM CORP., 1992                                                */
  6. /*                                                                          */
  7. /* ------------------------------------------------------------------------ */
  8. /*                                                                          */
  9. /*                                                                          */
  10. /* This is the OS/2 component of the DOSRUN package.  It's responsible      */
  11. /* for establishing a unique container between this OS/2 component and      */
  12. /* its sister DOS component.  The DOS component will handle redirecting     */
  13. /* all STDOUT and STDERR messages from the DOS tool into this unique        */
  14. /* container.  Once the DOS tool has completed, it will also communicate    */
  15. /* the return codes either through the container or through some other      */
  16. /* means.  In the current DOSRUN package, the unique container implemented  */
  17. /* is a simple temporary file.  Once the DOS tool has completed, the        */
  18. /* return codes will also be added to the end of the temporary file.        */
  19. /* While the OS/2 component is waiting for the DOS tool to end, it will     */
  20. /* read from the unique container and echo it out to its STDOUT.  Since     */
  21. /* the WorkFrame/2 has already redirected its STDOUT and STDERR into        */
  22. /* the WorkFrame/2's output listbox, this is all that is required to        */
  23. /* redirect the DOS tool output into the WorkFrame/2's output listbox.      */
  24. /*                                                                          */
  25. /* The following illustrates this process for a DOS compiler:               */
  26. /*                                                                          */
  27. /*                                                                          */
  28. /*  ┌────┐                                                                  */
  29. /*  │    │                                                                  */
  30. /*  │    │                                                                  */
  31. /*  │    │                                                                  */
  32. /*  │WF/2│                                                                  */
  33. /*  │    │                                                                  */
  34. /*  │    │                                                                  */
  35. /*  └─┬──┘                                                                  */
  36. /*    │                                                                     */
  37. /*    │  User invokes                                                       */
  38. /*    │  action COMPILE                                                     */
  39. /*                                                                         */
  40. /*  ┌─┴─────────┐                    ┌────────┐                             */
  41. /*  │           │                    │WF/2    │                             */
  42. /*  │WF/2       ├───────────────────┤Output  │                             */
  43. /*  │Background │                    │Listbox │                             */
  44. /*  │Thread     │                    └───┬────┘                             */
  45. /*  └─┬─────────┘                        │                                  */
  46. /*    │                                  Contents of the unique container  */
  47. /*    │  Redirect STDOUT/STDERR          │is echoed by DOSCL1.EXE through   */
  48. /*    │  back to output listbox          │its STDOUT which has been         */
  49. /*    │  and invoke DOSCL1.EXE           │redirected back to the WF/2.      */
  50. /*                                  ┌───┴─────┐                            */
  51. /*  ┌─┴────────┐                     │Unique   │                            */
  52. /*  │DOSCL1.EXE├────────────────────┤Container│                            */
  53. /*  └─┬────────┘                     │         │                            */
  54. /*    │                              └───┬─────┘                            */
  55. /*    │  Create a unique container       │                                  */
  56. /*    │  and invoke DOSCL2.EXE                                             */
  57. /*    │  the name of the container       │                                  */
  58. /*                                      │                                  */
  59. /*  ┌─┴────────┐                         │                                  */
  60. /*  │DOSCL2.EXE│                         │                                  */
  61. /*  └─┬────────┘                         │                                  */
  62. /*    │                                  │                                  */
  63. /*    │  Redirect STDOUT/STDERR          │                                  */
  64. /*    │  back to the unique container    │STDOUT/STDERR from DOS            */
  65. /*    │  and invoke DOS Compiler         │compiler redirected back to       */
  66. /*                                      │the unique container              */
  67. /*  ┌─┴──────────┐                       │                                  */
  68. /*  │DOS Compiler├──────────────────────┘                                  */
  69. /*  └────────────┘                                                          */
  70. /*                                                                          */
  71. /*                                                                          */
  72. /*                                                                          */
  73. /* A better implementation could use a named pipe as the unique container.  */
  74. /* This way, you can avoid the expense of the physical I/O to disk.         */
  75. /*                                                                          */
  76. /****************************************************************************/
  77.  
  78. #define INCL_DOS
  79. #define INCL_ERRORS
  80. #define INCL_WIN
  81. #include <os2.h>
  82. #include <string.h>
  83. #include <stdio.h>
  84. #include <process.h>
  85. #include <stdlib.h>
  86. #include <signal.h>
  87. #define EOFFLAG  26
  88.  
  89. static unsigned char *get_cmdline( void );
  90.  
  91. #define BUFSIZE 256
  92.  
  93. ULONG  sess_id,pid;
  94. char  *tempfile;
  95. HFILE  handle;
  96.  
  97. void handler( int signum );
  98. BOOL ReadData( HFILE handle );
  99. char tmpbuf[BUFSIZE];
  100. int  rc;
  101.  
  102. int main( void )
  103. {
  104.    unsigned char *pCmdline;
  105.    STARTDATA  sd;               /* structure defined in bsedos.h */
  106.    STATUSDATA statusData;
  107.    char      *buffer;
  108.    char      *p1, *p2;
  109.    char      *doscl2;
  110.    ULONG      action;
  111.    BOOL       Done, Done2=FALSE;
  112.  
  113.  
  114.   /* Set exception handler for CTRL-C and CTRL-BREAK.                        */
  115.   if ( SIG_ERR==signal(SIGILL, handler )  ||
  116.        SIG_ERR==signal(SIGTERM, handler )  ||
  117.        SIG_ERR==signal(SIGBREAK, handler )  )
  118.      exit(2);
  119.  
  120.    /* Get a pointer to the command line.                                      */
  121.    pCmdline = get_cmdline( );
  122.  
  123.    /* Get the executable directory, use it for doscl2.exe */
  124.    p1 = pCmdline + strlen( pCmdline );
  125.    p2 = p1 + 1;
  126.    while ( p1 != pCmdline && *(p1-1) != '\\' && *(p1-1) != '/' ) --p1;
  127.  
  128.    *p1 = '\0';
  129.  
  130.    /* Fully qualify doscl2.exe */
  131.    doscl2 = malloc( strlen(pCmdline) + strlen("doscl2.exe") + 1 );
  132.    strcpy( doscl2, pCmdline );
  133.    strcat( doscl2, "doscl2.exe" );
  134.  
  135.    /* Open a tempfile for doscl2.exe to write and doscl1.exe to read */
  136.    tempfile = tmpnam( NULL );
  137.    if ( (rc=DosOpen( tempfile,
  138.                               &handle,
  139.                               &action,
  140.                               0,
  141.                               FILE_NORMAL,
  142.                               OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
  143.                               OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
  144.                               0 )) != 0 )
  145.      {
  146.      return rc;
  147.      }
  148.  
  149.    /* Construct the input parameter string to doscl2.exe */
  150.    buffer = malloc( strlen(tempfile) + strlen(p2) + 2 );
  151.    strcpy( buffer, tempfile );
  152.    strcat( buffer, " " );
  153.    strcat( buffer, p2 );
  154.  
  155.    sd.Length      = 32;
  156.    sd.Related     = SSF_RELATED_CHILD;
  157.    sd.FgBg        = SSF_FGBG_BACK;
  158.    sd.TraceOpt    = SSF_TRACEOPT_NONE;
  159.    sd.PgmTitle    = "WF/2 DOS Client";
  160.    sd.PgmName     = doscl2;
  161.    sd.PgmInputs   = buffer;
  162.    sd.TermQ       = NULL;
  163.    sd.Environment = NULL;
  164.    sd.InheritOpt  = SSF_INHERTOPT_PARENT;
  165.    sd.SessionType = SSF_TYPE_WINDOWEDVDM;
  166.  
  167.    statusData.Length = 6;
  168.    statusData.SelectInd = 0;
  169.    statusData.SelectInd = 0;
  170.  
  171.    if (!DosStartSession( &sd, &sess_id, &pid ))
  172.       Done      = FALSE;
  173.  
  174.    /* Wait for doscl2.exe to finish, keep reading tempfile at the same time */
  175.    while( !Done )
  176.       {
  177.       if ( DosSetSession( sess_id, &statusData ) )
  178.          Done = TRUE;
  179.  
  180.       DosSleep(5000);
  181.  
  182.       Done2 = ReadData( handle );
  183.       }
  184.  
  185.    while ( !Done2 )
  186.       {
  187.       Done2 = ReadData( handle );
  188.       } /* endwhile */
  189.  
  190.    DosClose( handle );
  191.    DosDelete( tempfile );
  192.    free( doscl2 );
  193.    free( buffer );
  194.  
  195.    return(rc);
  196. }
  197.  
  198.  
  199.  
  200. BOOL ReadData( HFILE handle )
  201.    {
  202.    BOOL   ret = FALSE;
  203.    char * p1;
  204.    int    dif;
  205.    char   crc[2];
  206.    ULONG  bytesread;
  207.    ULONG  actual;
  208.  
  209.    DosRead( handle, tmpbuf, BUFSIZE, &bytesread );
  210.  
  211.    if ( bytesread )
  212.       {
  213.       if (p1=memchr( tmpbuf, EOFFLAG, bytesread ) )
  214.          {
  215.          dif        = bytesread - (int)(p1-tmpbuf);
  216.          bytesread -= dif;
  217.          if (dif < 3)
  218.             {
  219.             DosRead( handle, crc+dif, 3-dif, &bytesread );
  220.             if (dif==1)
  221.                crc[0] = *(p1+1);
  222.             rc = *(unsigned int *)crc;
  223.             }
  224.          else
  225.             rc = *(unsigned int *)(p1+1);
  226.  
  227.          ret = TRUE;
  228.          } /* endif */
  229.  
  230.       DosWrite( 1, tmpbuf, bytesread, &actual );
  231.       }
  232.  
  233.    return( ret );
  234.    }
  235.  
  236.  
  237. /* This function will return a pointer to the command line string.            */
  238.  
  239. static unsigned char *get_cmdline( void )
  240.    {
  241.    PTIB            ptib;
  242.    PPIB            ppib;
  243.  
  244.    /* Get a pointer to the first through n arguments that were entered on     */
  245.    /* the command line.                                                       */
  246.  
  247.    DosGetInfoBlocks( &ptib, &ppib );
  248.  
  249.    return (ppib->pib_pchcmd);
  250.  
  251.    }
  252.  
  253. static void handler( int signum )
  254.    {
  255.    int rc;
  256.  
  257.    rc = DosStopSession( STOP_SESSION_ALL, sess_id );
  258.    printf( "DosStopSession rc = %d\n", rc );
  259.    rc = DosClose( handle );
  260.    printf( "DosClose rc = %d\n", rc );
  261.    rc = DosDelete( tempfile );
  262.    printf( "DosDelete rc = %d\n", rc );
  263.  
  264.    exit( EXIT_FAILURE );
  265.  
  266.    signum = 0;
  267.    }
  268.