From 787226dc28a5c1ec136210f5e82060be4bde3907 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 23 Oct 2019 12:28:09 +0200 Subject: [PATCH] include/strutils: add strdup_between_structs() * improve strdup_to_offset() readability * add strdup_between_offsets() and strdup_between_structs() to have better support for use-cases when we copy structs Signed-off-by: Karel Zak --- include/strutils.h | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/include/strutils.h b/include/strutils.h index 963e3d6f4..fc3bb0c1c 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -124,29 +124,61 @@ nothing: 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() */