альтернатива popen () - PullRequest
       13

альтернатива popen ()

9 голосов
/ 19 июля 2011

Мой вопрос является расширением этого: popen создает дополнительный процесс sh

Мотивы:

1) В моей программе необходимо создать дочернего элемента, который выполняет tail в файле.Мне нужно обрабатывать вывод построчно.Вот почему я использую popen, потому что он возвращает FILE *.Я могу легко получить одну строку, сделать то, что мне нужно, и распечатать ее.

Одна проблема с popen заключается в том, что вы не получаете pid child (команда tail в моем случае).

2) Моя программа не должна завершаться, пока не завершится ее дочерний процесс.Поэтому мне нужно сделать wait;но без pid я не могу этого сделать.

Как мне достичь обеих целей?

Возможное (kludge) решение: выполните execvp ("tail -f file> tmpfile") и продолжайте чтение этого tmpfile.Я не уверен, насколько хорошо это решение.

Ответы [ 4 ]

16 голосов
/ 19 июля 2011

Почему вы не используете метод pipe / fork / exec?

pid_t pid = 0;
int pipefd[2];
FILE* output;
char line[256];
int status;

pipe(pipefd); //create a pipe
pid = fork(); //span a child process
if (pid == 0)
{
// Child. Let's redirect its standard output to our pipe and replace process with tail
 close(pipefd[0]);
 dup2(pipefd[1], STDOUT_FILENO);
 dup2(pipefd[1], STDERR_FILENO);
 execl("/usr/bin/tail", "/usr/bin/tail", "-f", "path/to/your/file", (char*) NULL);
}

//Only parent gets here. Listen to what the tail says
close(pipefd[1]);
output = fdopen(pipefd[0], "r");

while(fgets(line, sizeof(line), output)) //listen to what tail writes to its standard output
{
//if you need to kill the tail application, just kill it:
  if(something_goes_wrong)
    kill(pid, SIGKILL);
}

//or wait for the child process to terminate
waitpid(pid, &status, 0);
1 голос
/ 19 июля 2011
  1. Вы можете использовать pipe, функцию семейства exec* и fdopen. Это нестандартно, но так же popen.
  2. Вам не нужно wait. Просто прочитайте трубку до EOF.
  3. execvp("tail -f file > tmpfile") не будет работать, перенаправление является функцией оболочки, и вы не запускаете оболочку здесь. Даже если бы это сработало, это было бы ужасным решением. Предположим, вы прочитали файл до конца, но дочерний процесс еще не завершен. Что ты делаешь?
0 голосов
/ 19 июля 2011

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

0 голосов
/ 19 июля 2011

Вы можете использовать wait, так как он не хочет ждать PID, а просто ожидает завершения любого дочернего процесса.Если вы создали другие дочерние процессы, вы можете отслеживать их, а если wait возвращает неизвестный PID, вы можете предположить, что это ваш popen процесс.

...