From c5b47cc03200c983981ac4b8de20fb0e26d4f873 Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Tue, 10 Oct 2017 16:53:21 +0200 Subject: 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 --- src/msgb.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/msgb.c') 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 #include #include +#include +#include + #include //#include @@ -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; +} + /*! @} */ -- cgit v1.2.3