svn commit: r279992 - in head: share/man/man9 sys/kern sys/sys

Ian Lepore ian at FreeBSD.org
Sat Mar 14 16:02:13 UTC 2015


Author: ian
Date: Sat Mar 14 16:02:11 2015
New Revision: 279992
URL: https://svnweb.freebsd.org/changeset/base/279992

Log:
  Add a new flag, SBUF_INCLUDENUL, and new get/set/clear functions for flags.
  
  The SBUF_INCLUDENUL flag causes the nulterm byte at the end of the string
  to be counted in the length of the data.  If copying the data using the
  sbuf_data() and sbuf_len() functions, or if writing it automatically with
  a drain function, the net effect is that the nulterm byte is copied along
  with the rest of the data.

Modified:
  head/share/man/man9/sbuf.9
  head/sys/kern/subr_sbuf.c
  head/sys/sys/sbuf.h

Modified: head/share/man/man9/sbuf.9
==============================================================================
--- head/share/man/man9/sbuf.9	Sat Mar 14 14:46:10 2015	(r279991)
+++ head/share/man/man9/sbuf.9	Sat Mar 14 16:02:11 2015	(r279992)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 11, 2013
+.Dd March 14, 2015
 .Dt SBUF 9
 .Os
 .Sh NAME
@@ -34,6 +34,9 @@
 .Nm sbuf_new_auto ,
 .Nm sbuf_new_for_sysctl ,
 .Nm sbuf_clear ,
+.Nm sbuf_get_flags ,
+.Nm sbuf_set_flags ,
+.Nm sbuf_clear_flags ,
 .Nm sbuf_setpos ,
 .Nm sbuf_bcat ,
 .Nm sbuf_bcopyin ,
@@ -67,6 +70,12 @@
 .Ft void
 .Fn sbuf_clear "struct sbuf *s"
 .Ft int
+.Fn sbuf_get_flags "struct sbuf *s"
+.Ft void
+.Fn sbuf_set_flags "struct sbuf *s" "int flags"
+.Ft void
+.Fn sbuf_clear_flags "struct sbuf *s" "int flags"
+.Ft int
 .Fn sbuf_setpos "struct sbuf *s" "int pos"
 .Ft int
 .Fn sbuf_bcat "struct sbuf *s" "const void *buf" "size_t len"
@@ -159,6 +168,8 @@ Attempting to extend the sbuf beyond thi
 .It Dv SBUF_AUTOEXTEND
 This indicates that the storage buffer may be extended as necessary, so long
 as resources allow, to hold additional data.
+.It Dv SBUF_INCLUDENUL
+This causes the final nulterm byte to be counted in the length of the data.
 .El
 .Pp
 Note that if
@@ -211,6 +222,18 @@ function invalidates the contents of the
 and resets its position to zero.
 .Pp
 The
+.Fn sbuf_get_flags
+function returns the current user flags.
+The
+.Fn sbuf_set_flags
+and
+.Fn sbuf_get_flags
+functions set or clear one or more user flags, respectively.
+The user flags are described under the
+.Fn sbuf_new
+function.
+.Pp
+The
 .Fn sbuf_setpos
 function sets the
 .Fa sbuf Ns 's

Modified: head/sys/kern/subr_sbuf.c
==============================================================================
--- head/sys/kern/subr_sbuf.c	Sat Mar 14 14:46:10 2015	(r279991)
+++ head/sys/kern/subr_sbuf.c	Sat Mar 14 16:02:11 2015	(r279992)
@@ -262,6 +262,28 @@ sbuf_uionew(struct sbuf *s, struct uio *
 }
 #endif
 
+int
+sbuf_get_flags(struct sbuf *s)
+{
+
+	return (s->s_flags & SBUF_USRFLAGMSK);
+}
+
+void
+sbuf_clear_flags(struct sbuf *s, int flags)
+{
+
+	s->s_flags &= ~(flags & SBUF_USRFLAGMSK);
+}
+
+void
+sbuf_set_flags(struct sbuf *s, int flags)
+{
+
+
+	s->s_flags |= (flags & SBUF_USRFLAGMSK);
+}
+
 /*
  * Clear an sbuf and reset its position.
  */
@@ -697,11 +719,13 @@ sbuf_finish(struct sbuf *s)
 	assert_sbuf_integrity(s);
 	assert_sbuf_state(s, 0);
 
+	s->s_buf[s->s_len] = '\0';
+	if (s->s_flags & SBUF_INCLUDENUL)
+		s->s_len++;
 	if (s->s_drain_func != NULL) {
 		while (s->s_len > 0 && s->s_error == 0)
 			s->s_error = sbuf_drain(s);
 	}
-	s->s_buf[s->s_len] = '\0';
 	SBUF_SETFLAG(s, SBUF_FINISHED);
 #ifdef _KERNEL
 	return (s->s_error);
@@ -743,6 +767,10 @@ sbuf_len(struct sbuf *s)
 
 	if (s->s_error != 0)
 		return (-1);
+
+	/* If finished, nulterm is already in len, else add one. */
+	if ((s->s_flags & (SBUF_INCLUDENUL | SBUF_FINISHED)) == SBUF_INCLUDENUL)
+		return (s->s_len + 1);
 	return (s->s_len);
 }
 

Modified: head/sys/sys/sbuf.h
==============================================================================
--- head/sys/sys/sbuf.h	Sat Mar 14 14:46:10 2015	(r279991)
+++ head/sys/sys/sbuf.h	Sat Mar 14 16:02:11 2015	(r279992)
@@ -48,6 +48,7 @@ struct sbuf {
 	ssize_t		 s_len;		/* current length of string */
 #define	SBUF_FIXEDLEN	0x00000000	/* fixed length buffer (default) */
 #define	SBUF_AUTOEXTEND	0x00000001	/* automatically extend buffer */
+#define	SBUF_INCLUDENUL	0x00000002	/* nulterm byte is counted in len */
 #define	SBUF_USRFLAGMSK	0x0000ffff	/* mask of flags the user may specify */
 #define	SBUF_DYNAMIC	0x00010000	/* s_buf must be freed */
 #define	SBUF_FINISHED	0x00020000	/* set by sbuf_finish() */
@@ -64,6 +65,9 @@ __BEGIN_DECLS
 struct sbuf	*sbuf_new(struct sbuf *, char *, int, int);
 #define		 sbuf_new_auto()				\
 	sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND)
+int		 sbuf_get_flags(struct sbuf *);
+void		 sbuf_clear_flags(struct sbuf *, int);
+void		 sbuf_set_flags(struct sbuf *, int);
 void		 sbuf_clear(struct sbuf *);
 int		 sbuf_setpos(struct sbuf *, ssize_t);
 int		 sbuf_bcat(struct sbuf *, const void *, size_t);


More information about the svn-src-all mailing list