diff --git a/include/components/config_parser.hpp b/include/components/config_parser.hpp index 0f5dc096..68f343a8 100644 --- a/include/components/config_parser.hpp +++ b/include/components/config_parser.hpp @@ -6,8 +6,6 @@ #include "components/config.hpp" #include "components/logger.hpp" #include "errors.hpp" -#include "utils/file.hpp" -#include "utils/string.hpp" POLYBAR_NS diff --git a/include/utils/file.hpp b/include/utils/file.hpp index 3949e2b8..ba165959 100644 --- a/include/utils/file.hpp +++ b/include/utils/file.hpp @@ -102,6 +102,7 @@ class fd_stream : public StreamType { namespace file_util { bool exists(const string& filename); + bool is_file(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 b422584e..dca093ea 100644 --- a/src/components/config_parser.cpp +++ b/src/components/config_parser.cpp @@ -1,8 +1,13 @@ #include "components/config_parser.hpp" #include +#include +#include #include +#include "utils/file.hpp" +#include "utils/string.hpp" + POLYBAR_NS config_parser::config_parser(const logger& logger, string&& file, string&& bar) @@ -89,6 +94,14 @@ void config_parser::parse_file(const string& file, file_list path) { throw application_error("include-file: Dependency cycle detected:\n" + path_str); } + if (!file_util::exists(file)) { + 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"); + } + m_log.trace("config_parser: Parsing %s", file); int file_index; diff --git a/src/utils/file.cpp b/src/utils/file.cpp index 0a4c6955..756d057d 100644 --- a/src/utils/file.cpp +++ b/src/utils/file.cpp @@ -170,12 +170,29 @@ int fd_streambuf::underflow() { namespace file_util { /** * Checks if the given file exist + * + * May also return false if the file status cannot be read + * + * Sets errno when returning false */ bool exists(const string& filename) { struct stat buffer {}; return stat(filename.c_str(), &buffer) == 0; } + /** + * Checks if the given path exists and is a file + */ + bool is_file(const string& filename) { + struct stat buffer {}; + + if (stat(filename.c_str(), &buffer) != 0) { + return false; + } + + return S_ISREG(buffer.st_mode); + } + /** * Picks the first existing file out of given entries */