From patchwork Wed Feb 5 13:04:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2773 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8809F60443 for ; Wed, 5 Feb 2020 14:04:26 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 31E87E48; Wed, 5 Feb 2020 14:04:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1580907866; bh=t+AzHqUDfnwtvOSNQDS6KA6QGxbt0Kw3HStE9Q3n54Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ag6rZftd5sOi8aRsSGNj0buDdMtKJ7ntq6Hk0u8WT2svZwNvj0Snq+TdRNRafkVhB 6k94ACCcOBbkgsOyn66dXL5pMwBZA8ovz6wgnXq+V9cUYa8bZf0wi3IQctznkaBOXL AxZoxXzdvRvTby0xQ42BMzQKla0Z5uZlnylrWf8Y= From: Kieran Bingham To: LibCamera Devel Date: Wed, 5 Feb 2020 13:04:18 +0000 Message-Id: <20200205130420.8736-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200205130420.8736-1-kieran.bingham@ideasonboard.com> References: <20200205130420.8736-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/5] libcamera: ipa_manager: Allow recursive parsing X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Feb 2020 13:04:26 -0000 Provide an optional means to recurse into subdirectories to search for IPA libraries. This allows IPAs contained within their own build directory to be resolved when loading from a non-installed build. Signed-off-by: Kieran Bingham --- src/libcamera/include/ipa_manager.h | 6 ++-- src/libcamera/ipa_manager.cpp | 54 ++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h index 94d35d9062e4..8243ba5a1f51 100644 --- a/src/libcamera/include/ipa_manager.h +++ b/src/libcamera/include/ipa_manager.h @@ -32,8 +32,10 @@ private: IPAManager(); ~IPAManager(); - int addDir(const char *libDir); - int addPath(const char *path); + int parseDir(const char *libDir, std::vector &paths, + unsigned int subdirs); + int addDir(const char *libDir, unsigned int subdirs = 0); + int addPath(const char *path, unsigned int subdirs = 0); }; } /* namespace libcamera */ diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 048465c37772..24fe709108fe 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -140,16 +140,17 @@ IPAManager *IPAManager::instance() } /** - * \brief Load IPA modules from a directory + * \brief Identify shared library objects within a directory * \param[in] libDir directory to search for IPA modules + * \param[in] subdirs maximum number of sub-directories to parse * - * This method tries to create an IPAModule instance for every shared object - * found in \a libDir, and skips invalid IPA modules. + * Search a directory for .so files. allowing recursion down to + * subdirectories no further than the quantity specified by \a subdirs * - * \return Number of modules loaded by this call, or a negative error code - * otherwise + * \return 0 on success or a negative error code otherwise */ -int IPAManager::addDir(const char *libDir) +int IPAManager::parseDir(const char *libDir, std::vector &paths, + unsigned int subdirs) { struct dirent *ent; DIR *dir; @@ -158,8 +159,20 @@ int IPAManager::addDir(const char *libDir) if (!dir) return -errno; - std::vector paths; while ((ent = readdir(dir)) != nullptr) { + if (ent->d_type == DT_DIR && subdirs) { + if (strcmp(ent->d_name, ".") == 0 || + strcmp(ent->d_name, "..") == 0) + continue; + + std::string subdir = std::string(libDir) + "/" + ent->d_name; + + /* Only recurse to the limit specified by subdirs */ + parseDir(subdir.c_str(), paths, subdirs - 1); + + continue; + } + int offset = strlen(ent->d_name) - 3; if (offset < 0) continue; @@ -170,6 +183,28 @@ int IPAManager::addDir(const char *libDir) } closedir(dir); + return 0; +} + +/** + * \brief Load IPA modules from a directory + * \param[in] libDir directory to search for IPA modules + * \param[in] subdirs maximum number of sub-directories to parse + * + * This method tries to create an IPAModule instance for every shared object + * found in \a libDir, and skips invalid IPA modules. + * + * \return Number of modules loaded by this call, or a negative error code + * otherwise + */ +int IPAManager::addDir(const char *libDir, unsigned int subdirs) +{ + std::vector paths; + + int ret = parseDir(libDir, paths, subdirs); + if (ret < 0) + return ret; + /* Ensure a stable ordering of modules. */ std::sort(paths.begin(), paths.end()); @@ -193,6 +228,7 @@ int IPAManager::addDir(const char *libDir) /** * \brief Load IPA modules from a colon separated PATH variable * \param[in] path string to split to search for IPA modules + * \param[in] subdirs maximum number of sub-directories to parse * * This method tries to create an IPAModule instance for every shared object * found in the directories described by \a paths. @@ -200,7 +236,7 @@ int IPAManager::addDir(const char *libDir) * \return Number of modules loaded by this call, or a negative error code * otherwise */ -int IPAManager::addPath(const char *paths) +int IPAManager::addPath(const char *paths, unsigned int subdirs) { int ipaCount = 0; @@ -210,7 +246,7 @@ int IPAManager::addPath(const char *paths) if (count) { std::string path(paths, count); - int ret = addDir(path.c_str()); + int ret = addDir(path.c_str(), subdirs); if (ret > 0) ipaCount += ret; }