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>