diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-09-11 15:28:46 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-09-11 15:28:46 +0000 |
commit | 886ace82e60cea4b6a1269f9740cd2affd710aac (patch) | |
tree | 4dbbea29e66231689e559e630692823fbf866e4b /res | |
parent | c52a118fff19a115756b2f62b222911c2ff22ef4 (diff) |
Merged revisions 82245 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r82245 | russell | 2007-09-11 10:26:51 -0500 (Tue, 11 Sep 2007) | 9 lines
(closes issue #10553)
Reported by: juggie
Patches:
res_agi_fgets-2.patch uploaded by juggie (license 24)
Tested by: juggie
When using fastagi, fgets() can return before a full line is read. Add explicit
handling for the case where it gets interrupted.
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@82246 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'res')
-rw-r--r-- | res/res_agi.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/res/res_agi.c b/res/res_agi.c index 181fba1bd..d7d9bf52c 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -67,6 +67,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/agi.h" #define MAX_ARGS 128 +#define AGI_NANDFS_RETRY 3 +#define AGI_BUF_LEN 2048 static char *app = "AGI"; @@ -1856,18 +1858,17 @@ static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int } return 0; } -#define RETRY 3 static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead, int argc, char *argv[]) { struct ast_channel *c; int outfd, ms, needhup = 0; enum agi_result returnstatus = AGI_RESULT_SUCCESS; struct ast_frame *f; - char buf[2048]; + char buf[AGI_BUF_LEN]; 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) */ - int retry = RETRY; + int retry = AGI_NANDFS_RETRY; if (!(readf = fdopen(agi->ctrl, "r"))) { ast_log(LOG_WARNING, "Unable to fdopen file descriptor\n"); @@ -1887,7 +1888,7 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi ms = -1; c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms); if (c) { - retry = RETRY; + retry = AGI_NANDFS_RETRY; /* Idle the channel until we get a command */ f = ast_read(c); if (!f) { @@ -1904,9 +1905,25 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi ast_frfree(f); } } else if (outfd > -1) { - retry = RETRY; + 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)) { + fgets(buf + buflen, len, readf); + if (feof(readf)) + break; + if (ferror(readf) && ((errno != EINTR) && (errno != EAGAIN))) + 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 != AST_PBX_KEEPALIVE) returnstatus = -1; @@ -1917,6 +1934,7 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi pid = -1; break; } + /* get rid of trailing newline, if any */ if (*buf && buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; @@ -2067,7 +2085,7 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int { enum agi_result res; struct ast_module_user *u; - char buf[2048] = "", *tmp = buf; + char buf[AGI_BUF_LEN] = "", *tmp = buf; int fds[2], efd = -1, pid; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(arg)[MAX_ARGS]; |