mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
session: process environment.d and allow empty variables
1. All '*.env' files in an 'environment.d' directory alongside each potential 'environment' file will be parsed and added to the environment. 2. For the purposes of configuration merging, an environment definition exists at one level if either the 'environment' file is defined or its corresponding 'environment.d' contains any valid '*.env' file. 3. Variable declarations of the form "VARIABLE=", with no following value, will be written to the environment as empty strings.
This commit is contained in:
parent
52cb643189
commit
e837445114
4 changed files with 121 additions and 10 deletions
|
|
@ -37,13 +37,23 @@ option.
|
|||
All configuration and theme files except autostart and shutdown are re-loaded on
|
||||
receiving signal SIGHUP.
|
||||
|
||||
The *environment* file is parsed as *variable=value* and sets environment
|
||||
variables accordingly. It is recommended to specify keyboard layout settings and
|
||||
cursor size/theme here; see environment variable section below for details. Note
|
||||
that the environment file is treated differently by openbox where it is simply
|
||||
sourced prior to running openbox.
|
||||
Note: Tilde (~) and environment variables in the value are expanded, but
|
||||
subshell syntax and apostrophes are ignored.
|
||||
Environment variables may be set within *environment* files, wherein each line
|
||||
defines shell variables in the format *variable=value*. It is recommended to
|
||||
specify keyboard layout settings and cursor size/theme here; see environment
|
||||
variable section below for details. Within an XDG Base Directory, a file named
|
||||
"environment" will be parsed first, followed by any file matching the glob
|
||||
"environment.d/\*.env". Files within the environment.d directory are parsed in
|
||||
an arbitrary order; any variables that must be set in a particular sequence
|
||||
should be set within the same file. Unless the --merge-config option is
|
||||
specified, labwc will consider a particular XDG Base Directory to have provided
|
||||
an environment file if that directory contains either the "environment"
|
||||
directory or at least one "environment.d/\*.env" file.
|
||||
|
||||
Note: environment files are treated differently by Openbox, which will simply
|
||||
source the file as a valid shell script before running the window manager. Files
|
||||
are instead parsed directly by labwc, although any environment variables
|
||||
referenced as $VARIABLE or ${VARIABLE} will be substituted and the tilde (~)
|
||||
will be expanded as the user's home directory.
|
||||
|
||||
The *autostart* file is executed as a shell script after labwc has read its
|
||||
configuration and set variables defined in the environment file. Additionally,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,18 @@ char *strdup_printf(const char *fmt, ...);
|
|||
* The separator is arbitrary. When the separator is NULL, a single space will
|
||||
* be used.
|
||||
*/
|
||||
char *str_join(const char * const parts[],
|
||||
char *str_join(const char *const parts[],
|
||||
const char *restrict fmt, const char *restrict sep);
|
||||
|
||||
/**
|
||||
* str_endswith - indicate whether a string ends with a given suffix
|
||||
* @string: string to test
|
||||
* @suffix: suffix to expect in string
|
||||
*
|
||||
* If suffix is "" or NULL, this method always returns true; otherwise, this
|
||||
* method returns true if and only if the full suffix exists at the end of the
|
||||
* string.
|
||||
*/
|
||||
bool str_endswith(const char *const string, const char *const suffix);
|
||||
|
||||
#endif /* LABWC_STRING_HELPERS_H */
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ strdup_printf(const char *fmt, ...)
|
|||
}
|
||||
|
||||
char *
|
||||
str_join(const char * const parts[],
|
||||
str_join(const char *const parts[],
|
||||
const char *restrict fmt, const char *restrict sep)
|
||||
{
|
||||
assert(parts);
|
||||
|
|
@ -154,3 +154,19 @@ str_join(const char * const parts[],
|
|||
return buf;
|
||||
}
|
||||
|
||||
bool
|
||||
str_endswith(const char *const string, const char *const suffix)
|
||||
{
|
||||
size_t len_str = string ? strlen(string) : 0;
|
||||
size_t len_sfx = suffix ? strlen(suffix) : 0;
|
||||
|
||||
if (len_str < len_sfx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len_sfx == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return strcmp(string + len_str - len_sfx, suffix) == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <wlr/backend/drm.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
|
@ -49,9 +51,10 @@ process_line(char *line)
|
|||
buf_add(&value, string_strip(++p));
|
||||
buf_expand_shell_variables(&value);
|
||||
buf_expand_tilde(&value);
|
||||
if (string_null_or_empty(key) || !value.len) {
|
||||
if (string_null_or_empty(key)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
setenv(key, value.buf, 1);
|
||||
error:
|
||||
free(value.buf);
|
||||
|
|
@ -80,6 +83,71 @@ read_environment_file(const char *filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
static char *
|
||||
strdup_env_path_validate(const char *prefix, struct dirent *dirent)
|
||||
{
|
||||
assert(prefix);
|
||||
|
||||
/* Valid environment files always end in '.env' */
|
||||
if (!str_endswith(dirent->d_name, ".env")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *full_path = strdup_printf("%s/%s", prefix, dirent->d_name);
|
||||
if (!full_path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Valid environment files must be regular files */
|
||||
struct stat statbuf;
|
||||
if (stat(full_path, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) {
|
||||
return full_path;
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
read_environment_dir(const char *path_prefix)
|
||||
{
|
||||
bool success = false;
|
||||
char *path = strdup_printf("%s.d", path_prefix);
|
||||
|
||||
errno = 0;
|
||||
DIR *envdir = opendir(path);
|
||||
|
||||
if (!envdir) {
|
||||
if (errno != ENOENT) {
|
||||
const char *err_msg = strerror(errno);
|
||||
wlr_log(WLR_INFO,
|
||||
"failed to read environment directory: %s",
|
||||
err_msg ? err_msg : "reason unknown");
|
||||
}
|
||||
|
||||
goto env_dir_cleanup;
|
||||
}
|
||||
|
||||
struct dirent *dirent;
|
||||
while ((dirent = readdir(envdir)) != NULL) {
|
||||
char *env_file_path = strdup_env_path_validate(path, dirent);
|
||||
if (!env_file_path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read_environment_file(env_file_path)) {
|
||||
success = true;
|
||||
}
|
||||
|
||||
free(env_file_path);
|
||||
}
|
||||
|
||||
env_dir_cleanup:
|
||||
closedir(envdir);
|
||||
free(path);
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
backend_check_drm(struct wlr_backend *backend, void *is_drm)
|
||||
{
|
||||
|
|
@ -176,7 +244,13 @@ session_environment_init(void)
|
|||
|
||||
for (struct wl_list *elm = iter(&paths); elm != &paths; elm = iter(elm)) {
|
||||
struct path *path = wl_container_of(elm, path, link);
|
||||
|
||||
/* Process an environment file itself */
|
||||
bool success = read_environment_file(path->string);
|
||||
|
||||
/* Process a correponding environment.d directory */
|
||||
success |= read_environment_dir(path->string);
|
||||
|
||||
if (success && !should_merge_config) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue