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
*/