Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Feb 2001 14:30:35 -0700
From:      "Kenneth D. Merry" <ken@kdm.org>
To:        Dag-Erling Smorgrav <des@ofug.org>
Cc:        arch@FreeBSD.ORG
Subject:   Re: sbufs in userland
Message-ID:  <20010226143035.A25402@panzer.kdm.org>
In-Reply-To: <xzpelwlc2hm.fsf@flood.ping.uio.no>; from des@ofug.org on Mon, Feb 26, 2001 at 08:44:37AM %2B0100
References:  <20010226003319.A19994@panzer.kdm.org> <xzpelwlc2hm.fsf@flood.ping.uio.no>

next in thread | previous in thread | raw e-mail | index | archive | help

--qMm9M+Fa2AknHoGS
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Feb 26, 2001 at 08:44:37 +0100, Dag-Erling Smorgrav wrote:
> "Kenneth D. Merry" <ken@kdm.org> writes:
> > 2.	If we do put sbufs in userland, what is the best way to do it?
> 
> Whichever way you do it, you need to change userland sprintf() to
> behave like kernel sprintf(), i.e. use a backend function that does
> the actual formatting and takes a pointer to a character output
> function, instead of what it currently does, which is to fake a FILE
> structure with the target string as buffer.

Well, what I did was change the kernel implementation to do something that
could also be done in userland.

It is using vnsprintf() instead of kvprintf.  Diffs for that, and the
userland conversion are attached.

Ken
-- 
Kenneth Merry
ken@kdm.org

--qMm9M+Fa2AknHoGS
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="subr_sbuf.c.20010226"

==== //depot/FreeBSD-adaptec/src/sys/kern/subr_sbuf.c#1 - /a/ken/perforce/FreeBSD-adaptec/src/sys/kern/subr_sbuf.c ====
*** /tmp/tmp.77466.0	Mon Feb 26 14:27:27 2001
--- /a/ken/perforce/FreeBSD-adaptec/src/sys/kern/subr_sbuf.c	Wed Feb 14 15:33:36 2001
***************
*** 29,42 ****
   */
  
  #include <sys/param.h>
  #include <sys/kernel.h>
  #include <sys/malloc.h>
- #include <sys/sbuf.h>
  #include <sys/systm.h>
- 
  #include <machine/stdarg.h>
  
  MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
  
  /*
   * Predicates
--- 29,48 ----
   */
  
  #include <sys/param.h>
+ #include <sys/sbuf.h>
+ 
+ #ifdef _KERNEL
  #include <sys/kernel.h>
  #include <sys/malloc.h>
  #include <sys/systm.h>
  #include <machine/stdarg.h>
+ #else /* _KERNEL */
+ #include <stdarg.h>
+ #endif /* _KERNEL */
  
+ #ifdef _KERNEL
  MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
+ #endif /* _KERNEL */
  
  /*
   * Predicates
***************
*** 52,83 ****
  #define SBUF_SETFLAG(s, f)	do { (s)->s_flags |= (f); } while (0)
  #define SBUF_CLEARFLAG(s, f)	do { (s)->s_flags &= ~(f); } while (0)
  
  /*
   * Debugging support
   */
