eddy ed
eddy ed

Reputation: 967

C pipe() returns error after a certain number of calls

I wrote this function to communicate with an external program. Such program takes input from stdin and prints its output on stdout. In order to make my code communicate with this program I redirect the stdin and stdout to buffers using pipes.

int query_oracle(mpz * c,int *t, mpz * m) {
  int out_pipe[2];
  int in_pipe[2];
  int saved_stdout;
  int saved_stdin;

  // REDIRECT STDIN
  saved_stdin = dup(STDIN_FILENO);      /* save stdin for later */
  pipe(in_pipe);            /* make a pipe */
  close(STDIN_FILENO);
  dup2(in_pipe[0], STDIN_FILENO);   /* redirect pipe to stdin */
  //write(in_pipe[1], in_buf, strlen(in_buf));

  // REDIRECT STDOUT
  saved_stdout = dup(STDOUT_FILENO);  /* save stdout for display later */
  if( pipe(out_pipe) != 0 ) {          /* make a pipe */
  exit(1);
  }
  dup2(out_pipe[1], STDOUT_FILENO);   /* redirect stdout to the pipe */
  close(out_pipe[1]);

  /* Some reads and writes on the pipes occur here 
   * so that the program can communicate with an 
   * external program*/

  dup2(saved_stdout, STDOUT_FILENO);    /* reconnect stdout */
  dup2(saved_stdin, STDIN_FILENO);  /* reconnect stdin */

  return 0;
}

the problem is that the 204th time I invoke this function, pipe() returns me an error (-1)! Any idea why is that, or how can I avoid it? thanks a lot

further details: This is on Linux. The result of uname -a is:

 Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

Upvotes: 1

Views: 557

Answers (2)

eddy ed
eddy ed

Reputation: 967

As many of you suggested, the problem was I neglected to close file descriptors before returning from the function, so I soon ran out of available ones.

Here it follows the revised (working) version of the code

int query_oracle(mpz * c,int *t, mpz * m) {
  int out_pipe[2];
  int in_pipe[2];
  int saved_stdout;
  int saved_stdin;

  // REDIRECT STDIN
  saved_stdin = dup(STDIN_FILENO);      /* save stdin for later */
  pipe(in_pipe);            /* make a pipe */
  close(STDIN_FILENO);
  dup2(in_pipe[0], STDIN_FILENO);   /* redirect pipe to stdin */
  //write(in_pipe[1], in_buf, strlen(in_buf));

  // REDIRECT STDOUT
  saved_stdout = dup(STDOUT_FILENO);  /* save stdout for display later */
  if( pipe(out_pipe) != 0 ) {          /* make a pipe */
  exit(1);
  }
  dup2(out_pipe[1], STDOUT_FILENO);   /* redirect stdout to the pipe */
  close(out_pipe[1]);

  /* Some reads and writes on the pipes occur here 
   * so that the program can communicate with an 
   * external program*/

  dup2(saved_stdout, STDOUT_FILENO);    /* reconnect stdout */
  dup2(saved_stdin, STDIN_FILENO);  /* reconnect stdin */

  /* close all open file descriptors */
  close(in_pipe[1]);
  close(in_pipe[0]);
  close(out_pipe[1]);
  close(out_pipe[0]);
  close(saved_stdin);
  close(saved_stdout);

  return 0;
}

Upvotes: 0

Steve Baker
Steve Baker

Reputation: 4373

You're perhaps running our of file descriptors. It appears you may not be closing in_pipe[1] and out_pipe[0] in the program after you've forked the remote program, or ever for that matter.

Upvotes: 6

Related Questions