From e5c434a2df294eb565fca77ace9daae1aa9d9acd Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Sun, 30 Jul 2017 17:04:06 +0100 Subject: [PATCH] librb: add rb_snprintf_try_append For when it might fit, or it might not. --- librb/include/rb_tools.h | 9 ++------- librb/src/export-syms.txt | 1 + librb/src/tools.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/librb/include/rb_tools.h b/librb/include/rb_tools.h index 26186763..6b45b037 100644 --- a/librb/include/rb_tools.h +++ b/librb/include/rb_tools.h @@ -36,13 +36,8 @@ char *rb_strcasestr(const char *s, const char *find); size_t rb_strlcpy(char *dst, const char *src, size_t siz); size_t rb_strlcat(char *dst, const char *src, size_t siz); size_t rb_strnlen(const char *s, size_t count); - -#ifdef __GNUC__ -int rb_snprintf_append(char *str, size_t len, const char *format, ...) - __attribute__ ((format(printf, 3, 4))); -#else -int rb_snprintf_append(char *str, const size_t size, const char *, ...); -#endif +int rb_snprintf_append(char *str, size_t len, const char *format, ...) AFP(3,4); +int rb_snprintf_try_append(char *str, size_t len, const char *format, ...) AFP(3,4); char *rb_basename(const char *); char *rb_dirname(const char *); diff --git a/librb/src/export-syms.txt b/librb/src/export-syms.txt index 39256305..ddd4a7fc 100644 --- a/librb/src/export-syms.txt +++ b/librb/src/export-syms.txt @@ -161,6 +161,7 @@ rb_setup_fd rb_setup_ssl_server rb_sleep rb_snprintf_append +rb_snprintf_try_append rb_socket rb_socketpair rb_spawn_process diff --git a/librb/src/tools.c b/librb/src/tools.c index 05c7e3eb..992508fb 100644 --- a/librb/src/tools.c +++ b/librb/src/tools.c @@ -324,6 +324,41 @@ rb_snprintf_append(char *str, size_t len, const char *format, ...) return (orig_len + append_len); } +/* + * rb_snprintf_try_append() + * appends snprintf formatted string to the end of the buffer but not + * exceeding len + * returns -1 if there isn't enough space for the whole string to fit + */ +int +rb_snprintf_try_append(char *str, size_t len, const char *format, ...) +{ + if(len == 0) + return -1; + + int orig_len = strlen(str); + + if((int)len < orig_len) { + str[len - 1] = '\0'; + return -1; + } + + va_list ap; + va_start(ap, format); + int append_len = vsnprintf(str + orig_len, len - orig_len, format, ap); + va_end(ap); + + if (append_len < 0) + return append_len; + + if (orig_len + append_len > (int)(len - 1)) { + str[orig_len] = '\0'; + return -1; + } + + return (orig_len + append_len); +} + /* rb_basename * * input -