Index: include/asterisk/agi.h =================================================================== --- include/asterisk/agi.h (revision 82631) +++ include/asterisk/agi.h (working copy) @@ -31,6 +31,7 @@ int fd; /* FD for general output */ int audio; /* FD for audio output */ int ctrl; /* FD for input control */ + int fast; /* flag for fast agi or not */ } AGI; typedef struct agi_command { Index: res/res_agi.c =================================================================== --- res/res_agi.c (revision 82631) +++ res/res_agi.c (working copy) @@ -113,6 +113,7 @@ enum agi_result { AGI_RESULT_SUCCESS, + AGI_RESULT_SUCCESS_FAST, AGI_RESULT_FAILURE, AGI_RESULT_HANGUP }; @@ -1833,6 +1834,7 @@ enum agi_result returnstatus = AGI_RESULT_SUCCESS; struct ast_frame *f; char buf[AGI_BUF_LEN]; + char *res = NULL; FILE *readf; /* how many times we'll retry if ast_waitfor_nandfs will return without either channel or file descriptor in case select is interrupted by a system call (EINTR) */ @@ -1867,10 +1869,27 @@ ast_frfree(f); } } else if (outfd > -1) { + size_t len = sizeof(buf); + size_t buflen = 0; + retry = AGI_NANDFS_RETRY; buf[0] = '\0'; - if (!fgets(buf, sizeof(buf), readf)) { + while (buflen < (len - 1)) { + res = fgets(buf + buflen, len, readf); + if (feof(readf)) + break; + if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN))) + break; + if (res != NULL && !agi->fast) + break; + buflen = strlen(buf); + len -= buflen; + if (agidebug) + ast_verbose( "AGI Rx << temp buffer %s - errno %s\n", buf, strerror(errno)); + } + + if (!buf[0]) { /* Program terminated */ if (returnstatus) returnstatus = -1; @@ -2027,14 +2046,18 @@ } #endif res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid); - if (res == AGI_RESULT_SUCCESS) { + if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) { int status = 0; agi.fd = fds[1]; agi.ctrl = fds[0]; agi.audio = efd; + if (res == AGI_RESULT_SUCCESS_FAST) + agi.fast = 1; + else + agi.fast = 0; res = run_agi(chan, argv[0], &agi, pid, &status, dead); /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */ - if (res == AGI_RESULT_SUCCESS && status) + if ((res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) && status) res = AGI_RESULT_FAILURE; if (fds[1] != fds[0]) close(fds[1]); @@ -2046,6 +2069,7 @@ switch (res) { case AGI_RESULT_SUCCESS: + case AGI_RESULT_SUCCESS_FAST: pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS"); break; case AGI_RESULT_FAILURE: