Skip to content

Commit dd82a8e

Browse files
committed
commands: Add export command
The `export` command allows one to set environment variables easily within their configuration. It additionally allows one to get an environment variable using the `$ENV:<name>` syntax. With the configuration snippet listed below, which MUST appear before any `exec` commands -- so that environment variables are all available to these newly launched programs -- set a number of variables used by GTK & Qt for forcing Wayland rendering. ``` export GDK_BACKEND wayland export CLUTTER_BACKEND wayland export MOZ_ENABLE_WAYLAND 1 export QT_QPA_PLATFORM wayland-egl export QT_WAYLAND_DISABLE_WINDOWDECORATION 1 export ELM_DISPLAY wl export _JAVA_AWT_WM_NONREPARENTING 0 export SDL_VIDEODRIVER wayland ``` While the above does not demonstrate reading variables, the example below does demonstrates its use: ``` export PATH $ENV:HOME/bin:$ENV:PATH ``` Signed-off-by: Joseph Benden <[email protected]>
1 parent f5ca4c2 commit dd82a8e

File tree

5 files changed

+88
-0
lines changed

5 files changed

+88
-0
lines changed

include/sway/commands.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ sway_cmd cmd_default_floating_border;
123123
sway_cmd cmd_default_orientation;
124124
sway_cmd cmd_exec;
125125
sway_cmd cmd_exec_always;
126+
sway_cmd cmd_export;
126127
sway_cmd cmd_exit;
127128
sway_cmd cmd_floating;
128129
sway_cmd cmd_floating_maximum_size;

sway/commands.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static struct cmd_handler handlers[] = {
5858
{ "default_floating_border", cmd_default_floating_border },
5959
{ "exec", cmd_exec },
6060
{ "exec_always", cmd_exec_always },
61+
{ "export", cmd_export },
6162
{ "floating_maximum_size", cmd_floating_maximum_size },
6263
{ "floating_minimum_size", cmd_floating_minimum_size },
6364
{ "floating_modifier", cmd_floating_modifier },

sway/commands/export.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#define _POSIX_C_SOURCE 200809L
2+
#define _GNU_SOURCE 1
3+
#define __BSD_VISIBLE 1
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include <strings.h>
7+
#include "sway/commands.h"
8+
#include "sway/config.h"
9+
#include "list.h"
10+
#include "log.h"
11+
#include "stringop.h"
12+
13+
// sort in order of longest->shortest
14+
static int compare_set_qsort(const void *_l, const void *_r) {
15+
struct sway_variable const *l = *(void **)_l;
16+
struct sway_variable const *r = *(void **)_r;
17+
return strlen(r->name) - strlen(l->name);
18+
}
19+
20+
// export TERM xterm-256color
21+
struct cmd_results *cmd_export(int argc, char **argv) {
22+
struct cmd_results *error = NULL;
23+
if ((error = checkarg(argc, "export", EXPECTED_AT_LEAST, 2))) {
24+
return error;
25+
}
26+
27+
char *search_var;
28+
if (asprintf(&search_var, "$ENV:%s", argv[0]) < 0) {
29+
return cmd_results_new(CMD_FAILURE, "Unable to allocate search variable");
30+
}
31+
32+
struct sway_variable *var = NULL;
33+
// Find old variable if it exists
34+
int i;
35+
for (i = 0; i < config->symbols->length; ++i) {
36+
var = config->symbols->items[i];
37+
if (strcmp(var->name, search_var) == 0) {
38+
break;
39+
}
40+
var = NULL;
41+
}
42+
if (var) {
43+
free(var->value);
44+
} else {
45+
var = malloc(sizeof(struct sway_variable));
46+
if (!var) {
47+
return cmd_results_new(CMD_FAILURE, "Unable to allocate variable");
48+
}
49+
var->name = strdup(search_var);
50+
list_add(config->symbols, var);
51+
list_qsort(config->symbols, compare_set_qsort);
52+
}
53+
var->value = join_args(argv + 1, argc - 1);
54+
// NOTE(jbenden): Should an empty string mean to unsetenv?
55+
if (setenv(argv[0], var->value, true) != 0)
56+
return cmd_results_new(CMD_FAILURE, "Unable to set environment variable");
57+
return cmd_results_new(CMD_SUCCESS, NULL);
58+
}

sway/config.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,33 @@ char *do_var_replacement(char *str) {
919919
++find;
920920
continue;
921921
}
922+
// Is an environment variable requested?
923+
if (strncmp(find, "$ENV:", strlen("$ENV:")) == 0) {
924+
char *var_name = &find[5];
925+
int vnlen = strlen(var_name);
926+
if (var_name[0] == '\0') continue;
927+
char *env_value = getenv(var_name);
928+
if (env_value) {
929+
int vvlen = strlen(env_value);
930+
char *newstr = malloc(strlen(str) - (strlen("$ENV:") + vnlen) + vvlen + 1);
931+
if (!newstr) {
932+
sway_log(SWAY_ERROR,
933+
"Unable to allocate replacement "
934+
"during variable expansion");
935+
continue;
936+
}
937+
char *newptr = newstr;
938+
int offset = find - str;
939+
strncpy(newptr, str, offset);
940+
newptr += offset;
941+
strncpy(newptr, env_value, vvlen);
942+
newptr += vvlen;
943+
strcpy(newptr, find + vnlen + strlen("$ENV:"));
944+
free(str);
945+
str = newstr;
946+
find = str + offset + vvlen;
947+
}
948+
}
922949
// Find matching variable
923950
for (i = 0; i < config->symbols->length; ++i) {
924951
struct sway_variable *var = config->symbols->items[i];

sway/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ sway_sources = files(
5151
'commands/exit.c',
5252
'commands/exec.c',
5353
'commands/exec_always.c',
54+
'commands/export.c',
5455
'commands/floating.c',
5556
'commands/floating_minmax_size.c',
5657
'commands/floating_modifier.c',

0 commit comments

Comments
 (0)