Question

I have two C++ programs: Program1 and Program2. What I want to do is have Program1 run its algorithm to compute whatever it needs and then pipe all that calculated information into Program2 to let it run its algorithm using the output of Program1.

It would be nice if I could just pipe the information and close Program1 without having to wait for Program2 to finish first. It would be something like the subprocess.call() in python.

Was it helpful?

Solution 2

You'll want to do something along the lines of this:

#include <unistd.h>

int main () {
  // Do stuff for program1
  int pipefds[2];
  if (pipe (pipefds))
    throw 1;
  // Use ``write'' to send binary data to pipefds[0]
  dup2 (pipefds[1], 0);
  execl (/* Put the program2 arguments you want here. */);
  return 1;
}

With this, all you need is to have program2 read all the necessary data out of stdin and you're done.

OTHER TIPS

To emulate subprocess.check_call("Program1 | Program2", shell=True) Python call, you could use system(3) in C:

/** $ gcc simple-pipe-system.c && ./a.out */
#include <stdlib.h>

int main(void) {
  return system("Program1 | Program2");
}

Here's how to emulate Program1 | Program2 pipeline using low level pipe(2)/fork(2)/execlp(2) in C for comparison:

/** $ gcc simple-pipe.c && ./a.out */
#include <sys/types.h> /* pid_t */
#include <unistd.h>

int main(void) {
  int fd[2]; /* pipe ends */
  pid_t pid = -1;

  if (pipe(fd) == -1)
    Report_error_and_exit("pipe");

  if ((pid = fork()) == -1)
    Report_error_and_exit("fork");
  else if (pid == 0)  {
    /* child: run Program1, redirecting stdout to the pipe */
    is_child = 1;
    Close(fd[0]); /* close unused read end of the pipe */

    /* redirect stdout */
    Redirect(fd[1], STDOUT_FILENO);

    /* run Program1 with redirected stdout */
    execlp("Program1", "Program1", NULL);
    Report_error_and_exit("execlp");
  }

  /* parent: run Program2, redirecting stdin to the pipe */
  Close(fd[1]); /* close unused write end of the pipe */

  /* redirect stdin */
  Redirect(fd[0], STDIN_FILENO);
  /* run Program2 with redirected stdin */
  execlp("Program2", "Program2", NULL);
  Report_error_and_exit("execlp");
}

where Report_error_and_exit, Close, Redirect could be defined as:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#define Close(FD) do {                                          \
    const int Close_fd = (FD);                                  \
    if (close(Close_fd) == -1)                                  \
      fprintf(stderr, "%s:%d: close(" #FD ") %d: %s\n",         \
          __FILE__, __LINE__, Close_fd, strerror(errno));       \
  }while(0)

#define Report_error_and_exit(msg) do {                       \
    fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__,    \
        (msg), strerror(errno));                              \
    (is_child ? _exit : exit)(EXIT_FAILURE);                  \
  } while(0)
static int is_child = 0;

#define Redirect(FROM, TO) do {            \
    const int from = (FROM);               \
    const int to = (TO);                   \
    if (from != to) {                      \
      if (dup2(from, to) == -1)            \
        Report_error_and_exit("dup2");     \
      else                                 \
        Close(from);                       \
    }                                      \
  } while(0)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top