Added concat_buf api to util.h, as inline functions to avoid duplication in tgtadm.c. Should consider separation into a separate file in the future. concat_printf() is based on FILE* produced by open_memstream(). This mechanism takes care of the dynamic allocation and possible re-allocation of memory on the as-needed basis. Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx> --- usr/util.h | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 77 insertions(+), 11 deletions(-) diff --git a/usr/util.h b/usr/util.h index 8abdb94..45a96ec 100644 --- a/usr/util.h +++ b/usr/util.h @@ -8,6 +8,10 @@ #include <signal.h> #include <syscall.h> #include <unistd.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <limits.h> #include <linux/types.h> @@ -88,17 +92,6 @@ static inline int between(uint32_t seq1, uint32_t seq2, uint32_t seq3) return seq3 - seq2 >= seq1 - seq2; } -#define shprintf(total, buf, rest, fmt, args...) \ -do { \ - int len; \ - len = snprintf(buf, rest, fmt, ##args); \ - if (len > rest) \ - goto overflow; \ - buf += len; \ - total += len; \ - rest -= len; \ -} while (0) - extern unsigned long pagesize, pageshift; #if defined(__NR_signalfd) && defined(USE_SIGNALFD) @@ -151,4 +144,77 @@ struct signalfd_siginfo { ret; \ }) +struct concat_buf { + FILE *streamf; + int err; + int used; + char *buf; + int size; +}; + +static inline void concat_buf_init(struct concat_buf *b) +{ + b->streamf = open_memstream(&b->buf, (size_t *)&b->size); + b->err = b->streamf ? 0 : errno; + b->used = 0; +} + +static inline int concat_printf(struct concat_buf *b, const char *format, ...) +{ + va_list args; + int nprinted; + + if (!b->err) { + va_start(args, format); + nprinted = vfprintf(b->streamf, format, args); + if (nprinted >= 0) + b->used += nprinted; + else { + b->err = nprinted; + fclose(b->streamf); + b->streamf = NULL; + } + va_end(args); + } + return b->err; +} + +static inline const char *concat_delim(struct concat_buf *b, const char *delim) +{ + return !b->used ? "" : delim; +} + +static inline int concat_buf_finish(struct concat_buf *b) +{ + if (b->streamf) { + fclose(b->streamf); + b->streamf = NULL; + if (b->size) + b->size ++; /* account for trailing NULL char */ + } + return b->err; +} + +static inline int concat_write(struct concat_buf *b, int fd, int offset) +{ + concat_buf_finish(b); + + if (b->err) + return b->err; + + if (b->size - offset > 0) + return write(fd, b->buf + offset, b->size - offset); + else + return 0; +} + +static inline void concat_buf_release(struct concat_buf *b) +{ + concat_buf_finish(b); + if (b->buf) { + free(b->buf); + memset(b, 0, sizeof(*b)); + } +} + #endif -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html