0

I have the following program

int external_apply(char *type)
{
    int pfds[2];
    if (pipe(pfds) < 0)
        return -1;

    if ((pid = fork()) == -1)
        goto error;

    if (pid == 0) {
        /* child */

        const char *argv[8];
        int i = 0;
        argv[i++] = "/bin/sh";
        argv[i++] = "script_file.sh";
        argv[i++] = "apply";

        close(pfds[0]);
        dup2(pfds[1], 1);
        close(pfds[1]);

        execvp(argv[0], (char **) argv);
        exit(ESRCH);

    } else if (pid < 0)
        goto error;

    /* parent */
    close(pfds[1]);

    int status;
    while (wait(&status) != pid) {
        printf("waiting for child to exit");
    }

    return 0;

error:
    close(pfds[0]);
    return -1;
}

The fork call my script file. The script file contains command that cause a pipe close (sometimes). If the pipe is closed by the scipt the wait will cause a crash of the program.

How to avoid the crash of the program when the pipe is closed by the script?

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
  • What do you mean by "it crashes"? Wait doesn't care for the pipes, it ponly waits for the child status to change. – Devolus Jun 12 '13 at 16:19
  • crash. I mean the program close without displaying any message. event the dmesg does not contain any segmentation fault – MOHAMED Jun 12 '13 at 16:25
  • What is the rest of the code doing? See my updated on my answer. To me it looks ok, so maybe your problem is somewhere else. – Devolus Jun 12 '13 at 16:35

3 Answers3

0

on the error replace return -1 with _exit(-1).

0

You are probably receiving a SIGPIPE signal and not handling, causing an exception instead.

Try

signal(SIGPIPE, SIG_IGN);

and see this question/answers for details (or google SIGPIPE).

Community
  • 1
  • 1
collaborator
  • 612
  • 4
  • 5
0

Your code leaks filedescriptors in error cases. It also closes uninitialized filedescriptors in case of errors.

But the loop you are showing will only be entered when wait returns with a different pid (in case you have more childs running) or it was interrupted (in which case it returns -1). So to me this looks exactly as it should work. When the child is finished, the loop will never be entered. If you think the program crashes, you should show the code calling this function.

Devolus
  • 21,661
  • 13
  • 66
  • 113