with Ada.Strings.Unbounded.Text_IO, Ada.Text_IO, POSIX.IO;

procedure Pipe_Demonstration is
   package Unbounded_Strings renames Ada.Strings.Unbounded;
   Input, Output : POSIX.IO.File_Descriptor;
   Line          : Unbounded_Strings.Unbounded_String;
   Written       : Natural;
begin
   POSIX.IO.Create_Pipe (Read_End  => Input,
                         Write_End => Output);

   Ada.Text_IO.Put_Line (Item => "Got a pipe!");
   Ada.Text_IO.Put_Line (Item => "Reading from file descriptor " &
                           POSIX.IO.File_Descriptor'Image (Input) &
                           " and writing to file descriptor " &
                           POSIX.IO.File_Descriptor'Image (Output) & ".");

   while not Ada.Text_IO.End_Of_File loop
      Line := Unbounded_Strings.Text_IO.Get_Line;

      POSIX.IO.NONSTANDARD_Write (File   => Output,
                                  Buffer => POSIX.To_POSIX_String
                                    (Unbounded_Strings.To_String (Line)),
                                  Last   => Written);
      if Written /= Unbounded_Strings.Length (Line) then
         Ada.Text_IO.Put_Line (File => Ada.Text_IO.Standard_Error,
                               Item => "Error writing to pipe.");
         exit;
      end if;

      declare
         Buffer : POSIX.IO.IO_Buffer (1 .. Unbounded_Strings.Length (Line)) :=
                    (others => 'X');
         Last   : Natural;
      begin
         POSIX.IO.NONSTANDARD_Read (File   => Input,
                                    Buffer => Buffer,
                                    Last   => Last);

         Ada.Text_IO.Put_Line (Item => POSIX.To_String (Buffer));
      end;
   end loop;
end Pipe_Demonstration;

