svn commit: r250308 - in stable/9: lib/libsbuf share/man/man9 sys/kern sys/sys

Mikolaj Golub trociny at FreeBSD.org
Mon May 6 20:32:16 UTC 2013


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;


More information about the svn-src-stable-9 mailing list