[Asterisk-Dev] waitpid in app_agi.c
marco.parisotto at virgilio.it
marco.parisotto at virgilio.it
Mon Jan 5 16:00:34 MST 2004
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
More information about the asterisk-dev
mailing list