[asterisk-commits] russell: branch 1.4 r82245 - /branches/1.4/res/res_agi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 11 10:26:52 CDT 2007


Author: russell
Date: Tue Sep 11 10:26:51 2007
New Revision: 82245

URL: http://svn.digium.com/view/asterisk?view=rev&rev=82245
Log:
(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.

Modified:
    branches/1.4/res/res_agi.c

Modified: branches/1.4/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_agi.c?view=diff&rev=82245&r1=82244&r2=82245
==============================================================================
--- branches/1.4/res/res_agi.c (original)
+++ branches/1.4/res/res_agi.c Tue Sep 11 10:26:51 2007
@@ -67,6 +67,8 @@
 
 #define MAX_ARGS 128
 #define MAX_COMMANDS 128
+#define AGI_NANDFS_RETRY 3
+#define AGI_BUF_LEN 2048
 
 /* Recycle some stuff from the CLI interface */
 #define fdprintf agi_debug_cli
@@ -1823,7 +1825,6 @@
 	}
 	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)
 {
 	struct ast_channel *c;
@@ -1831,11 +1832,11 @@
 	int ms;
 	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");
@@ -1850,7 +1851,7 @@
 		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) {
@@ -1866,9 +1867,25 @@
 				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 = -1;
@@ -1880,6 +1897,7 @@
 				pid = -1;
 				break;
 			}
+
 			/* get rid of trailing newline, if any */
 			if (*buf && buf[strlen(buf) - 1] == '\n')
 				buf[strlen(buf) - 1] = 0;
@@ -1993,7 +2011,7 @@
 	enum agi_result res;
 	struct ast_module_user *u;
 	char *argv[MAX_ARGS];
-	char buf[2048]="";
+	char buf[AGI_BUF_LEN] = "";
 	char *tmp = (char *)buf;
 	int argc = 0;
 	int fds[2];




More information about the asterisk-commits mailing list