! #ifdef INVARIANTS
  static void
  assert_sbuf_integrity(struct sbuf *s)
  {
! 	KASSERT(s != NULL,
  	    (__FUNCTION__ " called with a NULL sbuf pointer"));
! 	KASSERT(s->s_buf != NULL,
  	    (__FUNCTION__ " called with unitialized or corrupt sbuf"));
! 	KASSERT(s->s_len < s->s_size,
  	    ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
  }
  
  static void
  assert_sbuf_state(struct sbuf *s, int state)
  {
! 	KASSERT((s->s_flags & SBUF_FINISHED) == state,
  	    (__FUNCTION__ " called with %sfinished or corrupt sbuf",
  	    (state ? "un" : "")));
  }
! #else
  #define assert_sbuf_integrity(s) do { } while (0)
  #define assert_sbuf_state(s, i)	 do { } while (0)
! #endif
  
  /*
   * Initialize an sbuf.
--- 58,95 ----
  #define SBUF_SETFLAG(s, f)	do { (s)->s_flags |= (f); } while (0)
  #define SBUF_CLEARFLAG(s, f)	do { (s)->s_flags &= ~(f); } while (0)
  
+ #ifdef _KERNEL
+ #define SBASSERT(e, m)  KASSERT(e, m)
+ #else /* _KERNEL */
+ #define SBASSERT(e, m)
+ #endif /* _KERNEL */
+ 
  /*
   * Debugging support
   */
! #if defined(_KERNEL) && defined(INVARIANTS)
  static void
  assert_sbuf_integrity(struct sbuf *s)
  {
! 	SBASSERT(s != NULL,
  	    (__FUNCTION__ " called with a NULL sbuf pointer"));
! 	SBASSERT(s->s_buf != NULL,
  	    (__FUNCTION__ " called with unitialized or corrupt sbuf"));
! 	SBASSERT(s->s_len < s->s_size,
  	    ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
  }
  
  static void
  assert_sbuf_state(struct sbuf *s, int state)
  {
! 	SBASSERT((s->s_flags & SBUF_FINISHED) == state,
  	    (__FUNCTION__ " called with %sfinished or corrupt sbuf",
  	    (state ? "un" : "")));
  }
! #else /* _KERNEL && INVARIANTS */
  #define assert_sbuf_integrity(s) do { } while (0)
  #define assert_sbuf_state(s, i)	 do { } while (0)
! #endif /* _KERNEL && INVARIANTS */
  
  /*
   * Initialize an sbuf.
***************
*** 87,97 ****
  int
  sbuf_new(struct sbuf *s, char *buf, int length, int flags)
  {
! 	KASSERT(length >= 0,
  	    ("attempt to create an sbuf of negative length (%d)", length));
! 	KASSERT(flags == 0,
  	    (__FUNCTION__ " called with non-zero flags"));
! 	KASSERT(s != NULL,
  	    (__FUNCTION__ " called with a NULL sbuf pointer"));
  
  	bzero(s, sizeof *s);
--- 99,109 ----
  int
  sbuf_new(struct sbuf *s, char *buf, int length, int flags)
  {
! 	SBASSERT(length >= 0,
  	    ("attempt to create an sbuf of negative length (%d)", length));
! 	SBASSERT(flags == 0,
  	    (__FUNCTION__ " called with non-zero flags"));
! 	SBASSERT(s != NULL,
  	    (__FUNCTION__ " called with a NULL sbuf pointer"));
  
  	bzero(s, sizeof *s);
***************
*** 100,106 ****
--- 112,122 ----
  		s->s_buf = buf;
  		return (0);
  	}
+ #ifdef _KERNEL
  	s->s_buf = malloc(s->s_size, M_SBUF, M_WAITOK);
+ #else /* _KERNEL */
+ 	s->s_buf = (char *)malloc(s->s_size);
+ #endif /* _KERNEL */
  	if (s->s_buf == NULL)
  		return (-1);
  	SBUF_SETFLAG(s, SBUF_DYNAMIC);
***************
*** 130,138 ****
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, 0);
  	
! 	KASSERT(pos >= 0,
  	    ("attempt to seek to a negative position (%d)", pos));
! 	KASSERT(pos < s->s_size,
  	    ("attempt to seek past end of sbuf (%d >= %d)", pos, s->s_size));
  	       
  	if (pos < 0 || pos > s->s_len)
--- 146,154 ----
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, 0);
  	
! 	SBASSERT(pos >= 0,
  	    ("attempt to seek to a negative position (%d)", pos));
! 	SBASSERT(pos < s->s_size,
  	    ("attempt to seek past end of sbuf (%d >= %d)", pos, s->s_size));
  	       
  	if (pos < 0 || pos > s->s_len)
***************
*** 175,180 ****
--- 191,197 ----
  	return (sbuf_cat(s, str));
  }
  
+ #if 0
  /*
   * PCHAR function for sbuf_printf()
   */
***************
*** 193,198 ****
--- 210,216 ----
  	else
  		SBUF_SETFLAG(s, SBUF_OVERFLOWED);
  }
+ #endif
  
  /*
   * Format the given arguments and append the resulting string to an sbuf.
***************
*** 206,222 ****
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, 0);
  	
! 	KASSERT(fmt != NULL,
  	    (__FUNCTION__ " called with a NULL format string"));
  	
  	if (SBUF_HASOVERFLOWED(s))
  		return (-1);
  
  	va_start(ap, fmt);
  	len = kvprintf(fmt, _sbuf_pchar, s, 10, ap);
  	va_end(ap);
  
! 	KASSERT(s->s_len < s->s_size,
  	    ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
  
  	if (SBUF_HASOVERFLOWED(s))
--- 224,249 ----
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, 0);
  	
! 	SBASSERT(fmt != NULL,
  	    (__FUNCTION__ " called with a NULL format string"));
  	
  	if (SBUF_HASOVERFLOWED(s))
  		return (-1);
  
+ #if 0
  	va_start(ap, fmt);
  	len = kvprintf(fmt, _sbuf_pchar, s, 10, ap);
  	va_end(ap);
+ #endif
+ 	va_start(ap, fmt);
+ 	len = vsnprintf(&s->s_buf[s->s_len], s->s_size - s->s_len, fmt, ap);
+ 	va_end(ap);
+ 
+ 	s->s_len += len;
+ 	if (!SBUF_HASROOM(s))
+ 		SBUF_SETFLAG(s, SBUF_OVERFLOWED);
  
! 	SBASSERT(s->s_len < s->s_size,
  	    ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
  
  	if (SBUF_HASOVERFLOWED(s))
***************
*** 303,308 ****
--- 330,339 ----
  	/* don't care if it's finished or not */
  	
  	if (SBUF_ISDYNAMIC(s))
+ #ifdef _KERNEL
  		free(s->s_buf, M_SBUF);
+ #else /* _KERNEL */
+ 		free(s->s_buf);
+ #endif /* _KERNEL */
  	bzero(s, sizeof *s);
  }

--qMm9M+Fa2AknHoGS--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010226143035.A25402>