svn commit: r288223 - head/sys/kern

Conrad E. Meyer cem at FreeBSD.org
Fri Sep 25 18:37:16 UTC 2015


Author: cem
Date: Fri Sep 25 18:37:14 2015
New Revision: 288223
URL: https://svnweb.freebsd.org/changeset/base/288223

Log:
  sbuf: Process more than one char at a time
  
  Revamp sbuf_put_byte() to sbuf_put_bytes() in the obvious fashion and
  fixup callers.
  
  Add a thin shim around sbuf_put_bytes() with the old ABI to avoid ugly
  changes to some callers.
  
  Reviewed by:	jhb, markj
  Obtained from:	Dan Sledz
  Sponsored by:	EMC / Isilon Storage Division
  Differential Revision:	https://reviews.freebsd.org/D3717

Modified:
  head/sys/kern/subr_sbuf.c

Modified: head/sys/kern/subr_sbuf.c
==============================================================================
--- head/sys/kern/subr_sbuf.c	Fri Sep 25 18:21:48 2015	(r288222)
+++ head/sys/kern/subr_sbuf.c	Fri Sep 25 18:37:14 2015	(r288223)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/ctype.h>
 #include <sys/errno.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/malloc.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
@@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #else /* _KERNEL */
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -383,34 +385,51 @@ sbuf_drain(struct sbuf *s)
 }
 
 /*
- * Append a byte to an sbuf.  This is the core function for appending
+ * Append bytes to an sbuf.  This is the core function for appending
  * to an sbuf and is the main place that deals with extending the
  * buffer and marking overflow.
  */
 static void
-sbuf_put_byte(struct sbuf *s, int c)
+sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len)
 {
+	size_t n;
 
 	assert_sbuf_integrity(s);
 	assert_sbuf_state(s, 0);
 
 	if (s->s_error != 0)
 		return;
-	if (SBUF_FREESPACE(s) <= 0) {
-		/*
-		 * If there is a drain, use it, otherwise extend the
-		 * buffer.
-		 */
-		if (s->s_drain_func != NULL)
-			(void)sbuf_drain(s);
-		else if (sbuf_extend(s, 1) < 0)
-			s->s_error = ENOMEM;
-		if (s->s_error != 0)
-			return;
+	while (len > 0) {
+		if (SBUF_FREESPACE(s) <= 0) {
+			/*
+			 * If there is a drain, use it, otherwise extend the
+			 * buffer.
+			 */
+			if (s->s_drain_func != NULL)
+				(void)sbuf_drain(s);
+			else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len)
+			    < 0)
+				s->s_error = ENOMEM;
+			if (s->s_error != 0)
+				return;
+		}
+		n = SBUF_FREESPACE(s);
+		if (len < n)
+			n = len;
+		memcpy(&s->s_buf[s->s_len], buf, n);
+		s->s_len += n;
+		if (SBUF_ISSECTION(s))
+			s->s_sect_len += n;
+		len -= n;
+		buf += n;
 	}
-	s->s_buf[s->s_len++] = c;
-	if (SBUF_ISSECTION(s))
-		s->s_sect_len++;
+}
+
+static void
+sbuf_put_byte(struct sbuf *s, char c)
+{
+
+	sbuf_put_bytes(s, &c, 1);
 }
 
 /*
@@ -419,19 +438,10 @@ sbuf_put_byte(struct sbuf *s, int c)
 int
 sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
 {
-	const char *str = buf;
-	const char *end = str + len;
-
-	assert_sbuf_integrity(s);
-	assert_sbuf_state(s, 0);
 
+	sbuf_put_bytes(s, buf, len);
 	if (s->s_error != 0)
 		return (-1);
-	for (; str < end; str++) {
-		sbuf_put_byte(s, *str);
-		if (s->s_error != 0)
-			return (-1);
-	}
 	return (0);
 }
 
@@ -485,18 +495,12 @@ sbuf_bcpy(struct sbuf *s, const void *bu
 int
 sbuf_cat(struct sbuf *s, const char *str)
 {
+	size_t n;
 
-	assert_sbuf_integrity(s);
-	assert_sbuf_state(s, 0);
-
+	n = strlen(str);
+	sbuf_put_bytes(s, str, n);
 	if (s->s_error != 0)
 		return (-1);
-
-	while (*str != '\0') {
-		sbuf_put_byte(s, *str++);
-		if (s->s_error != 0)
-			return (-1);
-	}
 	return (0);
 }
 


More information about the svn-src-head mailing list