Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/subr_sbuf.c
Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#endif /* _KERNEL */ | #endif /* _KERNEL */ | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers"); | static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers"); | ||||
#define SBMALLOC(size) malloc(size, M_SBUF, M_WAITOK|M_ZERO) | #define SBMALLOC(size, flags) malloc(size, M_SBUF, (flags) | M_ZERO) | ||||
#define SBFREE(buf) free(buf, M_SBUF) | #define SBFREE(buf) free(buf, M_SBUF) | ||||
#else /* _KERNEL */ | #else /* _KERNEL */ | ||||
#define KASSERT(e, m) | #define KASSERT(e, m) | ||||
#define SBMALLOC(size) calloc(1, size) | #define SBMALLOC(size, flags) calloc(1, size) | ||||
#define SBFREE(buf) free(buf) | #define SBFREE(buf) free(buf) | ||||
#endif /* _KERNEL */ | #endif /* _KERNEL */ | ||||
/* | /* | ||||
* Predicates | * Predicates | ||||
*/ | */ | ||||
#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC) | #define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC) | ||||
#define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT) | #define SBUF_ISDYNSTRUCT(s) ((s)->s_flags & SBUF_DYNSTRUCT) | ||||
#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED) | #define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED) | ||||
#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1) | #define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1) | ||||
#define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1)) | #define SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1)) | ||||
#define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND) | #define SBUF_CANEXTEND(s) ((s)->s_flags & SBUF_AUTOEXTEND) | ||||
#define SBUF_ISSECTION(s) ((s)->s_flags & SBUF_INSECTION) | #define SBUF_ISSECTION(s) ((s)->s_flags & SBUF_INSECTION) | ||||
#define SBUF_NULINCLUDED(s) ((s)->s_flags & SBUF_INCLUDENUL) | #define SBUF_NULINCLUDED(s) ((s)->s_flags & SBUF_INCLUDENUL) | ||||
#define SBUF_ISDRAINTOEOR(s) ((s)->s_flags & SBUF_DRAINTOEOR) | #define SBUF_ISDRAINTOEOR(s) ((s)->s_flags & SBUF_DRAINTOEOR) | ||||
#define SBUF_DODRAINTOEOR(s) (SBUF_ISSECTION(s) && SBUF_ISDRAINTOEOR(s)) | #define SBUF_DODRAINTOEOR(s) (SBUF_ISSECTION(s) && SBUF_ISDRAINTOEOR(s)) | ||||
#define SBUF_MALLOCFLAG(s) \ | |||||
(((s)->s_flags & SBUF_NOWAIT) ? M_NOWAIT : M_WAITOK) | |||||
/* | /* | ||||
* Set / clear flags | * Set / clear flags | ||||
*/ | */ | ||||
#define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0) | #define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0) | ||||
#define SBUF_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0) | #define SBUF_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0) | ||||
#define SBUF_MINSIZE 2 /* Min is 1 byte + nulterm. */ | #define SBUF_MINSIZE 2 /* Min is 1 byte + nulterm. */ | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | |||||
sbuf_extend(struct sbuf *s, int addlen) | sbuf_extend(struct sbuf *s, int addlen) | ||||
{ | { | ||||
char *newbuf; | char *newbuf; | ||||
int newsize; | int newsize; | ||||
if (!SBUF_CANEXTEND(s)) | if (!SBUF_CANEXTEND(s)) | ||||
return (-1); | return (-1); | ||||
newsize = sbuf_extendsize(s->s_size + addlen); | newsize = sbuf_extendsize(s->s_size + addlen); | ||||
newbuf = SBMALLOC(newsize); | newbuf = SBMALLOC(newsize, SBUF_MALLOCFLAG(s)); | ||||
if (newbuf == NULL) | if (newbuf == NULL) | ||||
return (-1); | return (-1); | ||||
memcpy(newbuf, s->s_buf, s->s_size); | memcpy(newbuf, s->s_buf, s->s_size); | ||||
if (SBUF_ISDYNAMIC(s)) | if (SBUF_ISDYNAMIC(s)) | ||||
SBFREE(s->s_buf); | SBFREE(s->s_buf); | ||||
else | else | ||||
SBUF_SETFLAG(s, SBUF_DYNAMIC); | SBUF_SETFLAG(s, SBUF_DYNAMIC); | ||||
s->s_buf = newbuf; | s->s_buf = newbuf; | ||||
Show All 10 Lines | |||||
sbuf_newbuf(struct sbuf *s, char *buf, int length, int flags) | sbuf_newbuf(struct sbuf *s, char *buf, int length, int flags) | ||||
{ | { | ||||
memset(s, 0, sizeof(*s)); | memset(s, 0, sizeof(*s)); | ||||
s->s_flags = flags; | s->s_flags = flags; | ||||
s->s_size = length; | s->s_size = length; | ||||
s->s_buf = buf; | s->s_buf = buf; | ||||
if ((s->s_flags & SBUF_AUTOEXTEND) == 0) { | if (!SBUF_CANEXTEND(s)) { | ||||
KASSERT(s->s_size >= SBUF_MINSIZE, | KASSERT(s->s_size >= SBUF_MINSIZE, | ||||
("attempt to create an sbuf smaller than %d bytes", | ("attempt to create an sbuf smaller than %d bytes", | ||||
SBUF_MINSIZE)); | SBUF_MINSIZE)); | ||||
} | } | ||||
if (s->s_buf != NULL) | if (s->s_buf != NULL) | ||||
return (s); | return (s); | ||||
if ((flags & SBUF_AUTOEXTEND) != 0) | if (SBUF_CANEXTEND(s)) | ||||
s->s_size = sbuf_extendsize(s->s_size); | s->s_size = sbuf_extendsize(s->s_size); | ||||
s->s_buf = SBMALLOC(s->s_size); | s->s_buf = SBMALLOC(s->s_size, SBUF_MALLOCFLAG(s)); | ||||
if (s->s_buf == NULL) | if (s->s_buf == NULL) | ||||
return (NULL); | return (NULL); | ||||
SBUF_SETFLAG(s, SBUF_DYNAMIC); | SBUF_SETFLAG(s, SBUF_DYNAMIC); | ||||
return (s); | return (s); | ||||
} | } | ||||
/* | /* | ||||
* Initialize an sbuf. | * Initialize an sbuf. | ||||
* If buf is non-NULL, it points to a static or already-allocated string | * If buf is non-NULL, it points to a static or already-allocated string | ||||
* big enough to hold at least length characters. | * big enough to hold at least length characters. | ||||
*/ | */ | ||||
struct sbuf * | struct sbuf * | ||||
sbuf_new(struct sbuf *s, char *buf, int length, int flags) | sbuf_new(struct sbuf *s, char *buf, int length, int flags) | ||||
{ | { | ||||
KASSERT(length >= 0, | KASSERT(length >= 0, | ||||
("attempt to create an sbuf of negative length (%d)", length)); | ("attempt to create an sbuf of negative length (%d)", length)); | ||||
KASSERT((flags & ~SBUF_USRFLAGMSK) == 0, | KASSERT((flags & ~SBUF_USRFLAGMSK) == 0, | ||||
("%s called with invalid flags", __func__)); | ("%s called with invalid flags", __func__)); | ||||
flags &= SBUF_USRFLAGMSK; | flags &= SBUF_USRFLAGMSK; | ||||
if (s != NULL) | if (s != NULL) | ||||
return (sbuf_newbuf(s, buf, length, flags)); | return (sbuf_newbuf(s, buf, length, flags)); | ||||
s = SBMALLOC(sizeof(*s)); | s = SBMALLOC(sizeof(*s), (flags & SBUF_NOWAIT) ? M_NOWAIT : M_WAITOK); | ||||
if (s == NULL) | if (s == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (sbuf_newbuf(s, buf, length, flags) == NULL) { | if (sbuf_newbuf(s, buf, length, flags) == NULL) { | ||||
SBFREE(s); | SBFREE(s); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
SBUF_SETFLAG(s, SBUF_DYNSTRUCT); | SBUF_SETFLAG(s, SBUF_DYNSTRUCT); | ||||
return (s); | return (s); | ||||
▲ Show 20 Lines • Show All 653 Lines • Show Last 20 Lines |