home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
MXPIPE12.LZH
/
MAXPIPE.C
next >
Wrap
C/C++ Source or Header
|
1991-12-08
|
7KB
|
297 lines
#include <stdio.h>
#include <process.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define INCL_NOPM
#define INCL_DOS
#define INCL_VIO
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#include <os2.h>
#if !defined(CALLBACK)
#include "os2fubar.h"
#endif
#include "comm.h"
extern int DupHandles(void );
extern int StartThreads(void );
extern void CloseHandles(void );
extern void cdecl main(int argc,char * *argv);
extern void nextfh(void );
static void far _loadds WatchDogThread(void );
static int CHAR_AVAIL(void );
static BYTE GET_CHAR(void );
static void far _loadds StdinThread(void );
static void far _loadds StdoutThread(void );
#define STACK1 0x400
#define STACK2 0x400
#define STACK3 0x400
static HCOMM hfCom; // modem
static HFILE hfStdoutR;
static HFILE hfStdoutW;
static HFILE hfStdinR;
static HFILE hfStdinW;
static HFILE oldStdin, oldStdout, oldStderr;
static PID pidProc;
int alive = TRUE;
int large = 0;
void cdecl main(int argc, char **argv)
{
PID pidd;
RESULTCODES rescResults;
int hf;
nextfh();
if( argc < 3 ){
printf("MaxPipe v1.12 Copyright (c) Peter Fitzsimmons, 1990\n");
printf("Usage: maxpipe <comm handle> <program.exe> [arguments]\n");
exit(0);
}
hf = (HFILE)atoi(argv[1]);
if(hf<=0 || hf>255){
if(ComOpen(argv[1], &hfCom, 0, 0))
hfCom = 0;
}
else
ComHRegister(hf, &hfCom, 0, 0);
rescResults.codeResult = 0;
if(DupHandles() && StartThreads()){
printf("
MAXPIPE is now spawning %s
\n", argv[2]);
pidProc = spawnvp(P_NOWAIT, argv[2], &argv[2]);
if(pidProc != -1)
DosCwait(DCWA_PROCESSTREE, DCWW_WAIT, &rescResults, &pidd, pidProc);
else{
fprintf(stderr, "Couldn't spawn %s\n", argv[2]);
rescResults.codeResult = 1;
}
}
else
exit(3);
if(hfCom)
ComTxWait(hfCom, 2000L);
CloseHandles();
nextfh();
exit(rescResults.codeResult);
}
int DupHandles(void)
{
HFILE sin = fileno(stdin);
HFILE sout = fileno(stdout);
HFILE serr = fileno(stderr);
oldStdin = oldStdout = oldStderr = 0xffff;
DosDupHandle(sin, &oldStdin );
DosDupHandle(sout, &oldStdout);
DosDupHandle(serr, &oldStderr);
if(DosMakePipe(&hfStdoutR, &hfStdoutW, 150) ||
DosMakePipe(&hfStdinR, &hfStdinW, 150) ||
DosDupHandle(hfStdinR, &sin) ||
DosDupHandle(hfStdoutW, &serr) ||
DosDupHandle(hfStdoutW, &sout))
{
fprintf(stderr, "Couldn't dup stdin/stdout handles\n");
return(FALSE);
}
// printf("pipe>Std handles duped successfully\n");
return(TRUE);
}
void * zalloc(size_t bytes)
{
void * ret = malloc(bytes);
if(!ret){
fprintf(stderr, "Couldn't allocate %u bytes\n", bytes);
exit(3);
}
return(ret);
}
int StartThreads(void)
{
BYTE *stack1, *stack2, *stack3;
TID tid1, tid2, tid3;
stack1 = zalloc(STACK1);
stack2 = zalloc(STACK2);
if( DosCreateThread((PFNTHREAD)StdinThread, &tid1, stack1+STACK1) ||
DosCreateThread((PFNTHREAD)StdoutThread, &tid2, stack2+STACK2) )
{
fprintf(stderr, "Couldn't create threads\n");
return(FALSE);
}
// printf("pipe>Stdin/Stdout threads created successfully\n");
if( hfCom ){
stack3 = zalloc(STACK3);
if(DosCreateThread((PFNTHREAD)WatchDogThread, &tid3, stack3+STACK3)){
fprintf(stderr, "Couldn't create Watchdog thread\n");
return(FALSE);
}
// printf("pipe>WatchDog thread created successfully\n");
}
return(TRUE);
}
void CloseHandles(void)
{
HFILE sin = fileno(stdin);
HFILE sout = fileno(stdout);
HFILE serr = fileno(stderr);
DosClose(hfStdoutR);
DosClose(hfStdoutW);
DosClose(hfStdinR);
DosClose(hfStdinW);
DosDupHandle(oldStderr, &serr);
DosDupHandle(oldStdout, &sout);
DosDupHandle(oldStdin, &sin);
DosClose(oldStderr);
DosClose(oldStdout);
DosClose(oldStdin);
}
void nextfh(void)
{
#if 0
FILE *f = fopen("out", "wb");
fprintf(stderr, "fh = %u\n", fileno(f));
fclose(f);
#endif
}
#pragma check_stack(off)
/* wake up every 15 seconds and check the carrier */
static VOID FAR _loadds WatchDogThread(void)
{
while(alive){
DosSleep(1000L);
if(!ComIsOnline(hfCom))
DosKillProcess(DKP_PROCESSTREE, pidProc);
else
DosBufReset(fileno(stdout));
}
DosExit(EXIT_THREAD, 0);
}
static int CHAR_AVAIL(void)
{
if( kbhit() )
return(TRUE);
if( hfCom )
return (ComPeek(hfCom) != -1);
else
return(FALSE);
}
static BYTE GET_CHAR(void)
{
BYTE c;
if( kbhit() )
return (BYTE)getch();
ComRxWait(hfCom, 10000L);
c = (BYTE)ComGetc(hfCom);
if( c == 3 ){
if(!DosSendSignal(pidProc, SIG_CTRLBREAK))
ComPurge(hfCom, COMM_PURGE_ALL);
}
return(c);
}
static VOID FAR _loadds StdinThread(void)
{
static char linebuf[100];
USHORT bytes, bo;
BYTE c;
bytes = 0;
while(alive){
if( CHAR_AVAIL() ){
while( CHAR_AVAIL() && bytes<sizeof(linebuf))
{
c = GET_CHAR();
if(c == '\r'){
c = '\n';
}
if( c == 8 ){ // backspace
if( bytes>0 ){
bytes--;
DosWrite(hfStdoutW, "\x8 \x8", 3, &bo);
}
}
else{
linebuf[bytes++] = (char)c;
DosWrite(hfStdoutW, &c, 1, &bo);
}
}
if( c == '\n'){
DosWrite(hfStdinW, linebuf, bytes, &bo);
bytes = 0;
}
}
else
DosSleep(1L);
}
DosExit(EXIT_THREAD, 0);
}
#if 1
static VOID FAR _loadds StdoutThread(void)
{
static char bufout[200];
static char buf[150];
USHORT bytes,i,j;
while(alive){
DosRead(hfStdoutR, buf, sizeof(buf), &bytes);
for(i=j=0; i<bytes; i++){
if( buf[i] == '\n' )
bufout[j++] = '\r';
bufout[j++] = buf[i];
}
if(hfCom)
ComWrite(hfCom, bufout, j);
VioWrtTTY(bufout, j, 0);
/* if( j > 100)
DosSleep(1L);
if( j > large )
large = j;*/
}
DosExit(EXIT_THREAD, 0);
}
#else
static VOID FAR _loadds StdoutThread(void)
{
SHORT c, c2;
USHORT bytes;
while(alive){
DosRead(hfStdoutR, &c, 1, &bytes);
if( c == '\n' ){
ComPutc(hfCom, '\r');
c2 = '\r';
VioWrtTTY((PCH)&c2, 1, 0);
}
ComPutc(hfCom, c);
VioWrtTTY((PCH)&c, 1, 0);
}
DosExit(EXIT_THREAD, 0);
}
#endif