C pipe () возвращает ошибку после определенного количества вызовов - PullRequest
1 голос
/ 27 марта 2012

Я написал эту функцию для связи с внешней программой.Такая программа принимает входные данные из стандартного ввода и выводит их вывод на стандартный вывод.Чтобы заставить мой код взаимодействовать с этой программой, я перенаправляю stdin и stdout в буферы, используя каналы.

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;
}

проблема в том, что в 204-й раз, когда я вызываю эту функцию, pipe () возвращает мне ошибку (-1)!Любая идея, почему это, или как я могу избежать этого?Большое спасибо

подробнее: Это на Linux.Результат uname -a:

 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

Ответы [ 2 ]

6 голосов
/ 27 марта 2012

Возможно, вы используете наши файловые дескрипторы.Похоже, что вы не можете закрывать in_pipe [1] и out_pipe [0] в программе после того, как вы разветвили удаленную программу, или когда-либо в этом отношении.

0 голосов
/ 28 марта 2012

Как многие из вас предположили, проблема заключалась в том, что я пренебрег закрытием файловых дескрипторов перед возвратом из функции, поэтому вскоре у меня закончились доступные.

Здесь следует пересмотренная (рабочая) версиякод

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;
}
...