From: Michael Tremer Date: Tue, 2 Aug 2022 08:50:48 +0000 (+0000) Subject: jail: Implement setting environment variables X-Git-Tag: 0.9.28~645 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32d5f21d039eb2b3e46c90ad33f38beb9963e5c8;p=pakfire.git jail: Implement setting environment variables Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/jail.h b/src/libpakfire/include/pakfire/jail.h index d2c45dc49..dc6772be0 100644 --- a/src/libpakfire/include/pakfire/jail.h +++ b/src/libpakfire/include/pakfire/jail.h @@ -32,6 +32,10 @@ int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire); struct pakfire_jail* pakfire_jail_ref(struct pakfire_jail* jail); struct pakfire_jail* pakfire_jail_unref(struct pakfire_jail* jail); +// Environment +const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key); +int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value); + #endif #endif /* PAKFIRE_JAIL_H */ diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index fdadc50ea..8ac6c3287 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -18,13 +18,22 @@ # # #############################################################################*/ +#include +#include + #include #include #include +#include + +#define ENVIRON_SIZE 128 struct pakfire_jail { struct pakfire* pakfire; int nrefs; + + // Environment + char* env[ENVIRON_SIZE]; }; int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) { @@ -48,6 +57,10 @@ int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) { static void pakfire_jail_free(struct pakfire_jail* jail) { DEBUG(jail->pakfire, "Freeing jail at %p\n", jail); + // Free environment + for (unsigned int i = 0; jail->env[i]; i++) + free(jail->env[i]); + pakfire_unref(jail->pakfire); free(jail); } @@ -65,3 +78,69 @@ struct pakfire_jail* pakfire_jail_unref(struct pakfire_jail* jail) { pakfire_jail_free(jail); return NULL; } + +// Environment + +// Returns the length of the environment +static unsigned int pakfire_jail_env_length(struct pakfire_jail* jail) { + unsigned int i = 0; + + // Count everything in the environment + for (char** e = jail->env; *e; e++) + i++; + + return i; +} + +// Finds an existing environment variable and returns its index or -1 if not found +static int pakfire_jail_find_env(struct pakfire_jail* jail, const char* key) { + if (!key) { + errno = EINVAL; + return -1; + } + + char buffer[strlen(key) + 2]; + pakfire_string_format(buffer, "%s=", key); + + for (unsigned int i = 0; jail->env[i]; i++) { + if (pakfire_string_startswith(jail->env[i], buffer)) + return i; + } + + // Nothing found + return -1; +} + +// Returns the value of an environment variable or NULL +const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key) { + int i = pakfire_jail_find_env(jail, key); + if (i < 0) + return NULL; + + return jail->env[i] + strlen(key) + 1; +} + +// Sets an environment variable +int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value) { + // Find the index where to write this value to + int i = pakfire_jail_find_env(jail, key); + if (i < 0) + i = pakfire_jail_env_length(jail); + + // Return -ENOSPC when the environment is full + if (i >= ENVIRON_SIZE) { + errno = ENOSPC; + return -1; + } + + // Free any previous value + if (jail->env[i]) + free(jail->env[i]); + + // Format and set environment variable + asprintf(&jail->env[i], "%s=%s", key, value); + + DEBUG(jail->pakfire, "Set environment variable: %s\n", jail->env[i]); + + return 0; +} diff --git a/tests/libpakfire/jail.c b/tests/libpakfire/jail.c index d75c5c848..af8c42ba5 100644 --- a/tests/libpakfire/jail.c +++ b/tests/libpakfire/jail.c @@ -41,8 +41,34 @@ FAIL: return EXIT_FAILURE; } +static int test_env(const struct test* t) { + struct pakfire_jail* jail = NULL; + + // Create a new jail + ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire)); + + // Fetch a non-existing environment variable + ASSERT_NULL(pakfire_jail_get_env(jail, "VARIABLE")); + + // Set a variable + ASSERT_SUCCESS(pakfire_jail_set_env(jail, "VARIABLE", "VALUE")); + + // Read the value back + ASSERT_STRING_EQUALS(pakfire_jail_get_env(jail, "VARIABLE"), "VALUE"); + + // Destroy it + ASSERT_NULL(pakfire_jail_unref(jail)); + + return EXIT_SUCCESS; + +FAIL: + return EXIT_FAILURE; +} + + int main(int argc, char** argv) { testsuite_add_test(test_create); + testsuite_add_test(test_env); return testsuite_run(); }