config: add a new ‘environment’ section

This section allows the user to define custom environment variables to
be set in the child process:

  [environment]
  name=value
This commit is contained in:
Daniel Eklöf 2022-05-28 19:27:29 +02:00
parent 497c31d9fc
commit 755f96321a
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 63 additions and 4 deletions

View file

@ -2200,6 +2200,29 @@ err:
return false; return false;
} }
static bool
parse_section_environment(struct context *ctx)
{
struct config *conf = ctx->conf;
const char *key = ctx->key;
const char *value = ctx->value;
tll_foreach(conf->env_vars, it) {
if (strcmp(it->item.name, key) == 0) {
free(it->item.value);
it->item.value = xstrdup(value);
return true;
}
}
struct env_var var = {
.name = xstrdup(key),
.value = xstrdup(value),
};
tll_push_back(conf->env_vars, var);
return true;
}
static bool static bool
parse_section_tweak(struct context *ctx) parse_section_tweak(struct context *ctx)
{ {
@ -2403,6 +2426,7 @@ enum section {
SECTION_URL_BINDINGS, SECTION_URL_BINDINGS,
SECTION_MOUSE_BINDINGS, SECTION_MOUSE_BINDINGS,
SECTION_TEXT_BINDINGS, SECTION_TEXT_BINDINGS,
SECTION_ENVIRONMENT,
SECTION_TWEAK, SECTION_TWEAK,
SECTION_COUNT, SECTION_COUNT,
}; };
@ -2427,6 +2451,7 @@ static const struct {
[SECTION_URL_BINDINGS] = {&parse_section_url_bindings, "url-bindings"}, [SECTION_URL_BINDINGS] = {&parse_section_url_bindings, "url-bindings"},
[SECTION_MOUSE_BINDINGS] = {&parse_section_mouse_bindings, "mouse-bindings"}, [SECTION_MOUSE_BINDINGS] = {&parse_section_mouse_bindings, "mouse-bindings"},
[SECTION_TEXT_BINDINGS] = {&parse_section_text_bindings, "text-bindings"}, [SECTION_TEXT_BINDINGS] = {&parse_section_text_bindings, "text-bindings"},
[SECTION_ENVIRONMENT] = {&parse_section_environment, "environment"},
[SECTION_TWEAK] = {&parse_section_tweak, "tweak"}, [SECTION_TWEAK] = {&parse_section_tweak, "tweak"},
}; };
@ -2867,6 +2892,7 @@ config_load(struct config *conf, const char *conf_path,
.sixel = true, .sixel = true,
}, },
.env_vars = tll_init(),
.notifications = tll_init(), .notifications = tll_init(),
}; };
@ -3147,6 +3173,14 @@ config_clone(const struct config *old)
key_binding_list_clone(&conf->bindings.url, &old->bindings.url); key_binding_list_clone(&conf->bindings.url, &old->bindings.url);
key_binding_list_clone(&conf->bindings.mouse, &old->bindings.mouse); key_binding_list_clone(&conf->bindings.mouse, &old->bindings.mouse);
tll_foreach(old->env_vars, it) {
struct env_var copy = {
.name = xstrdup(it->item.name),
.value = xstrdup(it->item.value),
};
tll_push_back(conf->env_vars, copy);
}
conf->notifications.length = 0; conf->notifications.length = 0;
conf->notifications.head = conf->notifications.tail = 0; conf->notifications.head = conf->notifications.tail = 0;
tll_foreach(old->notifications, it) { tll_foreach(old->notifications, it) {
@ -3207,6 +3241,12 @@ config_free(struct config *conf)
free_key_binding_list(&conf->bindings.url); free_key_binding_list(&conf->bindings.url);
free_key_binding_list(&conf->bindings.mouse); free_key_binding_list(&conf->bindings.mouse);
tll_foreach(conf->env_vars, it) {
free(it->item.name);
free(it->item.value);
tll_remove(conf->env_vars, it);
}
user_notifications_free(&conf->notifications); user_notifications_free(&conf->notifications);
} }

View file

@ -104,6 +104,12 @@ struct config_spawn_template {
struct argv argv; struct argv argv;
}; };
struct env_var {
char *name;
char *value;
};
typedef tll(struct env_var) env_var_list_t;
struct config { struct config {
char *term; char *term;
char *shell; char *shell;
@ -296,6 +302,8 @@ struct config {
struct config_spawn_template notify; struct config_spawn_template notify;
bool notify_focus_inhibit; bool notify_focus_inhibit;
env_var_list_t env_vars;
struct { struct {
enum fcft_scaling_filter fcft_filter; enum fcft_scaling_filter fcft_filter;
bool overflowing_glyphs; bool overflowing_glyphs;

View file

@ -33,6 +33,9 @@
# selection-target=primary # selection-target=primary
# workers=<number of logical CPUs> # workers=<number of logical CPUs>
[environment]
# name=value
[bell] [bell]
# urgent=no # urgent=no
# notify=no # notify=no

10
slave.c
View file

@ -305,8 +305,9 @@ err:
pid_t pid_t
slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv, slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
char *const *envp, const char *term_env, const char *conf_shell, char *const *envp, const env_var_list_t *extra_env_vars,
bool login_shell, const user_notifications_t *notifications) const char *term_env, const char *conf_shell, bool login_shell,
const user_notifications_t *notifications)
{ {
int fork_pipe[2]; int fork_pipe[2];
if (pipe2(fork_pipe, O_CLOEXEC) < 0) { if (pipe2(fork_pipe, O_CLOEXEC) < 0) {
@ -356,6 +357,11 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
setenv("TERMINFO", FOOT_TERMINFO_PATH, 1); setenv("TERMINFO", FOOT_TERMINFO_PATH, 1);
#endif #endif
if (extra_env_vars != NULL) {
tll_foreach(*extra_env_vars, it)
setenv(it->item.name, it->item.value, 1);
}
char **_shell_argv = NULL; char **_shell_argv = NULL;
char **shell_argv = NULL; char **shell_argv = NULL;

View file

@ -3,9 +3,11 @@
#include <sys/types.h> #include <sys/types.h>
#include "config.h"
#include "user-notification.h" #include "user-notification.h"
pid_t slave_spawn( pid_t slave_spawn(
int ptmx, int argc, const char *cwd, char *const *argv, char *const *envp, int ptmx, int argc, const char *cwd, char *const *argv, char *const *envp,
const char *term_env, const char *conf_shell, bool login_shell, const env_var_list_t *extra_env_vars, const char *term_env,
const char *conf_shell, bool login_shell,
const user_notifications_t *notifications); const user_notifications_t *notifications);

View file

@ -1248,7 +1248,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
/* Start the slave/client */ /* Start the slave/client */
if ((term->slave = slave_spawn( if ((term->slave = slave_spawn(
term->ptmx, argc, term->cwd, argv, envp, term->ptmx, argc, term->cwd, argv, envp, &conf->env_vars,
conf->term, conf->shell, conf->login_shell, conf->term, conf->shell, conf->login_shell,
&conf->notifications)) == -1) &conf->notifications)) == -1)
{ {