[PATCH] faster and safer fpm config reading

From: Date: Wed, 08 May 2013 00:26:45 +0000
Subject: [PATCH] faster and safer fpm config reading
Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
commit edae18ccf5c51ae0bcc0e9655ead7540fd42dd9f
Author: Martin Pelikan <[email protected]>
Date:   Wed May 8 02:06:09 2013 +0200

    Faster and safer parsing of fpm configuration.
    
    The current fpm config parser did a read(2) syscall per character,
    which obfuscated debugging strace/ktrace output somewhat.  This also
    makes the 1024 characters per line limit more explicit, so the users
    will know what were they hitting.
    
    It might improve performance during php-fpm load (.03 vs .00 seconds
    on my laptop) but primarily serves to help observing fpm system call
    traces during deployment (in chroot for example).
    
    Signed-off-by: Martin Pelikan <[email protected]>

diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c
index 0a8a0e3..e004934 100644
--- a/sapi/fpm/fpm/fpm_conf.c
+++ b/sapi/fpm/fpm/fpm_conf.c
@@ -1447,11 +1447,11 @@ static void fpm_conf_ini_parser(zval *arg1, zval *arg2, zval *arg3, int
callback
 
 int fpm_conf_load_ini_file(char *filename TSRMLS_DC) /* {{{ */
 {
+	const int bufsize = 1024;
 	int error = 0;
-	char buf[1024+1];
-	int fd, n;
+	char buf[bufsize], *newl;
+	int fd, pos = 0;
 	int nb_read = 1;
-	char c = '*';
 
 	int ret = 1;
 
@@ -1473,36 +1473,48 @@ int fpm_conf_load_ini_file(char *filename TSRMLS_DC) /* {{{ */
 	}
 
 	ini_lineno = 0;
+	memset(buf, 0, sizeof buf);
 	while (nb_read > 0) {
 		int tmp;
-		memset(buf, 0, sizeof(char) * (1024 + 1));
-		for (n = 0; n < 1024 && (nb_read = read(fd, &c, sizeof(char))) == sizeof(char)
&& c != '\n'; n++) {
-			buf[n] = c;
-		}
-		buf[n++] = '\n';
-		ini_lineno++;
-		ini_filename = filename;
-		tmp = zend_parse_ini_string(buf, 1, ZEND_INI_SCANNER_NORMAL,
(zend_ini_parser_cb_t)fpm_conf_ini_parser, &error TSRMLS_CC);
-		ini_filename = filename;
-		if (error || tmp == FAILURE) {
-			if (ini_include) free(ini_include);
-			ini_recursion--;
-			close(fd);
-			return -1;
-		}
-		if (ini_include) {
-			char *tmp = ini_include;
-			ini_include = NULL;
-			fpm_evaluate_full_path(&tmp, NULL, NULL, 0);
-			fpm_conf_ini_parser_include(tmp, &error TSRMLS_CC);
-			if (error) {
-				free(tmp);
+
+		nb_read = read(fd, buf + pos, sizeof buf - pos);
+		pos = 0;
+		
+		while ((newl = strchr(buf + pos, '\n')) != NULL) {
+			newl[0] = '\0';
+			ini_lineno++;
+			ini_filename = filename;
+			tmp = zend_parse_ini_string(buf + pos, 1, ZEND_INI_SCANNER_NORMAL,
(zend_ini_parser_cb_t)fpm_conf_ini_parser, &error TSRMLS_CC);
+			ini_filename = filename;
+			if (error || tmp == FAILURE) {
+				if (ini_include) free(ini_include);
 				ini_recursion--;
 				close(fd);
 				return -1;
 			}
-			free(tmp);
+			if (ini_include) {
+				char *tmp = ini_include;
+				ini_include = NULL;
+				fpm_evaluate_full_path(&tmp, NULL, NULL, 0);
+				fpm_conf_ini_parser_include(tmp, &error TSRMLS_CC);
+				if (error) {
+					free(tmp);
+					ini_recursion--;
+					close(fd);
+					return -1;
+				}
+				free(tmp);
+			}
+
+			pos = newl - buf + 1;
+		}
+		if (nb_read > 0 && pos == 0) {
+			zlog(ZLOG_ERROR, "line %u too long", ini_lineno + 1);
+			close(fd);
+			return -1;
 		}
+		memmove(buf, buf + pos, sizeof buf - pos);
+		pos = sizeof buf - pos;
 	}
 
 	ini_recursion--;



Thread (1 message)

  • Martin Pelikan
« previous php.internals (#67368) next »