diff --git a/TODO.md b/TODO.md index 2dbb1af..88d3dc6 100644 --- a/TODO.md +++ b/TODO.md @@ -19,7 +19,7 @@ - [ ] Eight things eight, try it out! - maybe even write the python webhook extension. - [ ] Port this document to gitea issue tracking - [x] enable PATH-able programs and argv in the command section - - [ ] custom environment variable passing. Something like `-e MY_TOKEN` ala docker-style + - [x] custom environment variable passing. Something like `-e MY_TOKEN` ala docker-style - [x] address sanitizers please. - [ ] Ninth things ninth, fix bugs, see below - [ ] Tenth things tenth, write manpages, choose license diff --git a/include/executor.h b/include/executor.h index 7c42747..c32b8b7 100644 --- a/include/executor.h +++ b/include/executor.h @@ -1,7 +1,9 @@ #ifndef SCI_EXECUTOR_H #define SCI_EXECUTOR_H +#include "strlist.h" void executor(void* pipeline_event); void set_logdir(const char* logdir); +void set_shared_environment(const strlist_node* root); #endif diff --git a/include/util.h b/include/util.h index d85d8e2..5589305 100644 --- a/include/util.h +++ b/include/util.h @@ -40,6 +40,7 @@ typedef void(*line_handler)(const char*); void per_line(const char* file, line_handler handler); char* join(const char* a, const char* b); +char* join3(const char* a, const char* b, const char* c); const char* skip_arg(const char* cp); char* skip_spaces(const char* str); diff --git a/src/executor.c b/src/executor.c index 88324a8..b822ed1 100644 --- a/src/executor.c +++ b/src/executor.c @@ -2,6 +2,7 @@ #include "log.h" #include "optional.h" #include "pipeline.h" +#include "strlist.h" #include "util.h" #include #include @@ -13,6 +14,11 @@ #include const char* log_dir = "./"; // NOTE: must end with a / +const strlist_node* shared_environment = NULL; + +void set_shared_environment(const strlist_node* root) { + shared_environment = root; +} void set_logdir(const char* logdir) { log_dir = logdir; @@ -49,6 +55,38 @@ optional_int open_logfile(const char* const pipeline_id) { return result; } +void add_joined_str(strlist_node* root, const char* a, const char* b) { + char* tmp = join(a, b); + add_str(tmp, root); + free(tmp); +} + +void add_env(strlist_node* root, const char* env) { + char* tmp = join3(env, "=", getenv(env)); + add_str(tmp, root); + free(tmp); +} + +char** create_environment(const pipeline_event* const e, const char* pipeline_id) { + char* tmp = join("PATH=", getenv("PATH")); // TODO: consider removing PATH default, since it can be done as -e PATH + strlist_node* env = create_strlist_node(tmp); + free(tmp); + add_joined_str(env, "SCI_PIPELINE_NAME=", e->name); + add_joined_str(env, "SCI_PIPELINE_URL=", e->url); + add_joined_str(env, "SCI_PIPELINE_TRIGGER=", e->trigger); + add_joined_str(env, "SCI_PIPELINE_ID=", pipeline_id); + if(shared_environment != NULL) { + const strlist_node* cursor = shared_environment; + while(cursor != NULL) { + add_env(env, cursor->str); + cursor = cursor->next; + } + } + char** envp = strlist_to_array(env); + clear_strlist(env); + return envp; +} + void executor(void* data) { // Create pipeline id char* pipeline_id = create_pipeline_id(); @@ -67,12 +105,7 @@ void executor(void* data) { posix_spawn_file_actions_adddup2(&actions, fd.value, STDOUT_FILENO); posix_spawn_file_actions_adddup2(&actions, fd.value, STDERR_FILENO); const pipeline_event* const e = data; - char* path = join("PATH=", getenv("PATH")); - char* name = join("SCI_PIPELINE_NAME=", e->name); - char* url = join("SCI_PIPELINE_URL=", e->url); - char* trigger = join("SCI_PIPELINE_TRIGGER=", e->trigger); - char* id = join("SCI_PIPELINE_ID=", pipeline_id); - char* envp[] = { path, name, url, trigger, id, NULL }; + char** envp = create_environment(e, pipeline_id); int argc; char** argv = argv_split(e->command, &argc); log_trace("executing pipeline %s with argv:", e->name); @@ -98,9 +131,11 @@ end: argv_free(argv); close(fd.value); free(pipeline_id); - free(name); - free(url); - free(trigger); - free(id); free(data); + char** cursor = envp; + while(*cursor != NULL) { + free(*cursor); + cursor++; + } + free(envp); } diff --git a/src/main.c b/src/main.c index b726a2f..e0b41a6 100644 --- a/src/main.c +++ b/src/main.c @@ -110,6 +110,9 @@ int main(int argc, char** argv) { fprintf(stderr, "no such file or directory %s\n", args.config_file.value); exit(EXIT_FAILURE); } + + if(args.environment_vars.has_value) + set_shared_environment(args.environment_vars.value); pool = threadpool_create(args.executors); per_line(args.config_file.value, &config_interpret_line); diff --git a/src/strlist.c b/src/strlist.c index be27000..3f26f57 100644 --- a/src/strlist.c +++ b/src/strlist.c @@ -76,7 +76,8 @@ char** strlist_to_array(strlist_node* root) { if(len <= 0) return NULL; char** result = malloc(sizeof(char*) * (len + 1)); - memset(result, len+1, (size_t)NULL); + for(int i = 0; i < len+1; i++) + result[i] = NULL; strlist_node* cursor = root; for(int i = 0; i < len; i++) { if(cursor == NULL) diff --git a/src/util.c b/src/util.c index 1f8973a..6bd6085 100644 --- a/src/util.c +++ b/src/util.c @@ -63,6 +63,15 @@ char* join(const char* a, const char* b) { return result; } +char* join3(const char* a, const char* b, const char* c) { + size_t alen = strlen(a); + size_t blen = strlen(b); + size_t clen = strlen(c); + char* result = malloc(alen + blen + clen + 1); + sprintf(result, "%s%s%s", a, b, c); + return result; +} + const char* skip_arg(const char* cp) { while(*cp && !isspace(*cp)) cp++;