]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/strxcpyx.c
util: introduce strnpcpy_full() and friends to provide whether result is truncated...
[thirdparty/systemd.git] / src / basic / strxcpyx.c
index dbbf7d08d21a92ae4c5559d5c83c983a2bcf088b..52b95650cf38d0aa138651df5814b1731f725c4c 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#include "string-util.h"
 #include "strxcpyx.h"
 
-size_t strnpcpy(char **dest, size_t size, const char *src, size_t len) {
+size_t strnpcpy_full(char **dest, size_t size, const char *src, size_t len, bool *ret_truncated) {
+        bool truncated = false;
+
         assert(dest);
         assert(src);
 
-        if (size == 0)
+        if (size == 0) {
+                if (ret_truncated)
+                        *ret_truncated = len > 0;
                 return 0;
+        }
 
         if (len >= size) {
                 if (size > 1)
                         *dest = mempcpy(*dest, src, size-1);
                 size = 0;
+                truncated = true;
         } else if (len > 0) {
                 *dest = mempcpy(*dest, src, len);
                 size -= len;
         }
 
+        if (ret_truncated)
+                *ret_truncated = truncated;
+
         *dest[0] = '\0';
         return size;
 }
 
-size_t strpcpy(char **dest, size_t size, const char *src) {
+size_t strpcpy_full(char **dest, size_t size, const char *src, bool *ret_truncated) {
         assert(dest);
         assert(src);
 
-        return strnpcpy(dest, size, src, strlen(src));
+        return strnpcpy_full(dest, size, src, strlen(src), ret_truncated);
 }
 
-size_t strpcpyf(char **dest, size_t size, const char *src, ...) {
+size_t strpcpyf_full(char **dest, size_t size, bool *ret_truncated, const char *src, ...) {
+        bool truncated = false;
         va_list va;
         int i;
 
         assert(dest);
         assert(src);
 
-        if (size == 0)
-                return 0;
-
         va_start(va, src);
         i = vsnprintf(*dest, size, src, va);
-        if (i < (int)size) {
+        va_end(va);
+
+        if (i < (int) size) {
                 *dest += i;
                 size -= i;
-        } else
+        } else {
                 size = 0;
-        va_end(va);
+                truncated = i > 0;
+        }
+
+        if (ret_truncated)
+                *ret_truncated = truncated;
+
         return size;
 }
 
-size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
+size_t strpcpyl_full(char **dest, size_t size, bool *ret_truncated, const char *src, ...) {
+        bool truncated = false;
         va_list va;
 
         assert(dest);
@@ -73,31 +89,38 @@ size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
 
         va_start(va, src);
         do {
-                size = strpcpy(dest, size, src);
+                bool t;
+
+                size = strpcpy_full(dest, size, src, &t);
+                truncated = truncated || t;
                 src = va_arg(va, char *);
         } while (src);
         va_end(va);
+
+        if (ret_truncated)
+                *ret_truncated = truncated;
         return size;
 }
 
-size_t strnscpy(char *dest, size_t size, const char *src, size_t len) {
+size_t strnscpy_full(char *dest, size_t size, const char *src, size_t len, bool *ret_truncated) {
         char *s;
 
         assert(dest);
         assert(src);
 
         s = dest;
-        return strnpcpy(&s, size, src, len);
+        return strnpcpy_full(&s, size, src, len, ret_truncated);
 }
 
-size_t strscpy(char *dest, size_t size, const char *src) {
+size_t strscpy_full(char *dest, size_t size, const char *src, bool *ret_truncated) {
         assert(dest);
         assert(src);
 
-        return strnscpy(dest, size, src, strlen(src));
+        return strnscpy_full(dest, size, src, strlen(src), ret_truncated);
 }
 
-size_t strscpyl(char *dest, size_t size, const char *src, ...) {
+size_t strscpyl_full(char *dest, size_t size, bool *ret_truncated, const char *src, ...) {
+        bool truncated = false;
         va_list va;
         char *s;
 
@@ -107,10 +130,16 @@ size_t strscpyl(char *dest, size_t size, const char *src, ...) {
         va_start(va, src);
         s = dest;
         do {
-                size = strpcpy(&s, size, src);
+                bool t;
+
+                size = strpcpy_full(&s, size, src, &t);
+                truncated = truncated || t;
                 src = va_arg(va, char *);
         } while (src);
         va_end(va);
 
+        if (ret_truncated)
+                *ret_truncated = truncated;
+
         return size;
 }