[Asterisk-Dev] waitpid in app_agi.c

Mark Spencer markster at digium.com
Tue Jan 6 06:39:05 MST 2004


Actually we do have a child handler which is supposed to do the wait.  Are
we not receiving SIGCHLD when it dies?

Mark

On Tue, 6 Jan 2004, marco.parisotto at puntocontatto.it wrote:

> Hi all,
> it's easy to see that each time a dial plan calls an AGI script, a zombie
> is created when that AGI script terminates.
>
> ----------------------------
> For example:
>
> s,1,answer
> s,2,AGI(test.agi)
> s,3,hangup
>
> where test.agi is a whatever script
>
> test.agi:
> #!/usr/bin/perl
> exit (0);
> ---------------------------
>
> This behavior is due to the fact that Asterisk does not wait ( or waitpid)
> for its child.
> I fixed this problem in app_agi.c calling fork() twice and letting the init
> function become the parent of the second child (which actually executes
> the AGI script). This is a non-blocking way for waiting for the child process.
>
> --------------------
> My app_agi.c:
>
> (...)
>
>  pid = fork();
>  if (pid < 0) {
>   ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
>   return -1;
>  }
>  if (!pid) {
>   /* first child */
>   pid = fork();
>          if (pid < 0) {
>                  ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
>                  return -1;
>          }
>   if (!pid) {
>    /* second child */
>    /* Redirect stdin and out, provide enhanced audio channel if desired
> */
>    dup2(fromast[0], STDIN_FILENO);
>    dup2(toast[1], STDOUT_FILENO);
>    if (efd) {
>     dup2(audio[0], STDERR_FILENO + 1);
>    } else {
>     close(STDERR_FILENO + 1);
>    }
>    /* Close everything but stdin/out/error */
>    for (x=STDERR_FILENO + 2;x<1024;x++)
>     close(x);
>    /* Execute script */
>    execl(script, script, args, (char *)NULL);
>    /* Can't use ast_log since FD's are closed */
>    fprintf(stderr, "Failed to execute '%s': %s\n", script, strerror(errno));
>    exit(1);
>   } else
>    exit(0); /* exiting parent of second child = first child */
>
>  }
>  if (waitpid(pid, NULL, 0) != pid)
>    fprintf(stderr, "Failed to wait for first child PID '%d'", pid);
>  if (option_verbose > 2)
>   ast_verbose(VERBOSE_PREFIX_3 "Launched AGI Script %s\n", script);
>
> (...)
>
> -----------------------
>
> Any comment would be appreciated.
> Thanks
>
> Marco P
>
> _______________________________________________
> Asterisk-Dev mailing list
> Asterisk-Dev at lists.digium.com
> http://lists.digium.com/mailman/listinfo/asterisk-dev
>




More information about the asterisk-dev mailing list