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() */