]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/string_utils.h
github: Update for main branch
[mirror_lxc.git] / src / lxc / string_utils.h
CommitLineData
cc73685d 1/* SPDX-License-Identifier: LGPL-2.1+ */
37ef15bb
CB
2
3#ifndef __LXC_STRING_UTILS_H
4#define __LXC_STRING_UTILS_H
5
6#include "config.h"
7
1160ce89
CB
8#include <stdarg.h>
9
37ef15bb
CB
10#include "initutils.h"
11#include "macro.h"
12
db4af8c5 13#if !HAVE_STRLCAT
58db1a61 14#include "strlcat.h"
a08bfbe3
CB
15#endif
16
db4af8c5 17#if !HAVE_STRLCPY
58db1a61 18#include "strlcpy.h"
646b75b5
CB
19#endif
20
db4af8c5 21#if !HAVE_STRCHRNUL
58db1a61 22#include "strchrnul.h"
88cf3229
CB
23#endif
24
37ef15bb 25/* convert variadic argument lists to arrays (for execl type argument lists) */
99bf8f21
CB
26__hidden extern char **lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup);
27__hidden extern const char **lxc_va_arg_list_to_argv_const(va_list ap, size_t skip);
37ef15bb
CB
28
29/*
30 * Some simple string functions; if they return pointers, they are allocated
31 * buffers.
32 */
99bf8f21
CB
33__hidden extern char *lxc_string_replace(const char *needle, const char *replacement,
34 const char *haystack);
35__hidden extern bool lxc_string_in_array(const char *needle, const char **haystack);
36__hidden extern char *lxc_string_join(const char *sep, const char **parts, bool use_as_prefix);
37ef15bb 37
99bf8f21 38__hidden extern char *lxc_append_paths(const char *first, const char *second);
37ef15bb
CB
39
40/*
41 * Note: the following two functions use strtok(), so they will never
42 * consider an empty element, even if two delimiters are next to
43 * each other.
44 */
99bf8f21
CB
45__hidden extern bool lxc_string_in_list(const char *needle, const char *haystack, char sep);
46__hidden extern char **lxc_string_split(const char *string, char sep);
47__hidden extern char **lxc_string_split_and_trim(const char *string, char sep);
48__hidden extern char **lxc_string_split_quoted(char *string);
37ef15bb
CB
49
50/* Append string to NULL-terminated string array. */
99bf8f21 51__hidden extern int lxc_append_string(char ***list, char *entry);
37ef15bb
CB
52
53/* Some simple array manipulation utilities */
54typedef void (*lxc_free_fn)(void *);
55typedef void *(*lxc_dup_fn)(void *);
99bf8f21
CB
56__hidden extern int lxc_grow_array(void ***array, size_t *capacity, size_t new_size,
57 size_t capacity_increment);
58__hidden extern void lxc_free_array(void **array, lxc_free_fn element_free_fn);
59__hidden extern size_t lxc_array_len(void **array);
37ef15bb 60
99bf8f21
CB
61__hidden extern void **lxc_append_null_to_array(void **array, size_t count);
62__hidden extern void remove_trailing_newlines(char *l);
37ef15bb
CB
63
64/* Helper functions to parse numbers. */
99bf8f21
CB
65__hidden extern int lxc_safe_uint(const char *numstr, unsigned int *converted);
66__hidden extern int lxc_safe_int(const char *numstr, int *converted);
67__hidden extern int lxc_safe_long(const char *numstr, long int *converted);
68__hidden extern int lxc_safe_long_long(const char *numstr, long long int *converted);
69__hidden extern int lxc_safe_ulong(const char *numstr, unsigned long *converted);
70__hidden extern int lxc_safe_uint64(const char *numstr, uint64_t *converted, int base);
59f5a103
CB
71__hidden extern int lxc_safe_int64_residual(const char *restrict numstr,
72 int64_t *restrict converted,
73 int base, char *restrict residual,
74 size_t residual_len);
37ef15bb 75/* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */
4c5479d2 76__hidden extern int parse_byte_size_string(const char *s, long long int *converted);
37ef15bb
CB
77
78/*
79 * Concatenate all passed-in strings into one path. Do not fail. If any piece
80 * is not prefixed with '/', add a '/'.
81 */
99bf8f21
CB
82__hidden __attribute__((sentinel)) extern char *must_concat(size_t *len, const char *first, ...);
83__hidden __attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
84__hidden __attribute__((sentinel)) extern char *must_append_path(char *first, ...);
37ef15bb 85
9cde8a8a
CB
86#define must_make_path_relative(__first__, ...) \
87 ({ \
88 char *__ptr__; \
89 if (*__first__ == '/') \
90 __ptr__ = must_make_path(".", __first__, __VA_ARGS__); \
91 else \
92 __ptr__ = must_make_path(__first__, __VA_ARGS__); \
93 __ptr__; \
94 })
95
37ef15bb 96/* Return copy of string @entry. Do not fail. */
99bf8f21 97__hidden extern char *must_copy_string(const char *entry);
37ef15bb 98
54d423b8 99/* Re-allocate a pointer, do not fail */
99bf8f21 100__hidden extern void *must_realloc(void *orig, size_t sz);
37ef15bb 101
99bf8f21 102__hidden extern int lxc_char_left_gc(const char *buffer, size_t len);
37ef15bb 103
99bf8f21 104__hidden extern int lxc_char_right_gc(const char *buffer, size_t len);
37ef15bb 105
99bf8f21 106__hidden extern char *lxc_trim_whitespace_in_place(char *buffer);
37ef15bb 107
99bf8f21
CB
108__hidden extern int lxc_is_line_empty(const char *line);
109__hidden extern void remove_trailing_slashes(char *p);
37ef15bb 110
3473ca76
CB
111static inline bool is_empty_string(const char *s)
112{
113 return !s || strcmp(s, "") == 0;
114}
115
02efd041
CB
116#define maybe_empty(s) ((!is_empty_string(s)) ? (s) : ("(null)"))
117
a08bfbe3
CB
118static inline ssize_t safe_strlcat(char *src, const char *append, size_t len)
119{
120 size_t new_len;
121
122 new_len = strlcat(src, append, len);
123 if (new_len >= len)
124 return ret_errno(EINVAL);
125
126 return (ssize_t)new_len;
127}
128
78522aa9
CB
129static inline bool strnequal(const char *str, const char *eq, size_t len)
130{
131 return strncmp(str, eq, len) == 0;
132}
133
134static inline bool strequal(const char *str, const char *eq)
135{
136 return strcmp(str, eq) == 0;
137}
138
0a48ee66
CB
139static inline bool dotdot(const char *str)
140{
141 return !!strstr(str, "..");
142}
143
f63ef155
CB
144static inline bool abspath(const char *str)
145{
146 return *str == '/';
147}
148
600a0163
CB
149static inline char *deabs(char *str)
150{
151 return str + strspn(str, "/");
152}
153
a5e92f5d
CB
154#define strnprintf(buf, buf_size, ...) \
155 ({ \
156 int __ret_strnprintf; \
157 __ret_strnprintf = snprintf(buf, buf_size, ##__VA_ARGS__); \
158 if (__ret_strnprintf < 0 || (size_t)__ret_strnprintf >= (size_t)buf_size) \
159 __ret_strnprintf = ret_errno(EIO); \
160 __ret_strnprintf; \
66efb199
CB
161 })
162
4b7686ea
CB
163static inline const char *proc_self_fd(int fd)
164{
165 static const char *invalid_fd_path = "/proc/self/fd/-EBADF";
166 static char buf[LXC_PROC_SELF_FD_LEN] = "/proc/self/fd/";
167
168 if (strnprintf(buf + STRLITERALLEN("/proc/self/fd/"),
169 INTTYPE_TO_STRLEN(int), "%d", fd) < 0)
170 return invalid_fd_path;
171
172 return buf;
173}
174
289b707b 175static inline const char *fdstr(__s64 fd)
74f46388
CB
176{
177 static const char *fdstr_invalid = "-EBADF";
289b707b 178 static char buf[INTTYPE_TO_STRLEN(__s64)];
74f46388 179
e39f3333 180 if (strnprintf(buf, sizeof(buf), "%lld", (long long signed int)fd) < 0)
74f46388
CB
181 return fdstr_invalid;
182
183 return buf;
184}
185
d9be3d26
CB
186#define lxc_iterate_parts(__iterator, __splitme, __separators) \
187 for (char *__p = NULL, *__it = strtok_r(__splitme, __separators, &__p); \
188 (__iterator = __it); \
189 __iterator = __it = strtok_r(NULL, __separators, &__p))
190
539c3977 191__hidden extern char *lxc_path_simplify(const char *path);
28e54be1 192
37ef15bb 193#endif /* __LXC_STRING_UTILS_H */