tags:

views:

105

answers:

1

How do I run another program from within my C program, I need to be able to write data into STDIN(while execution of program i have to provide input through stdin more than once) of the programed launched (and read line by line from it's STDOUT)

I need the solution to work under Linux.

while going through net i found below code:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

void error(char *s);
char *data = "Some input data\n";

main()
{
  int in[2], out[2], n, pid;
  char buf[255];

  /* In a pipe, xx[0] is for reading, xx[1] is for writing */
  if (pipe(in) < 0) error("pipe in");
  if (pipe(out) < 0) error("pipe out");

  if ((pid=fork()) == 0) {
    /* This is the child process */

    /* Close stdin, stdout, stderr */
    close(0);
    close(1);
    close(2);
    /* make our pipes, our new stdin,stdout and stderr */
    dup2(in[0],0);
    dup2(out[1],1);
    dup2(out[1],2);

    /* Close the other ends of the pipes that the parent will use, because if
     * we leave these open in the child, the child/parent will not get an EOF
     * when the parent/child closes their end of the pipe.
     */
    close(in[1]);
    close(out[0]);

    /* Over-write the child process with the hexdump binary */
    execl("/usr/bin/hexdump", "hexdump", "-C", (char *)NULL);
    error("Could not exec hexdump");
  }

  printf("Spawned 'hexdump -C' as a child process at pid %d\n", pid);

  /* This is the parent process */
  /* Close the pipe ends that the child uses to read from / write to so
   * the when we close the others, an EOF will be transmitted properly.
   */
  close(in[0]);
  close(out[1]);

  printf("<- %s", data);
  /* Write some data to the childs input */
  write(in[1], data, strlen(data));

  /* Because of the small amount of data, the child may block unless we
   * close it's input stream. This sends an EOF to the child on it's
   * stdin.
   */
  close(in[1]);

  /* Read back any output */
  n = read(out[0], buf, 250);
  buf[n] = 0;
  printf("-> %s",buf);
  exit(0);
}

void error(char *s)
{
  perror(s);
  exit(1);
}

but this code is working fine if my C program(which needs to be executed usng exec) is reading input only once from stdin and returns output once .but if my Cprogram(which needs to be executed usng exec) is taking input more than once(dont know exactly how many times it will read input from stdin) and display output put mork than once(while execution display output line by line on stdout) then this code is crashing. can any body suggest how to solve this problem? Actually my C program(which needs to be executed usng exec) is displaying some output line by line and depending upon output i have to provide input on stdin and number of this read/write is not constant.

Please help me resolve this issue.

+1  A: 

You can use the select api to get notified when you can read/write a file descriptor. So you would basically put your read and write calls into a loop, and run select to find out when the external program consumed some bytes or wrote something to stdout.

Rudi
Hi Rudi, Can you please provide some sample code for this? Should i use posix thread coditions etc ? if yes please provide some sample code related to this issue .i am really unable to solve this problem
james
@james: your problem isn't thread conditions or anything, your problem is that there's no loop where you do the write->read->write->read->... sequence.Plus you are closing your child's stdin which means your communication channel to your child has vanished.Are you sure your other program can read beyond EOF?
hroptatyr