aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2017-10-10 16:53:21 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-10-22 20:09:26 +0000
commitc5b47cc03200c983981ac4b8de20fb0e26d4f873 (patch)
tree9072d96478518ce0e5e16be537a746ab9b429620 /src
parentfcf81b5deb8d02ba45907e90bb6668c67986a028 (diff)
add function msgb_printf() to print formatted text into msg buf
In ASCII string based protocols it a printf() version that prints directly to the message buffer may be useful. Add function msgb_printf(), make sure that msg buffer bounderies are not exceeded. If the end of the tail buffer is hit, return with an error code. Change-Id: I15e1af68616309555d0ed9ac5da027c9833d42e3
Diffstat (limited to 'src')
-rw-r--r--src/msgb.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/msgb.c b/src/msgb.c
index 2e9f4a25..6fcbe53a 100644
--- a/src/msgb.c
+++ b/src/msgb.c
@@ -55,6 +55,9 @@
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
+#include <stdarg.h>
+#include <errno.h>
+
#include <osmocom/core/msgb.h>
//#include <openbsc/gsm_data.h>
@@ -376,4 +379,49 @@ const char *msgb_hexdump(const struct msgb *msg)
return buf;
}
+
+/*! Print a string to the end of message buffer.
+ * \param[in] msg message buffer
+ * \returns 0 on success, -EINVAL on error
+ *
+ * The resulting string is printed to the msgb without a trailing nul
+ * character. A nul following the data tail may be written as an implementation
+ * detail, but a trailing nul is never part of the msgb data in terms of
+ * msgb_length().
+ *
+ * Note: the tailroom must always be one byte longer than the string to be
+ * written. The msgb is filled only up to tailroom=1. This is an implementation
+ * detail that allows leaving a nul character behind the valid data.
+ *
+ * In case of error, the msgb remains unchanged, though data may have been
+ * written to the (unused) memory after the tail pointer.
+ */
+int msgb_printf(struct msgb *msgb, const char *format, ...)
+{
+ va_list args;
+ int str_len;
+ int rc = 0;
+
+ OSMO_ASSERT(msgb);
+ OSMO_ASSERT(format);
+
+ /* Regardless of what we plan to add to the buffer, we must at least
+ * be able to store a string terminator (nullstring) */
+ if (msgb_tailroom(msgb) < 1)
+ return -EINVAL;
+
+ va_start(args, format);
+
+ str_len =
+ vsnprintf((char *)msgb->tail, msgb_tailroom(msgb), format, args);
+
+ if (str_len >= msgb_tailroom(msgb) || str_len < 0) {
+ rc = -EINVAL;
+ } else
+ msgb_put(msgb, str_len);
+
+ va_end(args);
+ return rc;
+}
+
/*! @} */