Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jan 2001 21:36:05 -0700
From:      "Justin T. Gibbs" <gibbs@scsiguy.com>
To:        freebsd-arch@FreeBSD.org
Subject:   Re: Proposed chage to sbuf semantics.
Message-ID:  <200101110436.f0B4a5T00319@caspian.scsiguy.com>

next in thread | raw e-mail | index | archive | help
I have yet to see a single comment about these changes.
If I don't hear anything by Friday, I'll commit them to
the tree.

--
Justin

------- Forwarded Message

To: freebsd-arch@FreeBSD.org
Subject: Proposed chage to sbuf semantics.
Date: Thu, 04 Jan 2001 21:59:55 -0700
From: "Justin T. Gibbs" <gibbs@caspian.scsiguy.com>

I decided to use the sbuf code in some recent cardbus enhancements.
Unfortunately, the sbuf code tried its best to prevent me from doing
what I wanted to do.  My goal was to fill a fixed sized buffer
from a whole slew of data sources that may or may not be available.
I didn't care if the end result was a truncated string so long as
it was nul terminated.  The only additional requirement for this
task was the ability to occasionally find out if anything had
been written to the sbuf prior to finalizing it (you may want to
add a separator before adding new data, etc.)  This kind of scenario
is all over the CAM code too... you prioritize what you put in the
passed in buffer and losing data off the end is okay.

The following patches allowed me to get what I needed out of sbuf.
I don't think it is unreasonable to allow this kind of behavior,
but I'm sure someone will disagree. 8-)

1) Allow the user to finalize an overflowed buffer.  If the user
   really cares about overflow, all they need to do is look at
   the error code of all previos operations or explicitly check
   for overflow prior to finalizing.  Finalizing now clears the
   overflow flag as the string is null terminated, which allowes
   all "after finalize" methods to operate on this sbuf.

2) Remove SBUF_HASOVERFLOWED test in sbuf_data().  It can never
   be true if we've finalized the sbuf which is an asserted state
   for this method.

3) Add an SBUF_HASDATA macro that indicates if any data is currently
   in the sbuf.  sbuf_len() is only available once you finalize an
   sbuf or I would have used that.

4) Add an SBUF_CLEARFLAG macro to mirror SBUF_SETFLAG().  It is
   debatable whether this should be in the exported sbuf API,
   but the same could be said for SBUF_SETFLAG().

- --
Justin

Index: kern/subr_sbuf.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/subr_sbuf.c,v
retrieving revision 1.1
diff -c -r1.1 subr_sbuf.c
*** kern/subr_sbuf.c	2000/12/13 19:51:07	1.1
- --- kern/subr_sbuf.c	2001/01/03 20:36:39
***************
*** 220,229 ****
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, 0);
  	
! 	if (SBUF_HASOVERFLOWED(s))
! 		return (-1);
! 	
! 	s->s_buf[s->s_len++] = '\0';
  	SBUF_SETFLAG(s, SBUF_FINISHED);
  	return (0);
  }
- --- 220,230 ----
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, 0);
  	
! 	if (SBUF_HASOVERFLOWED(s)) {
! 		s->s_buf[s->s_len] = '\0';
! 		SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
! 	} else
! 		s->s_buf[s->s_len++] = '\0';
  	SBUF_SETFLAG(s, SBUF_FINISHED);
  	return (0);
  }
***************
*** 237,244 ****
  	assert_sbuf_integrity(s);
  	assert_sbuf_state(s, SBUF_FINISHED);
  	
- - 	if (SBUF_HASOVERFLOWED(s))
- - 		return (NULL);
  	return s->s_buf;
  }
  
- --- 238,243 ----
Index: sys/sbuf.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/sbuf.h,v
retrieving revision 1.1
diff -c -r1.1 sbuf.h
*** sys/sbuf.h	2000/12/13 19:51:07	1.1
- --- sys/sbuf.h	2001/01/03 20:40:54
***************
*** 53,63 ****
- --- 53,65 ----
  #define SBUF_ISFINISHED(s)	((s)->s_flags & SBUF_FINISHED)
  #define SBUF_HASOVERFLOWED(s)	((s)->s_flags & SBUF_OVERFLOWED)
  #define SBUF_HASROOM(s)		((s)->s_len < (s)->s_size - 1)
+ #define SBUF_HASDATA(s)		((s)->s_len > 0)
  
  /*
   * Other macros
   */
  #define SBUF_SETFLAG(s, f)	do { (s)->s_flags |= (f); } while (0)
+ #define SBUF_CLEARFLAG(s, f)	do { (s)->s_flags &= ~(f); } while (0)
  
  /*
   * API functions

------- End of Forwarded Message



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?200101110436.f0B4a5T00319>