Есть ли способ проверить, удастся ли pclose ()?

В моем приложении C ++ я вижу pclose (), который зависает, потому что процесс канала завис и никогда не завершается. Можно ли в любом случае сделать что-то вроде select (), чтобы проверить, вернется ли pclose (), потому что дочерний процесс завершен? Я бы предпочел не делать fork () вместо popen (), если это возможно. Если fork () является единственным решением, есть ли примеры использования fork () для замены сценария popen () / pclose ()?

3

Решение

Вероятно, самый простой способ, особенно если у вас есть только один дочерний процесс, это поймать SIGCHLD и установите флаг, что процесс завершен и pclose() можно назвать.

Вот простой пример:

sillyprog.c:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
printf("This is some data from the child.\n");
fflush(stdout);
sleep(5);
return 0;
}

pc.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>

volatile sig_atomic_t child_done = 0;

void handler(int signum)
{
if ( signum == SIGCHLD ) {
child_done = 1;
}
}

int main(void)
{
/*  Set signal handler  */

struct sigaction sa;
sa.sa_handler = handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if ( sigaction(SIGCHLD, &sa, NULL) == -1 ) {
perror("couldn't set signal handler");
return EXIT_FAILURE;
}

/*  Open pipe  */

FILE * fp = popen("./sillyprog", "r");
if ( !fp ) {
fprintf(stderr, "Couldn't open pipe\n");
return EXIT_FAILURE;
}

/*  Get a line from pipe  */

char buffer[100];
if ( !fgets(buffer, 100, fp) ) {
fprintf(stderr, "Error calling fgets()\n");
return EXIT_FAILURE;
}

const size_t len = strlen(buffer);
if ( len && buffer[len - 1] == '\n' ) {
buffer[len - 1] = 0;
}
printf("Got '%s' from pipe.\n", buffer);

/*  Wait for child to finish  */

while ( !child_done ) {
printf("Child not ready, waiting...\n");
sleep(1);
}

/*  Close pipe  */

if ( pclose(fp) == -1 ) {
fprintf(stderr, "Error calling pclose()\n");
return EXIT_FAILURE;
}
else {
printf("pclose() successfully called.\n");
}

return 0;
}

какие выводы:

paul@horus:~/src/sandbox$ ./pc
Got 'This is some data from the child.' from pipe.
Child not ready, waiting...
Child not ready, waiting...
Child not ready, waiting...
Child not ready, waiting...
Child not ready, waiting...
pclose() successfully called.
paul@horus:~/src/sandbox$
1

Другие решения


По вопросам рекламы [email protected]