[asterisk-commits] russell: trunk r82931 - in /trunk: ./ include/asterisk/agi.h res/res_agi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 18 17:46:06 CDT 2007


Author: russell
Date: Tue Sep 18 17:46:05 2007
New Revision: 82931

URL: http://svn.digium.com/view/asterisk?view=rev&rev=82931
Log:
Merged revisions 82929 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r82929 | russell | 2007-09-18 17:42:27 -0500 (Tue, 18 Sep 2007) | 11 lines

Add a new patch to handle interrupting the fgets() call when using FastAGI.
This version of the patch maintains the original behavior of the code when
not using FastAGI.
(closes issue #10553)
Reported by: juggie
Patches:
      res_agi_fgets-4.patch uploaded by juggie (license 24)
      res_agi_fgets_1.4svn.patch uploaded by juggie (license 24)
	  Slight mods by me
Tested by: juggie, festr

........

Modified:
    trunk/   (props changed)
    trunk/include/asterisk/agi.h
    trunk/res/res_agi.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/include/asterisk/agi.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/agi.h?view=diff&rev=82931&r1=82930&r2=82931
==============================================================================
--- trunk/include/asterisk/agi.h (original)
+++ trunk/include/asterisk/agi.h Tue Sep 18 17:46:05 2007
@@ -31,6 +31,7 @@
 	int fd;		/* FD for general output */
 	int audio;	/* FD for audio output */
 	int ctrl;		/* FD for input control */
+	unsigned int fast:1; /* flag for fast agi or not */
 } AGI;
 
 typedef struct agi_command {

Modified: trunk/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_agi.c?view=diff&rev=82931&r1=82930&r2=82931
==============================================================================
--- trunk/res/res_agi.c (original)
+++ trunk/res/res_agi.c Tue Sep 18 17:46:05 2007
@@ -110,6 +110,7 @@
 
 enum agi_result {
 	AGI_RESULT_SUCCESS,
+	AGI_RESULT_SUCCESS_FAST,
 	AGI_RESULT_FAILURE,
 	AGI_RESULT_NOTFOUND,
 	AGI_RESULT_HANGUP,
@@ -231,7 +232,7 @@
 	fds[0] = s;
 	fds[1] = s;
 	*opid = -1;
-	return AGI_RESULT_SUCCESS;
+	return AGI_RESULT_SUCCESS_FAST;
 }
 
 static enum agi_result launch_script(char *script, char *argv[], int *fds, int *efd, int *opid)
@@ -1869,6 +1870,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) */
@@ -1909,10 +1911,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 != AST_PBX_KEEPALIVE)
 					returnstatus = -1;
@@ -2122,14 +2141,15 @@
 	}
 #endif
 	res = launch_script(args.argv[0], args.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;
+		agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0;
 		res = run_agi(chan, args.argv[0], &agi, pid, &status, dead, args.argc, args.argv);
 		/* 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]);
@@ -2141,6 +2161,7 @@
 
 	switch (res) {
 	case AGI_RESULT_SUCCESS:
+	case AGI_RESULT_SUCCESS_FAST:
 		pbx_builtin_setvar_helper(chan, "AGISTATUS", "SUCCESS");
 		break;
 	case AGI_RESULT_FAILURE:




More information about the asterisk-commits mailing list