* Initialize an sbuf. * If buf is non-NULL, it points to a static or already-allocated string * big enough to hold at least length characters. */
| 193 | * big enough to hold at least length characters. |
| 194 | */ |
| 195 | struct sbuf * |
| 196 | sbuf_new(struct sbuf *s, char *buf, int length, int flags) |
| 197 | { |
| 198 | |
| 199 | KASSERT(length >= 0, |
| 200 | ("attempt to create an sbuf of negative length (%d)", length)); |
| 201 | KASSERT((flags & ~SBUF_USRFLAGMSK) == 0, |
| 202 | ("%s called with invalid flags", __func__)); |
| 203 | KASSERT((flags & SBUF_AUTOEXTEND) || length >= SBUF_MINSIZE, |
| 204 | ("sbuf buffer %d smaller than minimum %d bytes", length, |
| 205 | SBUF_MINSIZE)); |
| 206 | |
| 207 | flags &= SBUF_USRFLAGMSK; |
| 208 | |
| 209 | /* |
| 210 | * Allocate 'DYNSTRUCT' sbuf from the heap, if NULL 's' was provided. |
| 211 | */ |
| 212 | if (s == NULL) { |
| 213 | s = SBMALLOC(sizeof(*s), |
| 214 | (flags & SBUF_NOWAIT) ? M_NOWAIT : M_WAITOK); |
| 215 | if (s == NULL) |
| 216 | goto out; |
| 217 | SBUF_SETFLAG(s, SBUF_DYNSTRUCT); |
| 218 | } else { |
| 219 | /* |
| 220 | * DYNSTRUCT SBMALLOC sbufs are allocated with M_ZERO, but |
| 221 | * user-provided sbuf objects must be initialized. |
| 222 | */ |
| 223 | memset(s, 0, sizeof(*s)); |
| 224 | } |
| 225 | |
| 226 | s->s_flags |= flags; |
| 227 | s->s_size = length; |
| 228 | s->s_buf = buf; |
| 229 | /* |
| 230 | * Never-written sbufs do not need \n termination. |
| 231 | */ |
| 232 | SBUF_SETFLAG(s, SBUF_DRAINATEOL); |
| 233 | |
| 234 | /* |
| 235 | * Allocate DYNAMIC, i.e., heap data buffer backing the sbuf, if no |
| 236 | * buffer was provided. |
| 237 | */ |
| 238 | if (s->s_buf == NULL) { |
| 239 | if (SBUF_CANEXTEND(s)) |
| 240 | s->s_size = sbuf_extendsize(s->s_size); |
| 241 | s->s_buf = SBMALLOC(s->s_size, SBUF_MALLOCFLAG(s)); |
| 242 | if (s->s_buf == NULL) |
| 243 | goto out; |
| 244 | SBUF_SETFLAG(s, SBUF_DYNAMIC); |
| 245 | } |
| 246 | |
| 247 | out: |
| 248 | if (s != NULL && s->s_buf == NULL) { |
| 249 | if (SBUF_ISDYNSTRUCT(s)) |
| 250 | SBFREE(s); |
| 251 | s = NULL; |
| 252 | } |
no test coverage detected