The stdndupa has a couple of gotchas:
- allocates memory on stack via alloca(3)... where we pass it a
user-provided string in at least one instance
- it's a GNU extension missing on musl and bionic
The mkdir_p() function is not a hot path, so using heap allocation is
perfectly fine. Swap the stdndupa for our local helper memdup.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Link: https://github.com/kmod-project/kmod/pull/92
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
# dietlibc doesn't have st.st_mtim struct member
AC_CHECK_MEMBERS([struct stat.st_mtim], [], [], [#include <sys/stat.h>])
-# musl 1.0 and bionic 4.4 don't have strndupa
# basename may be only available in libgen.h with the POSIX behavior,
# not desired here
-AC_CHECK_DECLS_ONCE([[strndupa], [basename]], [], [], [[#include <string.h>]])
+AC_CHECK_DECLS_ONCE([[basename]], [], [], [[#include <string.h>]])
AC_MSG_CHECKING([whether _Static_assert() is supported])
AC_COMPILE_IFELSE(
}
#endif
-#if !HAVE_DECL_STRNDUPA
-#include <string.h>
-#define strndupa(s, n) \
- ({ \
- const char *__old = (s); \
- size_t __len = strnlen(__old, (n)); \
- char *__new = alloca(__len + 1); \
- __new[__len] = '\0'; \
- memcpy(__new, __old, __len); \
- })
-#endif
-
#if !HAVE_DECL_BASENAME
#include <string.h>
static inline const char *basename(const char *s)
int mkdir_p(const char *path, int len, mode_t mode)
{
- char *start, *end;
+ _cleanup_free_ char *start;
+ char *end;
- start = strndupa(path, len);
+ start = memdup(path, len + 1);
+ if (!start)
+ return -ENOMEM;
+
+ start[len] = '\0';
end = start + len;
/*