From owner-svn-src-all@FreeBSD.ORG Mon May 6 20:32:15 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id E074EC9; Mon, 6 May 2013 20:32:15 +0000 (UTC) (envelope-from trociny@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id C39E8249; Mon, 6 May 2013 20:32:15 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r46KWFot054330; Mon, 6 May 2013 20:32:15 GMT (envelope-from trociny@svn.freebsd.org) Received: (from trociny@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r46KWEkl054322; Mon, 6 May 2013 20:32:14 GMT (envelope-from trociny@svn.freebsd.org) Message-Id: <201305062032.r46KWEkl054322@svn.freebsd.org> From: Mikolaj Golub Date: Mon, 6 May 2013 20:32:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r250308 - in stable/9: lib/libsbuf share/man/man9 sys/kern sys/sys X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 May 2013 20:32:16 -0000 Author: trociny Date: Mon May 6 20:32:14 2013 New Revision: 250308 URL: http://svnweb.freebsd.org/changeset/base/250308 Log: MFC r249377, r249378, r249379: r249377: Add sbuf_start_section() and sbuf_end_section() functions, which can be used for automatic section alignment. Discussed with: kib Reviewed by: kib r249378: Add sbuf_start_section and sbuf_end_section to the libsbuf symbol map. r249379: Document sbuf_start_section() and sbuf_end_section() functions. Modified: stable/9/lib/libsbuf/Symbol.map stable/9/lib/libsbuf/Version.def stable/9/share/man/man9/sbuf.9 stable/9/sys/kern/subr_sbuf.c stable/9/sys/sys/sbuf.h Directory Properties: stable/9/lib/libsbuf/ (props changed) stable/9/share/man/man9/ (props changed) stable/9/sys/ (props changed) stable/9/sys/sys/ (props changed) Modified: stable/9/lib/libsbuf/Symbol.map ============================================================================== --- stable/9/lib/libsbuf/Symbol.map Mon May 6 19:59:38 2013 (r250307) +++ stable/9/lib/libsbuf/Symbol.map Mon May 6 20:32:14 2013 (r250308) @@ -22,3 +22,8 @@ FBSD_1.2 { sbuf_done; sbuf_delete; }; + +FBSD_1.3 { + sbuf_start_section; + sbuf_end_section; +}; Modified: stable/9/lib/libsbuf/Version.def ============================================================================== --- stable/9/lib/libsbuf/Version.def Mon May 6 19:59:38 2013 (r250307) +++ stable/9/lib/libsbuf/Version.def Mon May 6 20:32:14 2013 (r250308) @@ -2,3 +2,6 @@ FBSD_1.2 { }; + +FBSD_1.3 { +} FBSD_1.2; Modified: stable/9/share/man/man9/sbuf.9 ============================================================================== --- stable/9/share/man/man9/sbuf.9 Mon May 6 19:59:38 2013 (r250307) +++ stable/9/share/man/man9/sbuf.9 Mon May 6 20:32:14 2013 (r250308) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 21, 2011 +.Dd April 11, 2013 .Dt SBUF 9 .Os .Sh NAME @@ -51,7 +51,9 @@ .Nm sbuf_data , .Nm sbuf_len , .Nm sbuf_done , -.Nm sbuf_delete +.Nm sbuf_delete , +.Nm sbuf_start_section , +.Nm sbuf_end_section .Nd safe string composition .Sh SYNOPSIS .In sys/types.h @@ -100,6 +102,10 @@ .Fn sbuf_done "struct sbuf *s" .Ft void .Fn sbuf_delete "struct sbuf *s" +.Ft void +.Fn sbuf_start_section "struct sbuf *s" "ssize_t *old_lenp" +.Ft ssize_t +.Fn sbuf_end_section "struct sbuf *s" "ssize_t old_len" "size_t pad" "int c" .In sys/sysctl.h .Ft struct sbuf * .Fn sbuf_new_for_sysctl "struct sbuf *s" "char *buf" "int length" "struct sysctl_req *req" @@ -402,6 +408,30 @@ returns the length of the un-drained dat returns non-zero if the .Fa sbuf is finished. +.Pp +The +.Fn sbuf_start_section +and +.Fn sbuf_end_section +functions may be used for automatic section alignment. +The arguments +.Fa pad +and +.Fa c +specify the padding size and a character used for padding. +The arguments +.Fa old_lenp +and +.Fa old_len +are to save and restore the current section length when nested sections +are used. +For the top level section +.Dv NULL +and \-1 can be specified for +.Fa old_lenp +and +.Fa old_len +respectively. .Sh NOTES If an operation caused an .Fa sbuf @@ -473,6 +503,10 @@ returns \-1 if copying string from userl copied otherwise. .Pp The +.Fn sbuf_end_section +function returns the section length or \-1 if the buffer has an error. +.Pp +The .Fn sbuf_finish 9 function (the kernel version) returns ENOMEM if the sbuf overflowed before being finished, Modified: stable/9/sys/kern/subr_sbuf.c ============================================================================== --- stable/9/sys/kern/subr_sbuf.c Mon May 6 19:59:38 2013 (r250307) +++ stable/9/sys/kern/subr_sbuf.c Mon May 6 20:32:14 2013 (r250308) @@ -69,6 +69,7 @@ static MALLOC_DEFINE(M_SBUF, "sbuf", "st #define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1) #define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1)) #define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND) +#define SBUF_ISSECTION(s) ((s)->s_flags & SBUF_INSECTION) /* * Set / clear flags @@ -254,6 +255,8 @@ sbuf_uionew(struct sbuf *s, struct uio * return (NULL); } s->s_len = s->s_size - 1; + if (SBUF_ISSECTION(s)) + s->s_sect_len = s->s_size - 1; *error = 0; return (s); } @@ -272,6 +275,7 @@ sbuf_clear(struct sbuf *s) SBUF_CLEARFLAG(s, SBUF_FINISHED); s->s_error = 0; s->s_len = 0; + s->s_sect_len = 0; } /* @@ -290,6 +294,8 @@ sbuf_setpos(struct sbuf *s, ssize_t pos) KASSERT(pos < s->s_size, ("attempt to seek past end of sbuf (%jd >= %jd)", (intmax_t)pos, (intmax_t)s->s_size)); + KASSERT(!SBUF_ISSECTION(s), + ("attempt to seek when in a section")); if (pos < 0 || pos > s->s_len) return (-1); @@ -372,6 +378,8 @@ sbuf_put_byte(struct sbuf *s, int c) return; } s->s_buf[s->s_len++] = c; + if (SBUF_ISSECTION(s)) + s->s_sect_len++; } /* @@ -491,6 +499,8 @@ sbuf_copyin(struct sbuf *s, const void * /* fall through */ case 0: s->s_len += done - 1; + if (SBUF_ISSECTION(s)) + s->s_sect_len += done - 1; break; default: return (-1); /* XXX */ @@ -601,6 +611,8 @@ sbuf_vprintf(struct sbuf *s, const char if (SBUF_FREESPACE(s) < len) len = SBUF_FREESPACE(s); s->s_len += len; + if (SBUF_ISSECTION(s)) + s->s_sect_len += len; if (!SBUF_HASROOM(s) && !SBUF_CANEXTEND(s)) s->s_error = ENOMEM; @@ -656,8 +668,11 @@ sbuf_trim(struct sbuf *s) if (s->s_error != 0) return (-1); - while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) + while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1])) { --s->s_len; + if (SBUF_ISSECTION(s)) + s->s_sect_len--; + } return (0); } @@ -758,3 +773,58 @@ sbuf_done(const struct sbuf *s) return (SBUF_ISFINISHED(s)); } + +/* + * Start a section. + */ +void +sbuf_start_section(struct sbuf *s, ssize_t *old_lenp) +{ + + assert_sbuf_integrity(s); + assert_sbuf_state(s, 0); + + if (!SBUF_ISSECTION(s)) { + KASSERT(s->s_sect_len == 0, + ("s_sect_len != 0 when starting a section")); + if (old_lenp != NULL) + *old_lenp = -1; + SBUF_SETFLAG(s, SBUF_INSECTION); + } else { + KASSERT(old_lenp != NULL, + ("s_sect_len should be saved when starting a subsection")); + *old_lenp = s->s_sect_len; + s->s_sect_len = 0; + } +} + +/* + * End the section padding to the specified length with the specified + * character. + */ +ssize_t +sbuf_end_section(struct sbuf *s, ssize_t old_len, size_t pad, int c) +{ + ssize_t len; + + assert_sbuf_integrity(s); + assert_sbuf_state(s, 0); + KASSERT(SBUF_ISSECTION(s), + ("attempt to end a section when not in a section")); + + if (pad > 1) { + len = roundup(s->s_sect_len, pad) - s->s_sect_len; + for (; s->s_error == 0 && len > 0; len--) + sbuf_put_byte(s, c); + } + len = s->s_sect_len; + if (old_len == -1) { + s->s_sect_len = 0; + SBUF_CLEARFLAG(s, SBUF_INSECTION); + } else { + s->s_sect_len += old_len; + } + if (s->s_error != 0) + return (-1); + return (len); +} Modified: stable/9/sys/sys/sbuf.h ============================================================================== --- stable/9/sys/sys/sbuf.h Mon May 6 19:59:38 2013 (r250307) +++ stable/9/sys/sys/sbuf.h Mon May 6 20:32:14 2013 (r250308) @@ -52,7 +52,9 @@ struct sbuf { #define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */ #define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */ #define SBUF_DYNSTRUCT 0x00080000 /* sbuf must be freed */ +#define SBUF_INSECTION 0x00100000 /* set by sbuf_start_section() */ int s_flags; /* flags */ + ssize_t s_sect_len; /* current length of section */ }; __BEGIN_DECLS @@ -81,6 +83,8 @@ char *sbuf_data(struct sbuf *); ssize_t sbuf_len(struct sbuf *); int sbuf_done(const struct sbuf *); void sbuf_delete(struct sbuf *); +void sbuf_start_section(struct sbuf *, ssize_t *); +ssize_t sbuf_end_section(struct sbuf *, ssize_t, size_t, int); #ifdef _KERNEL struct uio;