Add sbuf_copyin(). Also add 'b' variants of sbuf_{cat,copyin,cpy}() which

ignore NUL bytes in the source string.
This commit is contained in:
des 2001-06-11 17:05:52 +00:00
parent cd17b04723
commit 86b7e548ab
3 changed files with 160 additions and 2 deletions

View File

@ -32,7 +32,11 @@
.Nm sbuf_new ,
.Nm sbuf_clear ,
.Nm sbuf_setpos ,
.Nm sbuf_bcat ,
.Nm sbuf_bcopyin ,
.Nm sbuf_bcpy ,
.Nm sbuf_cat ,
.Nm sbuf_copyin ,
.Nm sbuf_cpy ,
.Nm sbuf_printf ,
.Nm sbuf_putc ,
@ -52,8 +56,16 @@
.Ft int
.Fn sbuf_setpos "struct sbuf *s" "int pos"
.Ft int
.Fn sbuf_bcat "struct sbuf *s" "const char *str" "size_t len"
.Ft int
.Fn sbuf_bcopyin "struct sbuf *s" "const void *uaddr" "size_t len"
.Ft int
.Fn sbuf_bcpy "struct sbuf *s" "const char *str" "size_t len"
.Ft int
.Fn sbuf_cat "struct sbuf *s" "const char *str"
.Ft int
.Fn sbuf_copyin "struct sbuf *s" "const void *uaddr" "size_t len"
.Ft int
.Fn sbuf_cpy "struct sbuf *s" "const char *str"
.Ft int
.Fn sbuf_printf "struct sbuf *s" "char *fmt" "..."
@ -131,18 +143,57 @@ which is a value between zero and one less than the size of the
storage buffer.
.Pp
The
.Fn sbuf_bcat
function appends the first
.Fa len
bytes from the byte string
.Fa str
to the
.Fa sbuf .
.Pp
The
.Fn sbuf_bcopyin
function copies
.Fa len
bytes from the specified userland address into the
.Fa sbuf .
.Pp
The
.Fn sbuf_bcpy
function replaces the contents of the
.Fa sbuf
with the first
.Fa len
bytes from the byte string
.Fa str .
.Pp
The
.Fn sbuf_cat
function appends the string
function appends the NUL-terminated string
.Fa str
to the
.Fa sbuf
at the current position.
.Pp
The
.Fn sbuf_copyin
function copies a NUL-terminated string from the specified userland
address into the
.Fa sbuf .
If the
.Fa len
argument is non-zero, no more than
.Fa len
characters (not counting the terminating NUL) are copied; otherwise
the entire string, or as much of it as can fit in the
.Fa sbuf ,
is copied.
.Pp
The
.Fn sbuf_cpy
function replaces the contents of the
.Fa sbuf
with those of the string
with those of the NUL-terminated string
.Fa str .
This is equivalent to calling
.Fn sbuf_cat
@ -248,6 +299,8 @@ return
.Dv NULL
and \-1, respectively, if the buffer overflowed.
.Sh SEE ALSO
.Xr copyin 9 ,
.Xr copyinstr 9 ,
.Xr printf 3 ,
.Xr strcat 3 ,
.Xr strcpy 3

View File

@ -166,6 +166,72 @@ sbuf_setpos(struct sbuf *s, int pos)
return (0);
}
/*
* Append a byte string to an sbuf.
*/
int
sbuf_bcat(struct sbuf *s, const char *str, size_t len)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
if (SBUF_HASOVERFLOWED(s))
return (-1);
while (len-- && SBUF_HASROOM(s))
s->s_buf[s->s_len++] = *str++;
if (len) {
SBUF_SETFLAG(s, SBUF_OVERFLOWED);
return (-1);
}
return (0);
}
#ifdef _KERNEL
/*
* Copy a byte string from userland into an sbuf.
*/
int
sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
if (SBUF_HASOVERFLOWED(s))
return (-1);
if (len == 0)
return (0);
if (len > (s->s_size - s->s_len - 1))
len = s->s_size - s->s_len - 1;
switch (copyin(uaddr, s->s_buf + s->s_len, len)) {
case ENAMETOOLONG:
SBUF_SETFLAG(s, SBUF_OVERFLOWED);
/* fall through */
case 0:
s->s_len += len;
break;
default:
return (-1); /* XXX */
}
return (0);
}
#endif
/*
* Copy a byte string into an sbuf.
*/
int
sbuf_bcpy(struct sbuf *s, const char *str, size_t len)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
sbuf_clear(s);
return (sbuf_bcat(s, str, len));
}
/*
* Append a string to an sbuf.
*/
@ -187,6 +253,38 @@ sbuf_cat(struct sbuf *s, const char *str)
return (0);
}
#ifdef _KERNEL
/*
* Copy a string from userland into an sbuf.
*/
int
sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
{
size_t done;
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
if (SBUF_HASOVERFLOWED(s))
return (-1);
if (len == 0 || len > (s->s_size - s->s_len - 1))
len = s->s_size - s->s_len - 1;
switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
case ENAMETOOLONG:
SBUF_SETFLAG(s, SBUF_OVERFLOWED);
/* fall through */
case 0:
s->s_len += done - 1;
break;
default:
return (-1); /* XXX */
}
return (0);
}
#endif
/*
* Copy a string into an sbuf.
*/

View File

@ -54,6 +54,8 @@ __BEGIN_DECLS
struct sbuf *sbuf_new(struct sbuf *s, char *buf, int length, int flags);
void sbuf_clear(struct sbuf *s);
int sbuf_setpos(struct sbuf *s, int pos);
int sbuf_bcat(struct sbuf *s, const char *str, size_t len);
int sbuf_bcpy(struct sbuf *s, const char *str, size_t len);
int sbuf_cat(struct sbuf *s, const char *str);
int sbuf_cpy(struct sbuf *s, const char *str);
int sbuf_printf(struct sbuf *s, char *fmt, ...);
@ -63,6 +65,11 @@ void sbuf_finish(struct sbuf *s);
char *sbuf_data(struct sbuf *s);
int sbuf_len(struct sbuf *s);
void sbuf_delete(struct sbuf *s);
#ifdef _KERNEL
int sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len);
int sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len);
#endif
__END_DECLS
#endif