From 9e3b5378173de8beff437fa41d997678b604d6f3 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Sun, 24 Oct 2021 11:25:05 +0200 Subject: [PATCH] feat: Support reading config from non-regular files (#2545) We had a check that restricted config files to "regular files". This check was to restrictive as it didn't allow for things like: ``` polybar -c <(gen_config) gen_config | polybar -c /dev/stdin ``` Now, polybar can easily read config data from stdin. --- CHANGELOG.md | 1 + include/utils/file.hpp | 1 + src/components/config_parser.cpp | 4 ++-- src/utils/file.cpp | 13 +++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33264c74..21b1f65e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `DEBUG_SHADED` cmake variable and its associated functionality. ### Added +- Polybar can now read config files from stdin: `polybar -c /dev/stdin`. - `custom/script`: Implement `env-*` config option. ([2090](https://github.com/polybar/polybar/issues/2090)) - `drawtypes/ramp`: Add support for ramp weights. diff --git a/include/utils/file.hpp b/include/utils/file.hpp index 213bf6cd..8a34c645 100644 --- a/include/utils/file.hpp +++ b/include/utils/file.hpp @@ -83,6 +83,7 @@ class fd_stream : public StreamType { namespace file_util { bool exists(const string& filename); bool is_file(const string& filename); + bool is_dir(const string& filename); string pick(const vector& filenames); string contents(const string& filename); void write_contents(const string& filename, const string& contents); diff --git a/src/components/config_parser.cpp b/src/components/config_parser.cpp index 034a0f2a..d29a2319 100644 --- a/src/components/config_parser.cpp +++ b/src/components/config_parser.cpp @@ -126,8 +126,8 @@ void config_parser::parse_file(const string& file, file_list path) { throw application_error("Failed to open config file " + file + ": " + strerror(errno)); } - if (!file_util::is_file(file)) { - throw application_error("Config file " + file + " is not a file"); + if (file_util::is_dir(file)) { + throw application_error("Config file " + file + " is a directory"); } m_log.trace("config_parser: Parsing %s", file); diff --git a/src/utils/file.cpp b/src/utils/file.cpp index bcf6ba26..9511ad61 100644 --- a/src/utils/file.cpp +++ b/src/utils/file.cpp @@ -165,6 +165,19 @@ namespace file_util { return S_ISREG(buffer.st_mode); } + /** + * Checks if the given path exists and is a file + */ + bool is_dir(const string& filename) { + struct stat buffer {}; + + if (stat(filename.c_str(), &buffer) != 0) { + return false; + } + + return S_ISDIR(buffer.st_mode); + } + /** * Picks the first existing file out of given entries */