TIP: Click on subject to list as thread! ANSI
echo: aust_c_here
to: All
from: Greg Newton
date: 1995-10-21 12:06:18
subject: OS/2 EMX PIPES and THREADS (is that

Hello everybody.  

I've been playing around with pipes and multithreading in a very
exploratory way, and I've had partial success in getting a single program
to talk to another instance of itself over named pipes.

This is the compile instruction:
      gcc -Zmt pltest.c pipeline.c

>>---------------------------------------------------------------
Here's the output from the first instance of the program:
>[d:\programs\it]pltest

Mode is SERVER
Mode is SERVER
`/pipe/meerschaum' created with rc= 0
Mode is SERVER
`/pipe/meerschaum' created with rc= 0
`/pipe/hookah' created with rc= 0
`/pipe/meerschaum' connected with rc= 0
`/pipe/hookah' connected with rc= 0

This was typed from the CLIENT task.


Disconnect result for `/pipe/hookah' is 0
>>---------------------------------------------------------------
Here's the output from the second instance of the program
>[d:\programs\it]pltest

Mode is CLIENT

This was typed from the SERVER task.

>>---------------------------------------------------------------
Here's pltest.c

#include 
#include 
UCHAR uchPipeLine();
int main( void )
{
   UCHAR mode;

   mode = uchPipeLine();
   printf("\nMode is %s", mode ? "CLIENT" : "SERVER" );
   for(;;)
      sleep(4294967);
}
>>---------------------------------------------------------------
Here's pipeline.c

/*
   PIPELINE.C
   Functions initialise two-way communication with a pair of pipes
   and begin threads to read from and write to the pipes.
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SERVER 0
#define CLIENT 1

/* macros to clearly indicate which index to use into PipeNames, etc */
#define INCOMING (uchMode)
#define OUTGOING ((uchMode+1)&1)

#define STACKTOUSE    8192
#define BUFLENGTH      256

/* Function declarations */
void outpipefunc( void );
void inpipefunc( void );
void outfilefunc( void );
void infilefunc( void* phInFile );

static PCSZ pcszPipeNames[] =
{
   "/pipe/hookah",             
   "/pipe/meerschaum"
};

static UCHAR uchMode = CLIENT;   /* initialised to CLIENT for 'open' */

UCHAR uchPipeLine()
{
   static int hInFile;            /* file handle to already created pipe 
                                    has to be static as passed by pointer
                                    to infilefunc thread 
                                  */

   /* try to open pipe */
   hInFile = open( pcszPipeNames[INCOMING], O_RDONLY | O_BINARY );
   if( -1 == hInFile )            /* does not exist yet */
   {
      uchMode = SERVER;
      _beginthread( outpipefunc, NULL, STACKTOUSE, NULL );
      _beginthread( inpipefunc,  NULL, STACKTOUSE, NULL );
   }
   else
   {
      uchMode = CLIENT;
      _beginthread( outfilefunc, NULL, STACKTOUSE, NULL );
      _beginthread( infilefunc,  NULL, STACKTOUSE, (void *)&hInFile );
   }
   return uchMode;
}
/* outbound file thread */
void outfilefunc( void )
{
   int hOutFile;
   int c;

   hOutFile = open( pcszPipeNames[OUTGOING], O_WRONLY | O_BINARY );
   if( hOutFile == -1 )
   {
      printf("\nUnable to open `%s'", pcszPipeNames[OUTGOING] );
      exit(1);
   }
   for(;;)
   {
      c = getch();
      c &= 0xff;            /* mask off high bits */
      if( c == '\x1b' )      /* quit on escape key */
      {
         write( hOutFile, &c, sizeof(char) );
         printf("\n\nDead in five seconds..." );
         sleep(5);
         break;
      }
      else if( c == 0 )            /* trash function keys, etc */
         getch();
      else
         write( hOutFile, &c, sizeof(char) );
   }
   close( hOutFile );
   exit(0);
}
/* inbound file thread */
void infilefunc( void* phInFile )
{
   int hInFile;
   int c;

   hInFile = *((int *)phInFile);
   for(;;)
   {
      read( hInFile, &c, sizeof( char ) );
      c &= 0xff;
      if( c == '\x1b' )
         break;
      putchar(c);
   }
   close( hInFile );
   exit(0);
}

/* variables available to pipe functions only */
static ULONG ulOpenMode[] = 
{
   NP_ACCESS_INBOUND  | NP_NOINHERIT,
   NP_ACCESS_OUTBOUND  | NP_NOINHERIT
};
static ULONG ulPipeMode =   NP_WAIT | NP_READMODE_BYTE |
                     NP_TYPE_BYTE | NP_UNLIMITED_INSTANCES;

/* outbound pipe thread */
void outpipefunc( void )
{
   ULONG rc;
   HPIPE hOutPipe;
   int   c;

   rc = DosCreateNPipe(
                     pcszPipeNames[OUTGOING],
                     &hOutPipe,
                     ulOpenMode[OUTGOING],
                     ulPipeMode,
                     BUFLENGTH,         /* inbuf length */
                     BUFLENGTH,         /* outbuf length */
                     0L);         /* timeout */

   printf("\n`%s' created with rc= %d", pcszPipeNames[OUTGOING], rc);
   /* Wait for client connect, use pipe, etc */
   rc = DosConnectNPipe( hOutPipe );
   printf("\n`%s' connected with rc= %d", pcszPipeNames[OUTGOING], rc );

   for(;;)
   {
      c = getch();
      c &= 0xff;
      if( c == '\x1b' )      /* quit on escape key */
      {
         write( hOutPipe, &c, sizeof(char) );
         sleep(1);
         break;
      }
      else if( c == 0 )
         getch();
      else
      {
         write( hOutPipe, &c, sizeof(char) );
      }
   }
   printf("\nDisconnect result for `%s' is %d",
         pcszPipeNames[OUTGOING],
         DosDisConnectNPipe(hOutPipe)
         );
   exit(0);
}
/* inbound pipe thread */
void inpipefunc( void )
{
   ULONG rc;
   HPIPE hInPipe;
   int c;

   rc = DosCreateNPipe(
                     pcszPipeNames[INCOMING],
                     &hInPipe,
                     ulOpenMode[INCOMING],
                     ulPipeMode,
                     BUFLENGTH,         /* inbuf length */
                     BUFLENGTH,         /* outbuf length */
                     0L);         /* timeout */

   printf("\n`%s' created with rc= %d", pcszPipeNames[INCOMING], rc);
   /* Wait for client connect, use pipe, etc */

   rc = DosConnectNPipe( hInPipe );
   printf("\n`%s' connected with rc= %d", pcszPipeNames[INCOMING], rc );
   for(;;)
   {
      read( hInPipe, &c, sizeof( char ) );
      c &= 0xff;
      if( c == '\x1b' )
         break;
      putchar(c);
   }
   printf("\nDisconnect result for `%s' is %d",
         pcszPipeNames[INCOMING],
         DosDisConnectNPipe(hInPipe)
         );
   exit(0);
}

>>---------------------------------------------------------------

My question is "Why does the first instance of the program print
"Mode is SERVER" three times, and open '/pipe/meerschaum' twice?

The overall aim of this exercise is ultimately to test protocol
implementations using pipes instead of serial ports.  This is my first
serious attack at OS/2 programming (ok, so it's not that serious!).

Any ideas welcome!

Cheers, 
Greg   |;^)

--- FleetStreet 1.04 #429
* Origin: Permaculture 1 BBS * Northcote_Aust * +61-3-9482-2942 (3:639/666)
SEEN-BY: 50/99 620/243 623/630 632/348 998 633/371 634/384 635/301 502 503
SEEN-BY: 635/544 639/100 666 711/401 409 410 413 430 510 807 808 809 932 934
SEEN-BY: 712/515 713/888 714/906 800/1 7877/2809
@PATH: 639/666 100 635/503 50/99 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.