[PATCH 2/6] mgmt and concat_buf: added concat_buf api to util.h

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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-allocatin of memory on
the as-needed basis.

Signed-off-by: Alexander Nezhinsky <alexandern@xxxxxxxxxxxx>
---
 usr/util.h |   63 +++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/usr/util.h b/usr/util.h
index 8abdb94..275f6f9 100644
--- a/usr/util.h
+++ b/usr/util.h
@@ -8,6 +8,8 @@
 #include <signal.h>
 #include <syscall.h>
 #include <unistd.h>
+#include <stdarg.h>
+#include <stdio.h>
 #include <limits.h>
 #include <linux/types.h>
 
@@ -88,17 +90,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 +142,54 @@ struct signalfd_siginfo {
 	ret;						\
 })
 
+struct concat_buf {
+	FILE *streamf;
+	int err;
+	int used;
+	int *size;
+};
+
+static inline void concat_buf_init(struct concat_buf *b, char **buf, int *size)
+{
+	b->streamf = open_memstream(buf, (size_t *)size);
+	b->err = b->streamf ? 0 : errno;
+	b->used = 0;
+	b->size = size;
+}
+
+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;
+		(*b->size) ++; /* account for trailing NULL char */
+	}
+	return b->err;
+}
+
 #endif
-- 
1.7.3.2

--
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


[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux