[collectd] [PATCH] email plugin: Do not allocate memory for the return value in read_line ().

Sebastian Harl sh<span style="display: none;">.trailing-username</span>(a)<span style="display: none;">leading-domain.</span>tokkee.org
Fri Dec 8 15:13:26 CET 2006


The read_line () function now uses the provided buffer to save the return
value to. In case no complete line could be read, read_line () is called
recursively until '\n' has been found or end-of-file has been reached.

Signed-off-by: Sebastian Harl <sh<span style="display: none;">.trailing-username</span>(a)<span style="display: none;">leading-domain.</span>tokkee.org>
---
 src/email.c |   47 ++++++++++++++++++-----------------------------
 1 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/src/email.c b/src/email.c
index 401ac92..377a6b1 100644
--- a/src/email.c
+++ b/src/email.c
@@ -115,7 +115,8 @@ typedef struct conn {
 
 	/* buffer to read data to */
 	char *buffer;
-	int  idx; /* current position in buffer */
+	int  idx; /* current write position in buffer */
+	int  length; /* length of the current line, i.e. index of '\0' */
 
 	struct conn *next;
 } conn_t;
@@ -322,8 +323,7 @@ char read_char (conn_t *src)
 /* Read a single line (terminated by '\n') from the the socket.
  *
  * The return value is zero terminated and does not contain any newline
- * characters. In case that no complete line is available (non-blocking mode
- * should be enabled) an empty string is returned.
+ * characters.
  *
  * If an error occurs or end-of-file is reached return NULL.
  *
@@ -333,10 +333,16 @@ char read_char (conn_t *src)
  * acceptable in this case ;-) */
 char *read_line (conn_t *src)
 {
-	int  i = 0;
-	char *ret;
+	int i = 0;
+
+	assert ((BUFSIZE >= src->idx) && (src->idx >= 0));
+	assert ((src->idx > src->length) || (src->length == 0));
 
-	assert (BUFSIZE > src->idx);
+	if (src->length > 0) { /* remove old line */
+		src->idx -= (src->length + 1);
+		memmove (src->buffer, src->buffer + src->length + 1, src->idx);
+		src->length = 0;
+	}
 
 	for (i = 0; i < src->idx; ++i) {
 		if ('\n' == src->buffer[i])
@@ -381,9 +387,7 @@ char *read_line (conn_t *src)
 		}
 
 		if (i == src->idx) {
-			ret = (char *)smalloc (1);
-
-			ret[0] = '\0';
+			src->length = 0;
 
 			if (BUFSIZE == src->idx) { /* no space left in buffer */
 				while ('\n' != read_char (src))
@@ -391,21 +395,14 @@ char *read_line (conn_t *src)
 
 				src->idx = 0;
 			}
-			return ret;
+			return read_line (src);
 		}
 	}
 
-	ret = (char *)smalloc (i + 1);
-	memcpy (ret, src->buffer, i + 1);
-	ret[i] = '\0';
-
-	src->idx -= (i + 1);
+	src->buffer[i] = '\0';
+	src->length    = i;
 
-	if (0 == src->idx)
-		src->buffer[0] = '\0';
-	else
-		memmove (src->buffer, src->buffer + i + 1, src->idx);
-	return ret;
+	return src->buffer;
 } /* char *read_line (conn_t *) */
 
 static void *collect (void *arg)
@@ -438,6 +435,7 @@ static void *collect (void *arg)
 
 		connection->buffer = buffer;
 		connection->idx    = 0;
+		connection->length = 0;
 
 		{ /* put the socket in non-blocking mode */
 			int flags = 0;
@@ -463,14 +461,8 @@ static void *collect (void *arg)
 				break;
 			}
 
-			if ('\0' == line[0]) {
-				free (line);
-				continue;
-			}
-
 			if (':' != line[1]) {
 				syslog (LOG_ERR, "email: syntax error in line '%s'", line);
-				free (line);
 				continue;
 			}
 
@@ -482,7 +474,6 @@ static void *collect (void *arg)
 
 				if (NULL == tmp) {
 					syslog (LOG_ERR, "email: syntax error in line '%s'", line);
-					free (line);
 					continue;
 				}
 
@@ -516,8 +507,6 @@ static void *collect (void *arg)
 			else {
 				syslog (LOG_ERR, "email: unknown type '%c'", line[0]);
 			}
-
-			free (line);
 		} /* while (loop) */
 
 		close (connection->socket);
-- 
1.4.3.2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mailman.verplant.org/pipermail/collectd/attachments/20061208/b1bfef16/attachment.pgp


More information about the collectd mailing list