On Wed, Mar 08, 2000 at 08:07:23PM +0400, bear wrote:
> Hello Everybody.
> Can you tell me please, how I can create a two sided pipes in C++.
> I want to say can I run a program and get its output to stdout as
> input stream to my program & vice-versa?
> 
> -- 
> Best regards,
>  Areg                          mailto:[EMAIL PROTECTED]

kinda... I don't know how to in C++. but here's a C program
that does set up the pipes correctly. There's some kind of bug in the
reading/writing, but I believe the pipes are setup up correctly.

umm. you could probably also poke around in $CPLUSPLUSAPPLICATION source
code for an example.. KDE comes to mind(It's one of the few Linux things
I know is written in C++, and it probably uses pipes).

also to help you are
man 2 pipe
man 2 dup

you can make an fstream in c++ from a filedescriptor
by declaring

fstream suchandso(filedescriptor);
 
 I think. Haven't been forced to write c++ for 6 months, so I'm pretty rusty
 at it.
------------begin pipetest.c-----------
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>

extern int errno;

int main ( void )
{

  char     buffer[8192];
  int      fd[2];
  ssize_t  test;
  int      childdone=0;
  if (pipe(fd) == -1){
    perror("Couldn't open pipe");
    exit(EXIT_FAILURE);
  }
  switch (fork()){
  case -1:
    perror("Couldn't fork:");
    close(fd[0]);
    close(fd[1]);
    exit(EXIT_FAILURE);
  case 0: /* child */
    close(STDIN_FILENO);
    if (dup(fd[0])==-1){ /*new standard in*/
      perror("[child]:Couldn't dup for stdin:");
      close(fd[0]);
      close(fd[1]);
      exit(EXIT_FAILURE);
    }
    close(STDOUT_FILENO);
    if (dup(fd[1])==-1){ /*new stdout*/
      perror("[child]:Couldn't dup for stdout:");
      close(fd[0]);
      close(fd[1]);
      exit(EXIT_FAILURE);
    }
    if(execl("/usr/bin/w","")==-1){
      perror("[child]:couldn't execl");
      close(fd[0]);
      close(fd[1]);
      exit(EXIT_FAILURE);
    }else{
      close(fd[0]);
      close(fd[1]);
      exit(EXIT_SUCCESS);
    }
    break;
  default: /*parent*/

    close(STDIN_FILENO);
    if (dup(fd[0])==-1){
      perror("[parent]:couldn't dup for stdout:");
      close(fd[0]);
      close(fd[1]);
      exit(EXIT_FAILURE);
    }
    fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
    close(STDOUT_FILENO);
    if (dup(fd[1])==-1){
      perror("[parent]:couldn't dup for stdin:");
      close(fd[0]);
      close(fd[1]);

      exit(EXIT_FAILURE);
    }
    /* okay at this point a doubly ended pipe should be set up
     * your programs stdout is the childs stdin and the childs stdout
     * is your stdin
     * enjoy
     */

     /* the stuff after this doesn't work quite right, 
      * but that's okay... its just an example. doesn't
      * have to be perfect :-)
      */
    while ((test=read(fd[0],buffer,8191))){
      if (test==-1){
          if(errno==EAGAIN){
              if (!childdone)
                   continue;
              test=0;
              break;
          }
        else
          break;
      }
      buffer[test]='\0';
      if(waitpid(0,0,WNOHANG)!=0)
          childdone=1;
      write(STDERR_FILENO,buffer,test);
    }
    if (test)
      perror("read error:");
    close(fd[0]);
    close(fd[1]);
    if (!test)
      exit(EXIT_SUCCESS);
    else
      exit(EXIT_FAILURE);
  }
  return(-1);/*shouldn't be reached*/
}
--------------end pipetest------------------

have fun,

greg
--
dronf!

-
To unsubscribe from this list: send the line "unsubscribe linux-newbie" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.linux-learn.org/faqs

Reply via email to