]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - include/strutils.h
include/pidfd-utils: small cleanup
[thirdparty/util-linux.git] / include / strutils.h
index d1f3da1b65f77159cf84ae2ddca0c74ff502d52c..fc3bb0c1c79e8cddfc78417dc5bc88a80b44669e 100644 (file)
@@ -93,29 +93,92 @@ static inline char *mem2strcpy(char *dest, const void *src, size_t n, size_t nma
        return dest;
 }
 
+/* Reallocate @str according to @newstr and copy @newstr to @str; returns new @str */
+static inline char * __attribute__((warn_unused_result))
+strrealloc(char *str, const char *newstr)
+{
+       size_t nsz, osz;
+
+       if (!str)
+               return newstr ? strdup(newstr) : NULL;
+       if (!newstr) {
+               free(str);
+               goto nothing;
+       }
+
+       osz = strlen(str);
+       nsz = strlen(newstr);
+
+       if (nsz > osz) {
+               char *tmp = realloc(str, nsz + 1);
+               if (!tmp)
+                       goto nothing;
+               str = tmp;
+       }
+
+       memcpy(str, newstr, nsz + 1);
+       return str;
+
+nothing:
+       free(str);
+       return NULL;
+}
+
+/* Copy string @str to struct @stru to member addressed by @offset */
 static inline int strdup_to_offset(void *stru, size_t offset, const char *str)
 {
-       char *n = NULL;
        char **o;
+       char *p = NULL;
 
        if (!stru)
                return -EINVAL;
 
        o = (char **) ((char *) stru + offset);
        if (str) {
-               n = strdup(str);
-               if (!n)
+               p = strdup(str);
+               if (!p)
                        return -ENOMEM;
        }
 
        free(*o);
-       *o = n;
+       *o = p;
        return 0;
 }
 
+/* Copy string __str to struct member _m of the struct _s */
 #define strdup_to_struct_member(_s, _m, _str) \
                strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
 
+/* Copy string addressed by @offset between two structs */
+static inline int strdup_between_offsets(void *stru_dst, void *stru_src, size_t offset)
+{
+       char **src;
+       char **dst;
+       char *p = NULL;
+
+       if (!stru_src || !stru_dst)
+               return -EINVAL;
+
+       src = (char **) ((char *) stru_src + offset);
+       dst = (char **) ((char *) stru_dst + offset);
+
+       if (*src) {
+               p = strdup(*src);
+               if (!p)
+                       return -ENOMEM;
+       }
+
+       free(*dst);
+       *dst = p;
+       return 0;
+}
+
+/* Copy string addressed by struct member between two instances of the same
+ * struct type */
+#define strdup_between_structs(_dst, _src, _m) \
+               strdup_between_offsets((void *)_dst, (void *)_src, offsetof(__typeof__(*(_src)), _m))
+
+
 extern char *xstrmode(mode_t mode, char *str);
 
 /* Options for size_to_human_string() */