summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2025-02-10 17:26:59 -0500
committerDavid Robillard <d@drobilla.net>2025-02-10 17:26:59 -0500
commit8348512a60399d172fc83cd7bdf121d4c0b1015e (patch)
treebcee65f2632c0bfd0659b3b7b77e1d4954268e2d /src
parentcdc8eb7ad393c049d3fdf520c6fd1475d33c3a73 (diff)
downloadzix-8348512a60399d172fc83cd7bdf121d4c0b1015e.tar.gz
zix-8348512a60399d172fc83cd7bdf121d4c0b1015e.tar.bz2
zix-8348512a60399d172fc83cd7bdf121d4c0b1015e.zip
Use getenv() instead of environ to avoid issues on FreeBSD
Diffstat (limited to 'src')
-rw-r--r--src/posix/environment_posix.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/src/posix/environment_posix.c b/src/posix/environment_posix.c
index 58b8fd2..0dd9358 100644
--- a/src/posix/environment_posix.c
+++ b/src/posix/environment_posix.c
@@ -4,14 +4,11 @@
#include <zix/environment.h>
#include <zix/allocator.h>
-#include <zix/string_view.h>
#include <stdbool.h>
+#include <stdlib.h>
#include <string.h>
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-extern char** environ;
-
static bool
is_path_delim(const char c)
{
@@ -24,27 +21,6 @@ is_var_name_char(const char c)
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
}
-static const char*
-find_env(const ZixStringView name)
-{
- if (environ) {
- for (size_t i = 0U; environ[i]; ++i) {
- // Find the first character in this entry that doesn't match the name
- const char* const entry = environ[i];
- size_t j = 0U;
- while (j < name.length && entry[j] == name.data[j]) {
- ++j;
- }
-
- if (j == name.length && entry[j] == '=') {
- return entry + j + 1U;
- }
- }
- }
-
- return NULL;
-}
-
// Append suffix to dst, update dst_len, and return the realloc'd result
static char*
append_str(ZixAllocator* const allocator,
@@ -65,7 +41,7 @@ append_str(ZixAllocator* const allocator,
return out;
}
-// Append the value of the environment variable var to dst if one is set
+// Append the value of an environment variable to dst if it's set
static char*
append_var(ZixAllocator* const allocator,
size_t* const dst_len,
@@ -74,8 +50,7 @@ append_var(ZixAllocator* const allocator,
const char* const ref)
{
// Get value from environment
- const ZixStringView var = zix_substring(ref + 1U, ref_len - 1U);
- const char* val = find_env(var);
+ const char* const val = getenv(ref + 1U); // NOLINT(concurrency-mt-unsafe)
if (val) {
return append_str(allocator, dst_len, dst, strlen(val), val);
}
@@ -84,12 +59,32 @@ append_var(ZixAllocator* const allocator,
return append_str(allocator, dst_len, dst, ref_len, ref);
}
+// Copy a variable reference string like $NAME to a null-termianted string
+static char*
+set_ref(ZixAllocator* const allocator,
+ char** const buffer,
+ const size_t ref_len,
+ const char* const ref)
+{
+ char* const out = (char*)zix_realloc(allocator, *buffer, ref_len + 1U);
+
+ if (out) {
+ memcpy(out, ref, ref_len);
+ out[ref_len] = '\0';
+ } else {
+ zix_free(allocator, *buffer);
+ }
+
+ return out;
+}
+
char*
zix_expand_environment_strings(ZixAllocator* const allocator,
const char* const string)
{
- char* out = NULL;
- size_t len = 0U;
+ char* ref = NULL; // Reference string like $NAME
+ char* out = NULL; // Expanded result
+ size_t len = 0U; // Length of expanded result
size_t start = 0U; // Start of current chunk to copy
for (size_t s = 0U; string[s];) {
@@ -102,7 +97,9 @@ zix_expand_environment_strings(ZixAllocator* const allocator,
const size_t prefix_len = s - start;
if ((prefix_len &&
!(out = append_str(allocator, &len, out, prefix_len, prefix))) ||
- !(out = append_var(allocator, &len, out, t, string + s))) {
+ !(ref = set_ref(allocator, &ref, t, string + s)) ||
+ !(out = append_var(allocator, &len, out, t, ref))) {
+ zix_free(allocator, ref);
return NULL;
}
start = s = t;
@@ -116,6 +113,7 @@ zix_expand_environment_strings(ZixAllocator* const allocator,
if ((prefix_len &&
!(out = append_str(allocator, &len, out, prefix_len, prefix))) ||
!(out = append_var(allocator, &len, out, 5U, "$HOME"))) {
+ zix_free(allocator, ref);
return NULL;
}
start = ++s;
@@ -130,5 +128,6 @@ zix_expand_environment_strings(ZixAllocator* const allocator,
out = append_str(allocator, &len, out, tail_len, tail);
}
+ zix_free(allocator, ref);
return out;
}