home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MXPIPE12.LZH / MAXPIPE.C next >
C/C++ Source or Header  |  1991-12-08  |  7KB  |  297 lines

  1. #include <stdio.h>
  2. #include <process.h>
  3. #include <conio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define INCL_NOPM
  7. #define INCL_DOS
  8. #define INCL_VIO
  9. #define INCL_DOSDEVICES
  10. #define INCL_DOSDEVIOCTL
  11. #include <os2.h>
  12. #if !defined(CALLBACK)
  13. #include "os2fubar.h"
  14. #endif
  15.  
  16. #include "comm.h"
  17.  
  18. extern  int DupHandles(void );
  19. extern  int StartThreads(void );
  20. extern  void CloseHandles(void );
  21. extern  void cdecl main(int argc,char * *argv);
  22. extern  void nextfh(void );
  23. static  void far _loadds WatchDogThread(void );
  24. static  int CHAR_AVAIL(void );
  25. static  BYTE GET_CHAR(void );
  26. static  void far _loadds StdinThread(void );
  27. static  void far _loadds StdoutThread(void );
  28.  
  29. #define STACK1 0x400
  30. #define STACK2 0x400
  31. #define STACK3 0x400
  32.  
  33. static HCOMM hfCom;         // modem
  34. static HFILE hfStdoutR;
  35. static HFILE hfStdoutW;
  36. static HFILE hfStdinR;
  37. static HFILE hfStdinW;
  38. static HFILE oldStdin, oldStdout, oldStderr;
  39. static PID pidProc;
  40. int alive =  TRUE;
  41. int large = 0;
  42.  
  43. void cdecl main(int argc, char **argv)
  44. {
  45.     PID pidd;
  46.     RESULTCODES rescResults;
  47.     int hf;
  48.  
  49.     nextfh();
  50.     if( argc < 3 ){
  51.         printf("MaxPipe v1.12 Copyright (c) Peter Fitzsimmons, 1990\n");
  52.         printf("Usage: maxpipe <comm handle> <program.exe> [arguments]\n");
  53.         exit(0);
  54.     }
  55.     hf = (HFILE)atoi(argv[1]);
  56.     if(hf<=0 || hf>255){
  57.         if(ComOpen(argv[1], &hfCom, 0, 0))
  58.             hfCom = 0;
  59.     }
  60.     else
  61.         ComHRegister(hf, &hfCom, 0, 0);
  62.  
  63.     rescResults.codeResult = 0;
  64.     if(DupHandles() && StartThreads()){
  65.         printf("MAXPIPE is now spawning %s\n", argv[2]);
  66.         pidProc = spawnvp(P_NOWAIT, argv[2], &argv[2]);
  67.         if(pidProc != -1)
  68.             DosCwait(DCWA_PROCESSTREE, DCWW_WAIT, &rescResults, &pidd, pidProc);
  69.         else{
  70.             fprintf(stderr, "Couldn't spawn %s\n", argv[2]);
  71.             rescResults.codeResult = 1;
  72.         }
  73.     }
  74.     else
  75.         exit(3);
  76.     if(hfCom)
  77.         ComTxWait(hfCom, 2000L);
  78.     CloseHandles();
  79.     nextfh();
  80.     exit(rescResults.codeResult);
  81. }
  82.  
  83. int DupHandles(void)
  84. {
  85.     HFILE sin = fileno(stdin);
  86.     HFILE sout = fileno(stdout);
  87.     HFILE serr = fileno(stderr);
  88.  
  89.     oldStdin = oldStdout = oldStderr = 0xffff;
  90.     DosDupHandle(sin,  &oldStdin );
  91.     DosDupHandle(sout, &oldStdout);
  92.     DosDupHandle(serr, &oldStderr);
  93.  
  94.  
  95.     if(DosMakePipe(&hfStdoutR, &hfStdoutW, 150) ||
  96.        DosMakePipe(&hfStdinR, &hfStdinW, 150) ||
  97.        DosDupHandle(hfStdinR, &sin) ||
  98.        DosDupHandle(hfStdoutW, &serr) ||
  99.        DosDupHandle(hfStdoutW, &sout))
  100.     {
  101.         fprintf(stderr, "Couldn't dup stdin/stdout handles\n");
  102.         return(FALSE);
  103.     }
  104.  
  105. //  printf("pipe>Std handles duped successfully\n");
  106.     return(TRUE);
  107. }
  108.  
  109. void * zalloc(size_t bytes)
  110. {
  111.     void * ret = malloc(bytes);
  112.     if(!ret){
  113.         fprintf(stderr, "Couldn't allocate %u bytes\n", bytes);
  114.         exit(3);
  115.     }
  116.     return(ret);
  117. }
  118.  
  119. int StartThreads(void)
  120. {
  121.     BYTE *stack1, *stack2, *stack3;
  122.     TID tid1, tid2, tid3;
  123.     stack1 = zalloc(STACK1);
  124.     stack2 = zalloc(STACK2);
  125.  
  126.     if( DosCreateThread((PFNTHREAD)StdinThread, &tid1, stack1+STACK1) ||
  127.         DosCreateThread((PFNTHREAD)StdoutThread, &tid2, stack2+STACK2) )
  128.     {
  129.         fprintf(stderr, "Couldn't create threads\n");
  130.         return(FALSE);
  131.     }
  132. //  printf("pipe>Stdin/Stdout threads created successfully\n");
  133.     if( hfCom ){
  134.         stack3 = zalloc(STACK3);
  135.         if(DosCreateThread((PFNTHREAD)WatchDogThread, &tid3, stack3+STACK3)){
  136.             fprintf(stderr, "Couldn't create Watchdog thread\n");
  137.             return(FALSE);
  138.         }
  139. //      printf("pipe>WatchDog thread created successfully\n");
  140.     }
  141.     return(TRUE);
  142. }
  143.  
  144. void CloseHandles(void)
  145. {
  146.     HFILE sin = fileno(stdin);
  147.     HFILE sout = fileno(stdout);
  148.     HFILE serr = fileno(stderr);
  149.  
  150.     DosClose(hfStdoutR);
  151.     DosClose(hfStdoutW);
  152.     DosClose(hfStdinR);
  153.     DosClose(hfStdinW);
  154.     DosDupHandle(oldStderr, &serr);
  155.     DosDupHandle(oldStdout, &sout);
  156.     DosDupHandle(oldStdin, &sin);
  157.     DosClose(oldStderr);
  158.     DosClose(oldStdout);
  159.     DosClose(oldStdin);
  160. }
  161.  
  162.  
  163. void nextfh(void)
  164. {
  165. #if 0
  166.     FILE *f = fopen("out", "wb");
  167.     fprintf(stderr, "fh = %u\n", fileno(f));
  168.     fclose(f);
  169. #endif
  170. }
  171.  
  172. #pragma check_stack(off)
  173.  
  174.  
  175. /* wake up every 15 seconds and check the carrier */
  176. static VOID FAR _loadds WatchDogThread(void)
  177. {
  178.     while(alive){
  179.         DosSleep(1000L);
  180.         if(!ComIsOnline(hfCom))
  181.             DosKillProcess(DKP_PROCESSTREE, pidProc);
  182.         else
  183.             DosBufReset(fileno(stdout));
  184.     }
  185.     DosExit(EXIT_THREAD, 0);
  186. }
  187.  
  188.  
  189. static int CHAR_AVAIL(void)
  190. {
  191.     if( kbhit() )
  192.         return(TRUE);
  193.     if( hfCom )
  194.         return (ComPeek(hfCom) != -1);
  195.     else
  196.         return(FALSE);
  197. }
  198.  
  199.  
  200. static BYTE GET_CHAR(void)
  201. {
  202.     BYTE c;
  203.  
  204.     if( kbhit() )
  205.         return (BYTE)getch();
  206.     ComRxWait(hfCom, 10000L);
  207.     c = (BYTE)ComGetc(hfCom);
  208.     if( c == 3 ){
  209.         if(!DosSendSignal(pidProc, SIG_CTRLBREAK))
  210.             ComPurge(hfCom, COMM_PURGE_ALL);
  211.     }
  212.     return(c);
  213. }
  214.  
  215. static VOID FAR _loadds StdinThread(void)
  216. {
  217.     static char linebuf[100];
  218.     USHORT bytes, bo;
  219.     BYTE c;
  220.  
  221.     bytes = 0;
  222.     while(alive){
  223.         if( CHAR_AVAIL() ){
  224.             while( CHAR_AVAIL() && bytes<sizeof(linebuf))
  225.             {
  226.                 c = GET_CHAR();
  227.                 if(c == '\r'){
  228.                     c = '\n';
  229.                 }
  230.                 if( c == 8 ){    // backspace
  231.                     if( bytes>0 ){
  232.                         bytes--;
  233.                         DosWrite(hfStdoutW, "\x8 \x8", 3, &bo);
  234.                     }
  235.                 }
  236.                 else{
  237.                     linebuf[bytes++] = (char)c;
  238.                     DosWrite(hfStdoutW, &c, 1, &bo);
  239.                 }
  240.             }
  241.             if( c == '\n'){
  242.                 DosWrite(hfStdinW, linebuf, bytes, &bo);
  243.                 bytes = 0;
  244.             }
  245.         }
  246.         else
  247.             DosSleep(1L);
  248.     }
  249.     DosExit(EXIT_THREAD, 0);
  250. }
  251.  
  252.  
  253. #if 1
  254. static VOID FAR _loadds StdoutThread(void)
  255. {
  256.     static char bufout[200];
  257.     static char buf[150];
  258.     USHORT bytes,i,j;
  259.  
  260.     while(alive){
  261.         DosRead(hfStdoutR, buf, sizeof(buf), &bytes);
  262.         for(i=j=0; i<bytes; i++){
  263.             if( buf[i] == '\n' )
  264.                 bufout[j++] = '\r';
  265.             bufout[j++] = buf[i];
  266.         }
  267.         if(hfCom)
  268.             ComWrite(hfCom, bufout, j);
  269.         VioWrtTTY(bufout, j, 0);
  270. /*        if( j > 100)
  271.             DosSleep(1L);
  272.         if( j > large )
  273.             large = j;*/
  274.     }
  275.     DosExit(EXIT_THREAD, 0);
  276. }
  277. #else
  278. static VOID FAR _loadds StdoutThread(void)
  279. {
  280.     SHORT c, c2;
  281.     USHORT bytes;
  282.  
  283.     while(alive){
  284.         DosRead(hfStdoutR, &c, 1, &bytes);
  285.         if( c  == '\n' ){
  286.             ComPutc(hfCom, '\r');
  287.             c2 = '\r';
  288.             VioWrtTTY((PCH)&c2, 1, 0);
  289.         }
  290.         ComPutc(hfCom, c);
  291.         VioWrtTTY((PCH)&c, 1, 0);
  292.     }
  293.     DosExit(EXIT_THREAD, 0);
  294. }
  295. #endif
  296.  
  297.