[v1] libcamera: pipeline_handler: Try more configuration file paths
diff mbox series

Message ID 20261017111758.633101-1-robert.mader@collabora.com
State New
Headers show
Series
  • [v1] libcamera: pipeline_handler: Try more configuration file paths
Related show

Commit Message

Robert Mader Oct. 17, 2026, 11:17 a.m. UTC
Similar to the global configuration file - configuration.yaml - check
the user- and system-configuration paths for pipeline handlers.

This is particularly useful on immutable OSs which typically don't allow
writes to /usr/share.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Closes https://gitlab.freedesktop.org/camera/libcamera/-/work_items/364
---
 src/libcamera/pipeline_handler.cpp | 44 ++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 11 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index a803f6208c32..c23a11026279 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -628,6 +628,8 @@  void PipelineHandler::cancelRequest(Request *request)
  *
  * - If libcamera is not installed, the src/libcamera/pipeline/\<subdir\>/data/
  *   directory within the source tree ; otherwise
+ * - The user configuration (~/.config/libcamera/pipeline/\<subdir\>) directory.
+ * - The system configuration (etc/libcamera/pipeline/\<subdir\>) directory.
  * - The system data (share/libcamera/pipeline/\<subdir\>) directory.
  *
  * The system directories are not searched if libcamera is not installed.
@@ -639,9 +641,8 @@  std::string PipelineHandler::configurationFile(const std::string &subdir,
 					       const std::string &name,
 					       bool silent) const
 {
-	std::string confPath;
+	std::vector<std::string> confPaths;
 	struct stat statbuf;
-	int ret;
 
 	std::string root = utils::libcameraSourcePath();
 	if (!root.empty()) {
@@ -652,25 +653,46 @@  std::string PipelineHandler::configurationFile(const std::string &subdir,
 		 * subdirectory of the corresponding pipeline handler.
 		 */
 		std::string confDir = root + "src/libcamera/pipeline/";
-		confPath = confDir + subdir + "/data/" + name;
+		confPaths.push_back(confDir + subdir + "/data/" + name);
 
 		LOG(Pipeline, Info)
 			<< "libcamera is not installed. Loading platform configuration file from '"
-			<< confPath << "'";
+			<< confPaths.front() << "'";
 	} else {
 		/* Else look in the system locations. */
-		confPath = std::string(LIBCAMERA_DATA_DIR)
-				+ "/pipeline/" + subdir + '/' + name;
+		std::filesystem::path userConfigurationDirectory;
+		const char *xdgConfigHome = utils::secure_getenv("XDG_CONFIG_HOME");
+		if (xdgConfigHome) {
+			userConfigurationDirectory = xdgConfigHome;
+		} else {
+			const char *home = utils::secure_getenv("HOME");
+			if (home)
+				userConfigurationDirectory =
+					std::filesystem::path(home) / ".config";
+		}
+
+		confPaths.push_back(std::string(userConfigurationDirectory) + "/libcamera");
+		confPaths.push_back(std::string(LIBCAMERA_SYSCONF_DIR));
+		confPaths.push_back(std::string(LIBCAMERA_DATA_DIR));
+
+		for (std::string &confPath : confPaths) {
+			confPath += "/pipeline/" + subdir + '/' + name;
+		}
 	}
 
-	ret = stat(confPath.c_str(), &statbuf);
-	if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
-		return confPath;
+	for (const std::string &confPath : confPaths) {
+		int ret = stat(confPath.c_str(), &statbuf);
+		if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG) {
+			LOG(Pipeline, Debug)
+				<< "Loading platform configuration file from '"
+				<< confPath << "'";
+			return confPath;
+		}
+	}
 
 	if (!silent)
 		LOG(Pipeline, Error)
-			<< "Configuration file '" << confPath
-			<< "' not found for pipeline handler '"
+			<< "Configuration file not found for pipeline handler '"
 			<< PipelineHandler::name() << "'";
 
 	return std::string();