Index: head/sys/kern/subr_sbuf.c =================================================================== --- head/sys/kern/subr_sbuf.c +++ head/sys/kern/subr_sbuf.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #else /* _KERNEL */ #include #include +#include #include #include #include @@ -383,34 +385,51 @@ } /* - * 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 @@ 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 @@ 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); }