tree-wide: Fix constness issues with newer glibc (#39896)
Latest glibc uses _Generic to have strstr() and other functions return const char* or char* based on whether the input is a const char* or a char*. This causes build failures as we previously always expected a char*. Let's fix the compilation failures and add our own macros similar to glibc's to have string functions that return a mutable or const pointer depending on the input.
This commit is contained in:
@@ -163,9 +163,7 @@ int proc_cmdline_strv(char ***ret) {
|
||||
}
|
||||
|
||||
static char *mangle_word(const char *word, ProcCmdlineFlags flags) {
|
||||
char *c;
|
||||
|
||||
c = startswith(word, "rd.");
|
||||
char *c = (char*) startswith(word, "rd.");
|
||||
if (c) {
|
||||
/* Filter out arguments that are intended only for the initrd */
|
||||
|
||||
@@ -182,6 +180,8 @@ static char *mangle_word(const char *word, ProcCmdlineFlags flags) {
|
||||
return (char*) word;
|
||||
}
|
||||
|
||||
#define mangle_word(word, flags) const_generic(word, mangle_word(word, flags))
|
||||
|
||||
static int proc_cmdline_parse_strv(char **args, proc_cmdline_parse_t parse_item, void *data, ProcCmdlineFlags flags) {
|
||||
int r;
|
||||
|
||||
|
||||
@@ -1849,7 +1849,7 @@ int vsock_parse_cid(const char *s, unsigned *ret) {
|
||||
int socket_address_parse_vsock(SocketAddress *ret_address, const char *s) {
|
||||
/* AF_VSOCK socket in vsock:cid:port notation */
|
||||
_cleanup_free_ char *n = NULL;
|
||||
char *e, *cid_start;
|
||||
const char *e, *cid_start;
|
||||
unsigned port, cid;
|
||||
int type, r;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* bsearch_safe(const void *key, const void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
|
||||
void* bsearch_safe_internal(const void *key, const void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
|
||||
/**
|
||||
* Normal bsearch requires base to be nonnull. Here were require
|
||||
* that only if nmemb > 0.
|
||||
@@ -40,7 +40,7 @@ void* bsearch_safe(const void *key, const void *base, size_t nmemb, size_t size,
|
||||
return NULL;
|
||||
|
||||
assert(base);
|
||||
return bsearch(key, base, nmemb, size, compar);
|
||||
return (void*) bsearch(key, base, nmemb, size, compar);
|
||||
}
|
||||
|
||||
void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
|
||||
|
||||
@@ -13,7 +13,9 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
||||
(typeof((b)[0])*) xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_userdata_fn_t) _func_, userdata); \
|
||||
})
|
||||
|
||||
void* bsearch_safe(const void *key, const void *base, size_t nmemb, size_t size, comparison_fn_t compar);
|
||||
void* bsearch_safe_internal(const void *key, const void *base, size_t nmemb, size_t size, comparison_fn_t compar);
|
||||
#define bsearch_safe(key, base, nmemb, size, compar) \
|
||||
const_generic((base), bsearch_safe_internal(key, base, nmemb, size, compar))
|
||||
|
||||
#define typesafe_bsearch(k, b, n, func) \
|
||||
({ \
|
||||
|
||||
+8
-14
@@ -1348,16 +1348,14 @@ char* strdupcspn(const char *a, const char *reject) {
|
||||
return strndup(a, strcspn(a, reject));
|
||||
}
|
||||
|
||||
char* find_line_startswith(const char *haystack, const char *needle) {
|
||||
char *p;
|
||||
|
||||
char* find_line_startswith_internal(const char *haystack, const char *needle) {
|
||||
assert(haystack);
|
||||
assert(needle);
|
||||
|
||||
/* Finds the first line in 'haystack' that starts with the specified string. Returns a pointer to the
|
||||
* first character after it */
|
||||
|
||||
p = strstr(haystack, needle);
|
||||
char *p = (char*) strstr(haystack, needle);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
@@ -1371,16 +1369,14 @@ char* find_line_startswith(const char *haystack, const char *needle) {
|
||||
return p + strlen(needle);
|
||||
}
|
||||
|
||||
char* find_line(const char *haystack, const char *needle) {
|
||||
char *p;
|
||||
|
||||
char* find_line_internal(const char *haystack, const char *needle) {
|
||||
assert(haystack);
|
||||
assert(needle);
|
||||
|
||||
/* Finds the first line in 'haystack' that match the specified string. Returns a pointer to the
|
||||
* beginning of the line */
|
||||
|
||||
p = find_line_startswith(haystack, needle);
|
||||
char *p = (char*) find_line_startswith(haystack, needle);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
@@ -1390,16 +1386,14 @@ char* find_line(const char *haystack, const char *needle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* find_line_after(const char *haystack, const char *needle) {
|
||||
char *p;
|
||||
|
||||
char* find_line_after_internal(const char *haystack, const char *needle) {
|
||||
assert(haystack);
|
||||
assert(needle);
|
||||
|
||||
/* Finds the first line in 'haystack' that match the specified string. Returns a pointer to the
|
||||
* next line after it */
|
||||
|
||||
p = find_line_startswith(haystack, needle);
|
||||
char *p = (char*) find_line_startswith(haystack, needle);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
@@ -1499,7 +1493,7 @@ ssize_t strlevenshtein(const char *x, const char *y) {
|
||||
return t1[yl];
|
||||
}
|
||||
|
||||
char* strrstr(const char *haystack, const char *needle) {
|
||||
char* strrstr_internal(const char *haystack, const char *needle) {
|
||||
/* Like strstr() but returns the last rather than the first occurrence of "needle" in "haystack". */
|
||||
|
||||
if (!haystack || !needle)
|
||||
@@ -1508,7 +1502,7 @@ char* strrstr(const char *haystack, const char *needle) {
|
||||
/* Special case: for the empty string we return the very last possible occurrence, i.e. *after* the
|
||||
* last char, not before. */
|
||||
if (*needle == 0)
|
||||
return strchr(haystack, 0);
|
||||
return (char*) strchr(haystack, 0);
|
||||
|
||||
for (const char *p = strstr(haystack, needle), *q; p; p = q) {
|
||||
q = strstr(p + 1, needle);
|
||||
|
||||
+23
-9
@@ -7,24 +7,28 @@
|
||||
#include "basic-forward.h"
|
||||
#include "string-util-fundamental.h" /* IWYU pragma: export */
|
||||
|
||||
static inline char* strstr_ptr(const char *haystack, const char *needle) {
|
||||
static inline char* strstr_ptr_internal(const char *haystack, const char *needle) {
|
||||
if (!haystack || !needle)
|
||||
return NULL;
|
||||
return strstr(haystack, needle);
|
||||
return (char*) strstr(haystack, needle);
|
||||
}
|
||||
|
||||
static inline char* strstrafter(const char *haystack, const char *needle) {
|
||||
char *p;
|
||||
#define strstr_ptr(haystack, needle) \
|
||||
const_generic(haystack, strstr_ptr_internal(haystack, needle))
|
||||
|
||||
static inline char* strstrafter_internal(const char *haystack, const char *needle) {
|
||||
/* Returns NULL if not found, or pointer to first character after needle if found */
|
||||
|
||||
p = strstr_ptr(haystack, needle);
|
||||
char *p = (char*) strstr_ptr(haystack, needle);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
return p + strlen(needle);
|
||||
}
|
||||
|
||||
#define strstrafter(haystack, needle) \
|
||||
const_generic(haystack, strstrafter_internal(haystack, needle))
|
||||
|
||||
static inline const char* strnull(const char *s) {
|
||||
return s ?: "(null)";
|
||||
}
|
||||
@@ -287,15 +291,25 @@ char* strdupcspn(const char *a, const char *reject);
|
||||
(char*) memdupa_suffix0(_t, strnlen(_t, n)); \
|
||||
})
|
||||
|
||||
char* find_line_startswith(const char *haystack, const char *needle);
|
||||
char* find_line(const char *haystack, const char *needle);
|
||||
char* find_line_after(const char *haystack, const char *needle);
|
||||
char* find_line_startswith_internal(const char *haystack, const char *needle);
|
||||
#define find_line_startswith(haystack, needle) \
|
||||
const_generic(haystack, find_line_startswith_internal(haystack, needle))
|
||||
|
||||
char* find_line_internal(const char *haystack, const char *needle);
|
||||
#define find_line(haystack, needle) \
|
||||
const_generic(haystack, find_line_internal(haystack, needle))
|
||||
|
||||
char* find_line_after_internal(const char *haystack, const char *needle);
|
||||
#define find_line_after(haystack, needle) \
|
||||
const_generic(haystack, find_line_after_internal(haystack, needle))
|
||||
|
||||
bool version_is_valid(const char *s) _pure_;
|
||||
bool version_is_valid_versionspec(const char *s) _pure_;
|
||||
|
||||
ssize_t strlevenshtein(const char *x, const char *y);
|
||||
|
||||
char* strrstr(const char *haystack, const char *needle) _pure_;
|
||||
char* strrstr_internal(const char *haystack, const char *needle) _pure_;
|
||||
#define strrstr(haystack, needle) \
|
||||
const_generic(haystack, strrstr_internal(haystack, needle))
|
||||
|
||||
size_t str_common_prefix(const char *a, const char *b) _pure_;
|
||||
|
||||
+4
-4
@@ -933,9 +933,9 @@ int strv_extend_joined_with_size_sentinel(char ***l, size_t *n, ...) {
|
||||
return strv_consume_with_size(l, n, x);
|
||||
}
|
||||
|
||||
char* startswith_strv(const char *s, char * const *l) {
|
||||
char* startswith_strv_internal(const char *s, char * const *l) {
|
||||
STRV_FOREACH(i, l) {
|
||||
char *found = startswith(s, *i);
|
||||
char *found = (char*) startswith(s, *i);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
@@ -943,9 +943,9 @@ char* startswith_strv(const char *s, char * const *l) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* endswith_strv(const char *s, char * const *l) {
|
||||
char* endswith_strv_internal(const char *s, char * const *l) {
|
||||
STRV_FOREACH(i, l) {
|
||||
char *found = endswith(s, *i);
|
||||
char *found = (char*) endswith(s, *i);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
|
||||
+4
-2
@@ -155,12 +155,14 @@ static inline void strv_print(char * const *l) {
|
||||
strv_print_full(l, NULL);
|
||||
}
|
||||
|
||||
char* startswith_strv(const char *s, char * const *l);
|
||||
char* startswith_strv_internal(const char *s, char * const *l);
|
||||
#define startswith_strv(s, l) const_generic(s, startswith_strv_internal(s, l))
|
||||
|
||||
#define STARTSWITH_SET(p, ...) \
|
||||
startswith_strv(p, STRV_MAKE(__VA_ARGS__))
|
||||
|
||||
char* endswith_strv(const char *s, char * const *l);
|
||||
char* endswith_strv_internal(const char *s, char * const *l);
|
||||
#define endswith_strv(s, l) const_generic(s, endswith_strv_internal(s, l))
|
||||
|
||||
#define ENDSWITH_SET(p, ...) \
|
||||
endswith_strv(p, STRV_MAKE(__VA_ARGS__))
|
||||
|
||||
@@ -1156,9 +1156,7 @@ static const char* extract_multiplier(const char *p, usec_t *ret) {
|
||||
assert(ret);
|
||||
|
||||
FOREACH_ELEMENT(i, table) {
|
||||
char *e;
|
||||
|
||||
e = startswith(p, i->suffix);
|
||||
const char *e = startswith(p, i->suffix);
|
||||
if (e) {
|
||||
*ret = i->usec;
|
||||
return e;
|
||||
@@ -1334,9 +1332,7 @@ static const char* extract_nsec_multiplier(const char *p, nsec_t *ret) {
|
||||
assert(ret);
|
||||
|
||||
FOREACH_ELEMENT(i, table) {
|
||||
char *e;
|
||||
|
||||
e = startswith(p, i->suffix);
|
||||
const char *e = startswith(p, i->suffix);
|
||||
if (e) {
|
||||
*ret = i->nsec;
|
||||
return e;
|
||||
|
||||
@@ -213,7 +213,7 @@ UnitType unit_name_to_type(const char *n) {
|
||||
int unit_name_change_suffix(const char *n, const char *suffix, char **ret) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
size_t a, b;
|
||||
char *e;
|
||||
const char *e;
|
||||
|
||||
assert(n);
|
||||
assert(suffix);
|
||||
@@ -521,7 +521,7 @@ int unit_name_template(const char *f, char **ret) {
|
||||
}
|
||||
|
||||
bool unit_name_is_hashed(const char *name) {
|
||||
char *s;
|
||||
const char *s;
|
||||
|
||||
if (!unit_name_is_valid(name, UNIT_NAME_PLAIN))
|
||||
return false;
|
||||
@@ -544,7 +544,7 @@ bool unit_name_is_hashed(const char *name) {
|
||||
|
||||
int unit_name_hash_long(const char *name, char **ret) {
|
||||
_cleanup_free_ char *n = NULL, *hash = NULL;
|
||||
char *suffix;
|
||||
const char *suffix;
|
||||
le64_t h;
|
||||
size_t len;
|
||||
|
||||
@@ -834,7 +834,7 @@ int slice_build_subslice(const char *slice, const char *name, char **ret) {
|
||||
if (streq(slice, SPECIAL_ROOT_SLICE))
|
||||
subslice = strjoin(name, ".slice");
|
||||
else {
|
||||
char *e;
|
||||
const char *e;
|
||||
|
||||
assert_se(e = endswith(slice, ".slice"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user