]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Implement setting environment variables
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 08:50:48 +0000 (08:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 08:50:48 +0000 (08:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/jail.h
src/libpakfire/jail.c
tests/libpakfire/jail.c

index d2c45dc49e7363ad1f1268a072bb57498376f8d9..dc6772be006e3b5c0a14e205b8db28bb05032e47 100644 (file)
@@ -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 */
index fdadc50eaee76d15bc41872792ae962b8b7f36af..8ac6c3287367b3c9057a0c91904ba5aa94acf026 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <errno.h>
+#include <stdlib.h>
+
 #include <pakfire/logging.h>
 #include <pakfire/jail.h>
 #include <pakfire/pakfire.h>
+#include <pakfire/util.h>
+
+#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;
+}
index d75c5c848eefdeb7e2e7dfc36b31652367d9352f..af8c42ba5a01b111a5cf3adb99adbb830d093f5a 100644 (file)
@@ -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();
 }