unnamed_pipe


An unnamed pipe permits two related processes to communicate: typically, a parent and its child. One process sends output to the write end of the pipe; the other process receives input from the read end of the pipe.

Following is a typical sequence of events for setting up and using an unnamed pipe.

  1. The parent process creates an unnamed pipe.
  2. The parent process creates a child that automatically inherits the pipe.
  3. One of the processes writes to the pipe, and the other process reads from it.
  4. Each process closes the pipe when it completes its action.

When an os_unnamed_pipe goes out of scope, it is automatically closed. Therefore, step four above is sometimes omitted. Once a pipe is closed, it cannot be reopened. Writing to an opened unnamed pipe adds data to the start of the FIFO queue. Reading from an opened unnamed pipe removes data from the end of the FIFO queue.

This section discusses uses of unnamed pipes.

Creating an Unnamed Pipe

The following example uses a global pipe inherited by the child process. The parent process writes to the pipe; the child process reads from the pipe and displays the text.

Example <ospace/unix/examples/unnamed1.cpp>
#include <iostream>
#include <ospace/unix.h>

// Global unnamed pipe that is shared by parent and child.
os_unnamed_pipe the_pipe;

int
reader()
  {
  while ( the_pipe.ok() )
    {
    char buffer[ 100 ];
    int result = the_pipe.read( buffer, sizeof( buffer ) );
    if ( the_pipe.eof() ) // Terminate loop when eof occurs.
      break;
    buffer[ result ] = 0; // Null terminate the string.
    cout << buffer << endl; // Display string.
    }
  return 0;
  }

int
main()
  {
  os_unix_toolkit initialize;

  os_process child( reader );
  the_pipe.write( "Systems<ToolKit> is cool!", 25 );
  the_pipe.close(); // Close pipe so that the child detects eof.
  os_this_process::wait_for_child( child );
  return 0;
  }

Systems<ToolKit> is cool!

Using Streams with an Unnamed Pipe

The os_unnamed_pipe class has an associated adapter for use with binary streams and text streams. For convenience, an automatic conversion operator accepts an os_unnamed_pipe whenever an os_adapter is expected. For more information about streams, refer to the Communications User Guide and Reference Manual.

This section contains examples of using text streams and binary streams with an unnamed pipe.

The following example shows how a text stream can be created on an unnamed pipe. The parent process uses the text stream to send text to the child process.

Example <ospace/unix/examples/tstream1.cpp>
#include <iostream>
#include <ospace/stream.h>
#include <ospace/unix.h>

// Global unnamed pipe that is shared by parent and child.
os_unnamed_pipe the_pipe;


// Child process to read from the stream.

int
reader()
  {
  // Create a text stream on the pipe and then read from it.
  os_tstream stream( the_pipe );
  char buffer[ 32 ];
  int num = -1;
  stream.getline( buffer, sizeof( buffer ) );
  stream >> num;
  cout << "Read: " << buffer << endl << num << endl;
  return 0;
  }

int
main()
  {
  os_streaming_toolkit init_stream;
  os_unix_toolkit init_unix;

  // Spawn a reader.
  os_process child( reader );

  // Create a text stream on the pipe and then write to it.
  os_tstream stream( the_pipe );
  char* txt = "This is a line of text.";
  int num = 42;
  cout << "Writing: " << txt << endl << num << endl;
  stream << txt << endl << num << endl;
  return 0;
  }

Writing: This is a line of text.
42
Read: This is a line of text.
42

The following example shows how a binary stream can be created on an unnamed pipe. The parent process uses the binary stream to send objects to the child process.

Example <ospace/unix/examples/bstream1.cpp>
#include <iostream>
#include <ospace/stream.h>
#include <ospace/time.h>
#include <ospace/unix.h>

// Global unnamed pipe that is shared by parent and child.
os_unnamed_pipe the_pipe;


// Child process to read the pipe.

int
reader()
  {
  // Create a binary stream on the pipe and read from it.
  os_bstream stream( the_pipe );
  os_date d;
  os_time t;
  stream >> d >> t;
  cout << "Read: " << d << " at " << t << endl;
  return 0;
  }

int
main()
  {
  os_streaming_toolkit init_stream;
  os_time_toolkit init_time;
  os_unix_toolkit init_unix;

  // Spawn a reader.
  os_process child( reader );

  // Create a binary stream on the pipe and write to it.
  os_bstream stream( the_pipe );
  os_date today = os_date::today();
  os_time now = os_time::now();
  cout << "Writing: " << today << " at " << now << endl;
  stream << today << now;
  return 0;
  }

Writing: 10/19/95 at 14:39:18
Read: 10/19/95 at 14:39:18

Using Processes with Unnamed Pipes

The os_process class has special constructors that automatically redirect descriptor-based I/O objects to the standard I/O channels of a child process. This approach is often used in conjunction with an os_unnamed_pipe , and either an os_tstream or an os_bstream , to communicate between a parent and its child processes.

The following example shows binary streaming over two os_unnamed_pipe objects. The read end of the send pipe becomes standard input for the child process. The write end of the receive pipe becomes standard output for the child process.

The os_process constructor determines the pipe connection behaviors. After spawning the child, the parent process sends a binary integer to the child. The child process squares the integer and returns the result.

Example <ospace/unix/examples/bstream2.cpp>
#include <iostream>
#include <ospace/stream.h>
#include <ospace/unix.h>

int
square_server()
  {
  os_bstream input_stream( os_adapter_for( cin ) );
  os_bstream output_stream( os_adapter_for( cout ) );
  while ( !input_stream.eof() )
    {
    int i;
    input_stream >> i; // Read an integer from standard input.
    output_stream << (i * i);
    }
  return 0;
  }

int
main()
  {
  os_streaming_toolkit init_stream;
  os_unix_toolkit init_unix;

  os_unnamed_pipe send; // Send data to child on this pipe.
  os_unnamed_pipe receive; // Receive data from child on this pipe.

  // Spawn child, connecting the read end of the send pipe to its
  // standard input channel and the write end of the receive pipe to its
  // standard output channel.
    os_process child ( os_nil_env, send.read_end(), receive.write_end(),
    os_nil_desc, square_server );

  os_bstream send_stream( send ); // Create binary stream on send pipe.
  os_bstream receive_stream( receive ); // Create stream on receive pipe.

  // Write 5 to my child's standard input channel.
  send_stream << 5;

  // Read reply from my child's standard output channel.
  int i;
  receive_stream >> i;
  cout << "5 squared is " << i << endl;
  return 0;
  }

5 squared is 25

Copyright©1994-2026 Recursion Software LLC
All Rights Reserved - For use by licensed users only.