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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to