]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/subr_sbuf.c
Add drain functionality to sbufs. The drain is a function that is
[FreeBSD/FreeBSD.git] / sys / kern / subr_sbuf.c
1 /*-
2  * Copyright (c) 2000-2008 Poul-Henning Kamp
3  * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer
11  *    in this position and unchanged.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33
34 #ifdef _KERNEL
35 #include <sys/ctype.h>
36 #include <sys/errno.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/systm.h>
40 #include <sys/uio.h>
41 #include <machine/stdarg.h>
42 #else /* _KERNEL */
43 #include <ctype.h>
44 #include <errno.h>
45 #include <stdarg.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #endif /* _KERNEL */
50
51 #include <sys/sbuf.h>
52
53 #ifdef _KERNEL
54 static MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
55 #define SBMALLOC(size)          malloc(size, M_SBUF, M_WAITOK)
56 #define SBFREE(buf)             free(buf, M_SBUF)
57 #else /* _KERNEL */
58 #define KASSERT(e, m)
59 #define SBMALLOC(size)          malloc(size)
60 #define SBFREE(buf)             free(buf)
61 #endif /* _KERNEL */
62
63 /*
64  * Predicates
65  */
66 #define SBUF_ISDYNAMIC(s)       ((s)->s_flags & SBUF_DYNAMIC)
67 #define SBUF_ISDYNSTRUCT(s)     ((s)->s_flags & SBUF_DYNSTRUCT)
68 #define SBUF_ISFINISHED(s)      ((s)->s_flags & SBUF_FINISHED)
69 #define SBUF_HASOVERFLOWED(s)   ((s)->s_flags & SBUF_OVERFLOWED)
70 #define SBUF_HASROOM(s)         ((s)->s_len < (s)->s_size - 1)
71 #define SBUF_FREESPACE(s)       ((s)->s_size - (s)->s_len - 1)
72 #define SBUF_CANEXTEND(s)       ((s)->s_flags & SBUF_AUTOEXTEND)
73
74 /*
75  * Set / clear flags
76  */
77 #define SBUF_SETFLAG(s, f)      do { (s)->s_flags |= (f); } while (0)
78 #define SBUF_CLEARFLAG(s, f)    do { (s)->s_flags &= ~(f); } while (0)
79
80 #define SBUF_MINEXTENDSIZE      16              /* Should be power of 2. */
81 #define SBUF_MAXEXTENDSIZE      PAGE_SIZE
82 #define SBUF_MAXEXTENDINCR      PAGE_SIZE
83
84 /*
85  * Debugging support
86  */
87 #if defined(_KERNEL) && defined(INVARIANTS)
88
89 static void
90 _assert_sbuf_integrity(const char *fun, struct sbuf *s)
91 {
92
93         KASSERT(s != NULL,
94             ("%s called with a NULL sbuf pointer", fun));
95         KASSERT(s->s_buf != NULL,
96             ("%s called with uninitialized or corrupt sbuf", fun));
97         KASSERT(s->s_len < s->s_size,
98             ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
99 }
100
101 static void
102 _assert_sbuf_state(const char *fun, struct sbuf *s, int state)
103 {
104
105         KASSERT((s->s_flags & SBUF_FINISHED) == state,
106             ("%s called with %sfinished or corrupt sbuf", fun,
107             (state ? "un" : "")));
108 }
109
110 #define assert_sbuf_integrity(s) _assert_sbuf_integrity(__func__, (s))
111 #define assert_sbuf_state(s, i)  _assert_sbuf_state(__func__, (s), (i))
112
113 #else /* _KERNEL && INVARIANTS */
114
115 #define assert_sbuf_integrity(s) do { } while (0)
116 #define assert_sbuf_state(s, i)  do { } while (0)
117
118 #endif /* _KERNEL && INVARIANTS */
119
120 #ifdef CTASSERT
121 CTASSERT(powerof2(SBUF_MAXEXTENDSIZE));
122 CTASSERT(powerof2(SBUF_MAXEXTENDINCR));
123 #endif
124
125 static int
126 sbuf_extendsize(int size)
127 {
128         int newsize;
129
130         if (size < (int)SBUF_MAXEXTENDSIZE) {
131                 newsize = SBUF_MINEXTENDSIZE;
132                 while (newsize < size)
133                         newsize *= 2;
134         } else {
135                 newsize = roundup2(size, SBUF_MAXEXTENDINCR);
136         }
137         KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
138         return (newsize);
139 }
140
141
142 /*
143  * Extend an sbuf.
144  */
145 static int
146 sbuf_extend(struct sbuf *s, int addlen)
147 {
148         char *newbuf;
149         int newsize;
150
151         if (!SBUF_CANEXTEND(s))
152                 return (-1);
153         newsize = sbuf_extendsize(s->s_size + addlen);
154         newbuf = SBMALLOC(newsize);
155         if (newbuf == NULL)
156                 return (-1);
157         bcopy(s->s_buf, newbuf, s->s_size);
158         if (SBUF_ISDYNAMIC(s))
159                 SBFREE(s->s_buf);
160         else
161                 SBUF_SETFLAG(s, SBUF_DYNAMIC);
162         s->s_buf = newbuf;
163         s->s_size = newsize;
164         return (0);
165 }
166
167 /*
168  * Initialize an sbuf.
169  * If buf is non-NULL, it points to a static or already-allocated string
170  * big enough to hold at least length characters.
171  */
172 struct sbuf *
173 sbuf_new(struct sbuf *s, char *buf, int length, int flags)
174 {
175
176         KASSERT(length >= 0,
177             ("attempt to create an sbuf of negative length (%d)", length));
178         KASSERT((flags & ~SBUF_USRFLAGMSK) == 0,
179             ("%s called with invalid flags", __func__));
180
181         flags &= SBUF_USRFLAGMSK;
182         if (s == NULL) {
183                 s = SBMALLOC(sizeof(*s));
184                 if (s == NULL)
185                         return (NULL);
186                 bzero(s, sizeof(*s));
187                 s->s_flags = flags;
188                 SBUF_SETFLAG(s, SBUF_DYNSTRUCT);
189         } else {
190                 bzero(s, sizeof(*s));
191                 s->s_flags = flags;
192         }
193         s->s_size = length;
194         if (buf != NULL) {
195                 s->s_buf = buf;
196                 return (s);
197         }
198         if ((flags & SBUF_AUTOEXTEND) != 0)
199                 s->s_size = sbuf_extendsize(s->s_size);
200         s->s_buf = SBMALLOC(s->s_size);
201         if (s->s_buf == NULL) {
202                 if (SBUF_ISDYNSTRUCT(s))
203                         SBFREE(s);
204                 return (NULL);
205         }
206         SBUF_SETFLAG(s, SBUF_DYNAMIC);
207         return (s);
208 }
209
210 #ifdef _KERNEL
211 /*
212  * Create an sbuf with uio data
213  */
214 struct sbuf *
215 sbuf_uionew(struct sbuf *s, struct uio *uio, int *error)
216 {
217
218         KASSERT(uio != NULL,
219             ("%s called with NULL uio pointer", __func__));
220         KASSERT(error != NULL,
221             ("%s called with NULL error pointer", __func__));
222
223         s = sbuf_new(s, NULL, uio->uio_resid + 1, 0);
224         if (s == NULL) {
225                 *error = ENOMEM;
226                 return (NULL);
227         }
228         *error = uiomove(s->s_buf, uio->uio_resid, uio);
229         if (*error != 0) {
230                 sbuf_delete(s);
231                 return (NULL);
232         }
233         s->s_len = s->s_size - 1;
234         *error = 0;
235         return (s);
236 }
237 #endif
238
239 /*
240  * Clear an sbuf and reset its position.
241  */
242 void
243 sbuf_clear(struct sbuf *s)
244 {
245
246         assert_sbuf_integrity(s);
247         /* don't care if it's finished or not */
248
249         SBUF_CLEARFLAG(s, SBUF_FINISHED);
250         SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
251         s->s_error = 0;
252         s->s_len = 0;
253 }
254
255 /*
256  * Set the sbuf's end position to an arbitrary value.
257  * Effectively truncates the sbuf at the new position.
258  */
259 int
260 sbuf_setpos(struct sbuf *s, int pos)
261 {
262
263         assert_sbuf_integrity(s);
264         assert_sbuf_state(s, 0);
265
266         KASSERT(pos >= 0,
267             ("attempt to seek to a negative position (%d)", pos));
268         KASSERT(pos < s->s_size,
269             ("attempt to seek past end of sbuf (%d >= %d)", pos, s->s_size));
270
271         if (pos < 0 || pos > s->s_len)
272                 return (-1);
273         s->s_len = pos;
274         return (0);
275 }
276
277 /*
278  * Set up a drain function and argument on an sbuf to flush data to
279  * when the sbuf buffer overflows.
280  */
281 void
282 sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
283 {
284
285         assert_sbuf_state(s, 0);
286         assert_sbuf_integrity(s);
287         KASSERT(func == s->s_drain_func || s->s_len == 0,
288             ("Cannot change drain to %p on non-empty sbuf %p", func, s));
289         s->s_drain_func = func;
290         s->s_drain_arg = ctx;
291 }
292
293 /*
294  * Call the drain and process the return.
295  */
296 static int
297 sbuf_drain(struct sbuf *s)
298 {
299         int len;
300
301         KASSERT(s->s_len > 0, ("Shouldn't drain empty sbuf %p", s));
302         len = s->s_drain_func(s->s_drain_arg, s->s_buf, s->s_len);
303         if (len < 0) {
304                 s->s_error = -len;
305                 SBUF_SETFLAG(s, SBUF_OVERFLOWED);
306                 return (s->s_error);
307         }
308
309         KASSERT(len > 0, ("Drain must either error or work!"));
310         s->s_len -= len;
311         /*
312          * Fast path for the expected case where all the data was
313          * drained.
314          */
315         if (s->s_len == 0)
316                 return (0);
317         /*
318          * Move the remaining characters to the beginning of the
319          * string.
320          */
321         memmove(s->s_buf, s->s_buf + len, s->s_len);
322         return (0);
323 }
324
325 /*
326  * Append a byte to an sbuf.  This is the core function for appending
327  * to an sbuf and is the main place that deals with extending the
328  * buffer and marking overflow.
329  */
330 static void
331 sbuf_put_byte(int c, struct sbuf *s)
332 {
333
334         assert_sbuf_integrity(s);
335         assert_sbuf_state(s, 0);
336
337         if (SBUF_HASOVERFLOWED(s))
338                 return;
339         if (SBUF_FREESPACE(s) <= 0) {
340                 /* 
341                  * If there is a drain, use it, otherwise extend the
342                  * buffer.
343                  */
344                 if (s->s_drain_func != NULL)
345                         (void)sbuf_drain(s);
346                 else if (sbuf_extend(s, 1) < 0)
347                         SBUF_SETFLAG(s, SBUF_OVERFLOWED);
348                 if (SBUF_HASOVERFLOWED(s))
349                         return;
350         }
351         s->s_buf[s->s_len++] = c;
352 }
353
354 /*
355  * Append a non-NUL character to an sbuf.  This prototype signature is
356  * suitable for use with kvprintf(9).
357  */
358 static void
359 sbuf_putc_func(int c, void *arg)
360 {
361
362         if (c != '\0')
363                 sbuf_put_byte(c, arg);
364 }
365
366 /*
367  * Append a byte string to an sbuf.
368  */
369 int
370 sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
371 {
372         const char *str = buf;
373         const char *end = str + len;
374
375         assert_sbuf_integrity(s);
376         assert_sbuf_state(s, 0);
377
378         if (SBUF_HASOVERFLOWED(s))
379                 return (-1);
380         for (; str < end; str++) {
381                 sbuf_put_byte(*str, s);
382                 if (SBUF_HASOVERFLOWED(s))
383                         return (-1);
384         }
385         return (0);
386 }
387
388 #ifdef _KERNEL
389 /*
390  * Copy a byte string from userland into an sbuf.
391  */
392 int
393 sbuf_bcopyin(struct sbuf *s, const void *uaddr, size_t len)
394 {
395
396         assert_sbuf_integrity(s);
397         assert_sbuf_state(s, 0);
398         KASSERT(s->s_drain_func == NULL,
399             ("Nonsensical copyin to sbuf %p with a drain", s));
400
401         if (SBUF_HASOVERFLOWED(s))
402                 return (-1);
403         if (len == 0)
404                 return (0);
405         if (len > SBUF_FREESPACE(s)) {
406                 sbuf_extend(s, len - SBUF_FREESPACE(s));
407                 if (SBUF_FREESPACE(s) < len)
408                         len = SBUF_FREESPACE(s);
409         }
410         if (copyin(uaddr, s->s_buf + s->s_len, len) != 0)
411                 return (-1);
412         s->s_len += len;
413
414         return (0);
415 }
416 #endif
417
418 /*
419  * Copy a byte string into an sbuf.
420  */
421 int
422 sbuf_bcpy(struct sbuf *s, const void *buf, size_t len)
423 {
424
425         assert_sbuf_integrity(s);
426         assert_sbuf_state(s, 0);
427
428         sbuf_clear(s);
429         return (sbuf_bcat(s, buf, len));
430 }
431
432 /*
433  * Append a string to an sbuf.
434  */
435 int
436 sbuf_cat(struct sbuf *s, const char *str)
437 {
438
439         assert_sbuf_integrity(s);
440         assert_sbuf_state(s, 0);
441
442         if (SBUF_HASOVERFLOWED(s))
443                 return (-1);
444
445         while (*str != '\0') {
446                 sbuf_put_byte(*str, s);
447                 if (SBUF_HASOVERFLOWED(s))
448                         return (-1);
449         }
450         return (0);
451 }
452
453 #ifdef _KERNEL
454 /*
455  * Append a string from userland to an sbuf.
456  */
457 int
458 sbuf_copyin(struct sbuf *s, const void *uaddr, size_t len)
459 {
460         size_t done;
461
462         assert_sbuf_integrity(s);
463         assert_sbuf_state(s, 0);
464         KASSERT(s->s_drain_func == NULL,
465             ("Nonsensical copyin to sbuf %p with a drain", s));
466
467         if (SBUF_HASOVERFLOWED(s))
468                 return (-1);
469
470         if (len == 0)
471                 len = SBUF_FREESPACE(s);        /* XXX return 0? */
472         if (len > SBUF_FREESPACE(s)) {
473                 sbuf_extend(s, len);
474                 if (SBUF_FREESPACE(s) < len)
475                         len = SBUF_FREESPACE(s);
476         }
477         switch (copyinstr(uaddr, s->s_buf + s->s_len, len + 1, &done)) {
478         case ENAMETOOLONG:
479                 SBUF_SETFLAG(s, SBUF_OVERFLOWED);
480                 /* fall through */
481         case 0:
482                 s->s_len += done - 1;
483                 break;
484         default:
485                 return (-1);    /* XXX */
486         }
487
488         return (done);
489 }
490 #endif
491
492 /*
493  * Copy a string into an sbuf.
494  */
495 int
496 sbuf_cpy(struct sbuf *s, const char *str)
497 {
498
499         assert_sbuf_integrity(s);
500         assert_sbuf_state(s, 0);
501
502         sbuf_clear(s);
503         return (sbuf_cat(s, str));
504 }
505
506 /*
507  * Format the given argument list and append the resulting string to an sbuf.
508  */
509 #ifdef _KERNEL
510 int
511 sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
512 {
513
514         assert_sbuf_integrity(s);
515         assert_sbuf_state(s, 0);
516
517         KASSERT(fmt != NULL,
518             ("%s called with a NULL format string", __func__));
519
520         (void)kvprintf(fmt, sbuf_putc_func, s, 10, ap);
521         if (SBUF_HASOVERFLOWED(s))
522                 return (-1);
523         return (0);
524 }
525 #else /* !_KERNEL */
526 int
527 sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
528 {
529         va_list ap_copy;
530         int error, len;
531
532         assert_sbuf_integrity(s);
533         assert_sbuf_state(s, 0);
534
535         KASSERT(fmt != NULL,
536             ("%s called with a NULL format string", __func__));
537
538         if (SBUF_HASOVERFLOWED(s))
539                 return (-1);
540
541         /*
542          * For the moment, there is no way to get vsnprintf(3) to hand
543          * back a character at a time, to push everything into
544          * sbuf_putc_func() as was done for the kernel.
545          *
546          * In userspace, while drains are useful, there's generally
547          * not a problem attempting to malloc(3) on out of space.  So
548          * expand a userland sbuf if there is not enough room for the
549          * data produced by sbuf_[v]printf(3).
550          */
551
552         error = 0;
553         do {
554                 va_copy(ap_copy, ap);
555                 len = vsnprintf(&s->s_buf[s->s_len], SBUF_FREESPACE(s) + 1,
556                     fmt, ap_copy);
557                 va_end(ap_copy);
558
559                 if (SBUF_FREESPACE(s) >= len)
560                         break;
561                 /* Cannot print with the current available space. */
562                 if (s->s_drain_func != NULL && s->s_len > 0)
563                         error = sbuf_drain(s);
564                 else
565                         error = sbuf_extend(s, len - SBUF_FREESPACE(s));
566         } while (error == 0);
567
568         /*
569          * s->s_len is the length of the string, without the terminating nul.
570          * When updating s->s_len, we must subtract 1 from the length that
571          * we passed into vsnprintf() because that length includes the
572          * terminating nul.
573          *
574          * vsnprintf() returns the amount that would have been copied,
575          * given sufficient space, so don't over-increment s_len.
576          */
577         if (SBUF_FREESPACE(s) < len)
578                 len = SBUF_FREESPACE(s);
579         s->s_len += len;
580         if (!SBUF_HASROOM(s) && !SBUF_CANEXTEND(s))
581                 SBUF_SETFLAG(s, SBUF_OVERFLOWED);
582
583         KASSERT(s->s_len < s->s_size,
584             ("wrote past end of sbuf (%d >= %d)", s->s_len, s->s_size));
585
586         if (SBUF_HASOVERFLOWED(s))
587                 return (-1);
588         return (0);
589 }
590 #endif /* _KERNEL */
591
592 /*
593  * Format the given arguments and append the resulting string to an sbuf.
594  */
595 int
596 sbuf_printf(struct sbuf *s, const char *fmt, ...)
597 {
598         va_list ap;
599         int result;
600
601         va_start(ap, fmt);
602         result = sbuf_vprintf(s, fmt, ap);
603         va_end(ap);
604         return (result);
605 }
606
607 /*
608  * Append a character to an sbuf.
609  */
610 int
611 sbuf_putc(struct sbuf *s, int c)
612 {
613
614         sbuf_putc_func(c, s);
615         if (SBUF_HASOVERFLOWED(s))
616                 return (-1);
617         return (0);
618 }
619
620 /*
621  * Trim whitespace characters from end of an sbuf.
622  */
623 int
624 sbuf_trim(struct sbuf *s)
625 {
626
627         assert_sbuf_integrity(s);
628         assert_sbuf_state(s, 0);
629         KASSERT(s->s_drain_func == NULL,
630             ("%s makes no sense on sbuf %p with drain", __func__, s));
631
632         if (SBUF_HASOVERFLOWED(s))
633                 return (-1);
634
635         while (s->s_len > 0 && isspace(s->s_buf[s->s_len-1]))
636                 --s->s_len;
637
638         return (0);
639 }
640
641 /*
642  * Check if an sbuf overflowed
643  */
644 int
645 sbuf_overflowed(struct sbuf *s)
646 {
647
648         return (SBUF_HASOVERFLOWED(s));
649 }
650
651 /*
652  * Finish off an sbuf.
653  */
654 int
655 sbuf_finish(struct sbuf *s)
656 {
657         int error = 0;
658
659         assert_sbuf_integrity(s);
660         assert_sbuf_state(s, 0);
661
662         if (s->s_drain_func != NULL) {
663                 error = s->s_error;
664                 while (s->s_len > 0 && error == 0)
665                         error = sbuf_drain(s);
666         } else if (SBUF_HASOVERFLOWED(s))
667                 error = ENOMEM;
668         s->s_buf[s->s_len] = '\0';
669         SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
670         SBUF_SETFLAG(s, SBUF_FINISHED);
671 #ifdef _KERNEL
672         return (error);
673 #else
674         errno = error;
675         return (-1);
676 #endif
677 }
678
679 /*
680  * Return a pointer to the sbuf data.
681  */
682 char *
683 sbuf_data(struct sbuf *s)
684 {
685
686         assert_sbuf_integrity(s);
687         assert_sbuf_state(s, SBUF_FINISHED);
688         KASSERT(s->s_drain_func == NULL,
689             ("%s makes no sense on sbuf %p with drain", __func__, s));
690
691         return (s->s_buf);
692 }
693
694 /*
695  * Return the length of the sbuf data.
696  */
697 int
698 sbuf_len(struct sbuf *s)
699 {
700
701         assert_sbuf_integrity(s);
702         /* don't care if it's finished or not */
703         KASSERT(s->s_drain_func == NULL,
704             ("%s makes no sense on sbuf %p with drain", __func__, s));
705
706         if (SBUF_HASOVERFLOWED(s))
707                 return (-1);
708         return (s->s_len);
709 }
710
711 /*
712  * Clear an sbuf, free its buffer if necessary.
713  */
714 void
715 sbuf_delete(struct sbuf *s)
716 {
717         int isdyn;
718
719         assert_sbuf_integrity(s);
720         /* don't care if it's finished or not */
721
722         if (SBUF_ISDYNAMIC(s))
723                 SBFREE(s->s_buf);
724         isdyn = SBUF_ISDYNSTRUCT(s);
725         bzero(s, sizeof(*s));
726         if (isdyn)
727                 SBFREE(s);
728 }
729
730 /*
731  * Check if an sbuf has been finished.
732  */
733 int
734 sbuf_done(struct sbuf *s)
735 {
736
737         return (SBUF_ISFINISHED(s));
738 }