X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Futil%2Futils.cc;h=963cb7f4f4747c806f9d9f25338194bf9e46791e;hb=refs%2Ftags%2Faccepted%2Ftizen%2Funified%2F20221014.123806;hp=a33eec2949d5f879023dbc0c0684307f63546415;hpb=ade011be54cd1981e09871ff900d6138a7766306;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index a33eec2..963cb7f 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -20,9 +20,11 @@ #include #include #include -#include #include #include +#include +#include +#include #include #include @@ -30,8 +32,10 @@ #include #include #include +#include #include #include +#include #include "log.h" #include "utils.h" @@ -48,9 +52,7 @@ static bool iCompare(const std::string& a, int aOffset, const std::string& b, in bool isManagedAssembly(const std::string& fileName) { - return (iCompare(fileName, fileName.size()-4, ".dll", 0, 4) || - iCompare(fileName, fileName.size()-4, ".exe", 0, 4)) && - !isNativeImage(fileName); + return iCompare(fileName, fileName.size()-4, ".dll", 0, 4) && !isNativeImage(fileName); } bool isNativeImage(const std::string& fileName) @@ -58,23 +60,6 @@ bool isNativeImage(const std::string& fileName) return iCompare(fileName, fileName.size()-7, ".ni", 0, 3); } -bool cmdOptionExists(char** begin, char** end, const std::string& option) -{ - return std::find(begin, end, option) != end; -} - -std::string readSelfPath() -{ - char buff[PATH_MAX]; - ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1); - if (len != -1) { - buff[len] = '\0'; - return std::string(buff); - } - - return ""; -} - std::string concatPath(const std::string& path1, const std::string& path2) { std::string path(path1); @@ -98,51 +83,188 @@ void splitPath(const std::string& path, std::vector& out) } } -std::string absolutePath(const std::string& path) +std::string getAbsolutePath(const std::string& path) { std::string absPath; - char realPath[PATH_MAX]; - if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0') + char *realPath = realpath(path.c_str(), NULL); + if (realPath) { absPath.assign(realPath); + free(realPath); + } return absPath; } -int getRootPath(std::string pkgId, std::string& rootPath) +std::string getRootPath(const std::string& pkgId) { int ret = 0; char *path = 0; - uid_t uid = 0; + std::string rootPath; - if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { - _ERR("Failed to get UID"); - return -1; + pkgmgrinfo_pkginfo_h pkg_handle; + ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { + return rootPath; } - pkgmgrinfo_pkginfo_h handle; - if (uid == 0) { - ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); - if (ret != PMINFO_R_OK) { - return -1; - } - } else { - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle); - if (ret != PMINFO_R_OK) { - return -1; - } + ret = pkgmgrinfo_pkginfo_get_root_path(pkg_handle, &path); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return rootPath; } + rootPath = path; + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + + return rootPath; +} + +std::string getExecName(const std::string& pkgId) +{ + char *exec = NULL; + char *appId = 0; + std::string execName; - ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path); + pkgmgrinfo_pkginfo_h pkg_handle; + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { + return execName; + } + + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); if (ret != PMINFO_R_OK) { - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - return -1; + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return execName; } - rootPath = path; - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - return 0; + + pkgmgrinfo_appinfo_h app_handle; + ret = pkgmgrGetAppInfo(appId, &app_handle); + if (ret != 0) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return execName; + } + + ret = pkgmgrinfo_appinfo_get_exec(app_handle, &exec); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return execName; + } + execName = std::string(exec).substr(std::string(exec).rfind('/') + 1); + + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + + return execName; +} + +std::string getAppType(const std::string& pkgId) +{ + char *appId = 0; + char *type = 0; + std::string appType; + + pkgmgrinfo_pkginfo_h pkg_handle; + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { + return appType; + } + + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return appType; + } + + pkgmgrinfo_appinfo_h app_handle; + ret = pkgmgrGetAppInfo(appId, &app_handle); + if (ret != 0) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return appType; + } + + ret = pkgmgrinfo_appinfo_get_apptype(app_handle, &type); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return appType; + } + appType = type; + + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + + return appType; +} + +std::string getMetadataValue(const std::string& pkgId, const std::string& key) +{ + char *value = NULL; + char *appId = 0; + std::string metadataValue; + + pkgmgrinfo_pkginfo_h pkg_handle; + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { + return metadataValue; + } + + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return metadataValue; + } + + pkgmgrinfo_appinfo_h app_handle; + ret = pkgmgrGetAppInfo(appId, &app_handle); + if (ret != 0) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return metadataValue; + } + + ret = pkgmgrinfo_appinfo_get_metadata_value(app_handle, key.c_str(), &value); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return metadataValue; + } + metadataValue = std::string(value); + + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + + return metadataValue; +} + +bool isReadOnlyArea(const std::string& path) +{ + FILE *f = NULL; + struct mntent *m = NULL; + + // "/opt/usr" is mounted to "RW" only + if (path.find("/opt/usr") != std::string::npos) { + return false; + } + + // check whether "/" is mounted to RO or not + f = setmntent("/proc/mounts", "r"); + if (!f) { + // return true for fail case to generate NI files under RW area. + return true; + } + + while((m = getmntent(f))) { + if (m->mnt_dir != NULL && strcmp(m->mnt_dir, "/") == 0 && + m->mnt_opts != NULL && strstr(m->mnt_opts, "ro,") != NULL) { + endmntent(f); + return true; + } + } + endmntent(f); + return false; + } -std::string baseName(const std::string& path) +std::string getBaseName(const std::string& path) { auto pos = path.find_last_of(PATH_SEPARATOR); if (pos != std::string::npos) @@ -152,68 +274,103 @@ std::string baseName(const std::string& path) return path; } -bool isFileExist(const std::string& path) +std::string replaceAll(const std::string& str, const std::string& pattern, const std::string& replace) { - struct stat sb; - return stat(path.c_str(), &sb) == 0; + std::string result = str; + std::string::size_type pos = 0; + std::string::size_type offset = 0; + + while ((pos = result.find(pattern, offset)) != std::string::npos) { + result.replace(result.begin() + pos, result.begin() + pos + pattern.size(), replace); + offset = pos + replace.size(); + } + + return result; +} + +std::string changeExtension(const std::string& path, const std::string& from, const std::string& to) +{ + return path.substr(0, path.rfind(from)) + to; } -std::string stripNiDLL(const std::string& path) +bool isFile(const std::string& path) { - std::string niPath(path); - if (path.size() < 5) return niPath; - if (!strncasecmp(path.c_str() + path.size() - 4, ".dll", 4)) - niPath = path.substr(0, path.size()-4); - else if (!strncasecmp(path.c_str() + path.size() - 4, ".exe", 4)) - niPath = path.substr(0, path.size()-4); + struct stat sb; + return lstat(path.c_str(), &sb) == 0; +} - if (!strncasecmp(niPath.c_str() + niPath.size() - 3, ".ni", 3)) - return niPath.substr(0, niPath.size()-3); +bool isSymlinkFile(const std::string& path) +{ + struct stat sb; + if (lstat(path.c_str(), &sb) != 0) { + return false; + } + return (sb.st_mode & S_IFMT) == S_IFLNK; +} - return niPath; +bool isDirectory(const std::string& path) +{ + struct stat sb; + if (stat(path.c_str(), &sb) != 0) { + return false; + } + return (sb.st_mode & S_IFMT) == S_IFDIR; } -void assembliesInDirectory(const std::vector& directories, std::string& tpaList) +std::string getAssemblyNameFromPath(const std::string& path) { - std::map assemblyList; - std::map tmpList; + std::string ret(getFileName(path)); + + if (ret.find_last_of(".") == std::string::npos) + return ret; + ret.erase(ret.find_last_of(".")); + + if (ret.size() > 3 && std::equal(ret.begin() + ret.size() - 3, ret.end(), ".ni")) + ret.erase(ret.size() - 3); + + return ret; +} - auto reader = [&assemblyList, &tmpList] (const std::string& path, const char* name) { - if (isManagedAssembly(path) || isNativeImage(path)) { - std::string dllName = stripNiDLL(name); - std::pair::iterator, bool> ret; - ret = tmpList.insert(std::pair(dllName, path)); - if (ret.second == false) { - if (isNativeImage(path)) - tmpList[dllName] = path; +void addAssembliesFromDirectories(const std::vector& directories, std::string& list) +{ + std::vector assems; + std::unordered_map assemPaths; + + auto reader = [&assems, &assemPaths](const std::string& path, const std::string& filename) { + if (isManagedAssembly(filename) || isNativeImage(filename)) { + std::string assem = getAssemblyNameFromPath(filename); + + if (assemPaths.count(assem) == 0) { + assems.push_back(assem); + assemPaths[assem] = path; + } else if (isManagedAssembly(assemPaths[assem]) && isNativeImage(filename)) { + // Update only if a native image is found in the same directory. + // For example, if we have two directories = { X, Y } where X contains A.dll and + // Y contains both A.dll and A.ni.dll, always A.dll in X will be used. + if (getBaseName(assemPaths[assem]).compare(getBaseName(path)) == 0) + assemPaths[assem] = path; } } }; + for (auto& directory : directories) + scanFilesInDirectory(directory, reader, 0); - for (auto directory : directories) { - scanFilesInDir(directory.c_str(), reader, 1); - // merge scaned dll list to tpa list. - // if the dll is already exist in the list, that is skipped. - assemblyList.insert(tmpList.begin(), tmpList.end()); - } + if (!list.empty() && list.back() != ':') + list.push_back(':'); - std::map::iterator it; - for (it = assemblyList.begin(); it != assemblyList.end(); it++) - tpaList += it->second + ':'; + for (auto& assem : assems) + list += assemPaths[assem] + ":"; - if (tpaList.back() == ':') - tpaList.pop_back(); + if (list.back() == ':') + list.pop_back(); } -void scanFilesInDir(const std::string& directory, FileReader reader, unsigned int depth) +void scanFilesInDirectory(const std::string& directory, FileReader reader, unsigned int depth) { DIR *dir; struct dirent* entry; bool isDir; - if (strstr(directory.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) - return; // skip nitool --regen-all-app (--r2r) - dir = opendir(directory.c_str()); if (dir == nullptr) @@ -229,51 +386,69 @@ void scanFilesInDir(const std::string& directory, FileReader reader, unsigned in case DT_DIR: isDir = true; break; + // symlink is added to the list even if there is no original file. + // It used to remove broken symlinks related to TAC case DT_LNK: + break; case DT_UNKNOWN: - struct stat sb; - if (stat(path.c_str(), &sb) == -1) - continue; - - if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode)) - break; + continue; default: continue; } if (!isDir) reader(path, entry->d_name); - else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) + else if (depth > 0 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) innerDirectories.push_back(path); } - if (depth != 0) + if (depth > 0) for (auto& d : innerDirectories) - scanFilesInDir(d.c_str(), reader, depth - 1); + scanFilesInDirectory(d, reader, depth - 1); closedir(dir); } -void updateAssemblyInfo(const std::string& getPath, const std::string& setPath) +void copySmackAndOwnership(const std::string& fromPath, const std::string& toPath, bool isSymlink) { char* label = NULL; + struct stat info; - // change smack label - if (smack_getlabel(getPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { - if (smack_setlabel(setPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { - fprintf(stderr, "Fail to set smack label\n"); + if (isSymlink) { + // change smack label for symbolic link. + if (smack_lgetlabel(fromPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { + if (smack_lsetlabel(toPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { + _SERR("Fail to set smack label"); + } + free(label); } - free(label); - } - // change owner and groups for generated ni file. - struct stat info; - if (!stat(getPath.c_str(), &info)) { - if (chown(setPath.c_str(), info.st_uid, info.st_gid) == -1) - fprintf(stderr, "Failed to change owner and group name\n"); + // change owner and groupsfor symbolic link. + // change mode is skipped for symlink because permission of symlink file is meaningless. + if (!lstat(fromPath.c_str(), &info)) { + if (lchown(toPath.c_str(), info.st_uid, info.st_gid) == -1) + _SERR("Failed to change owner and group name"); + } + } else { + // change smack label + if (smack_getlabel(fromPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { + if (smack_setlabel(toPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { + _SERR("Fail to set smack label"); + } + free(label); + } + + // change owner, groups and mode for generated ni file. + if (!stat(fromPath.c_str(), &info)) { + if (chown(toPath.c_str(), info.st_uid, info.st_gid) == -1) + _SERR("Failed to change owner and group name"); + if (chmod(toPath.c_str(), info.st_mode) == -1) + _SERR("Failed to change mode"); + } } } -static bool setOwnership(const bf::path& path, uid_t uid, gid_t gid) { +static bool setOwnership(const bf::path& path, uid_t uid, gid_t gid) +{ int fd = open(path.c_str(), O_RDONLY); if (fd < 0) { _ERR("Can't open directory: %s", path.c_str()); @@ -288,7 +463,8 @@ static bool setOwnership(const bf::path& path, uid_t uid, gid_t gid) { return true; } -static bool setDirPermissions(const bf::path& path, bf::perms permissions) { +static bool setDirPermissions(const bf::path& path, bf::perms permissions) +{ bs::error_code error; bf::permissions(path, permissions, error); if (error) { @@ -298,7 +474,8 @@ static bool setDirPermissions(const bf::path& path, bf::perms permissions) { return true; } -static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permissions, uid_t uid, gid_t gid) { +static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permissions, uid_t uid, gid_t gid) +{ if (!setOwnership(path, uid, gid)) { _ERR("Failed to change owner: %s, (uid: %d, gid: %d)", path.c_str(), uid, gid); return false; @@ -310,12 +487,18 @@ static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permis return true; } -static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) { - if (!bf::exists(path)) { +static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) +{ + if (!exist(path)) { _ERR("Failed to copy ownership and permissions from %s to %s", path.c_str(), path2.c_str()); return false; } - bf::perms permissions = bf::status(path).permissions(); + bs::error_code error; + bf::perms permissions = bf::status(path, error).permissions(); + if (error) { + _ERR("Failed to copy ownership and permissions : %s", error.message().c_str()); + return false; + } struct stat stats; if (stat(path.c_str(), &stats) != 0) { return false; @@ -327,8 +510,21 @@ static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& pa return true; } -bool createDir(const bf::path& path) { - if (bf::exists(path)) { +bool exist(const bf::path& path) +{ + bs::error_code error; + int ret = bf::exists(path, error); + if (error) { + if ((error.value() != bs::errc::success) && (error.value() != bs::errc::no_such_file_or_directory)) { + _ERR("Failed to check %s exists : %s", path.c_str(), error.message().c_str()); + } + } + return ret; +} + +bool createDir(const bf::path& path) +{ + if (exist(path)) { return true; } bs::error_code error; @@ -340,14 +536,15 @@ bool createDir(const bf::path& path) { return true; } -bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { +bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) +{ try { // Check whether the function call is valid - if (!bf::exists(path1) || !bf::is_directory(path1)) { + if (!exist(path1) || !bf::is_directory(path1)) { _ERR("Source directory %s does not exist or is not a directory", path1.c_str()); return false; } - if (!bf::exists(path2)) { + if (!exist(path2)) { // Create the destination directory if (!createDir(path2)) { _ERR("Unable to create destination directory %s", path2.c_str()); @@ -371,12 +568,12 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { } // Iterate through the source directory - for (bf::directory_iterator file(path1); file != bf::directory_iterator(); ++file) { - try { + try { + for (bf::directory_iterator file(path1); file != bf::directory_iterator(); ++file) { bf::path current(file->path()); bf::path target = path2 / current.filename(); - if (bf::is_symlink(symlink_status(current))) { - if ((flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE)) && bf::exists(target)) { + if (bf::is_symlink(bf::symlink_status(current))) { + if ((flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE)) && exist(target)) { continue; } bs::error_code error; @@ -391,7 +588,7 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { return false; } } else { - if ((flags & FS_MERGE_SKIP) && bf::exists(target)) { + if ((flags & FS_MERGE_SKIP) && exist(target)) { continue; } bf::path destination = target; @@ -413,16 +610,21 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { bf::rename(destination, target); } } - } catch (const bf::filesystem_error& error) { - _ERR("Failed to copy directory: %s", error.what()); - return false; } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to copy directory: %s", error.what()); + return false; } + return true; } -bool copyFile(const bf::path& path1, const bf::path& path2) { +bool copyFile(const bf::path& path1, const bf::path& path2) +{ bs::error_code error; + if (!exist(path1)) { + return false; + } bf::copy_file(path1, path2, bf::copy_option::overwrite_if_exists, error); if (error) { _ERR("copy file %s due to error [%s]", path1.c_str(), error.message().c_str()); @@ -431,8 +633,9 @@ bool copyFile(const bf::path& path1, const bf::path& path2) { return true; } -bool moveFile(const bf::path& path1, const bf::path& path2) { - if (bf::exists(path2)) { +bool moveFile(const bf::path& path1, const bf::path& path2) +{ + if (!exist(path1) || exist(path2)) { return false; } bs::error_code error; @@ -453,8 +656,9 @@ bool moveFile(const bf::path& path1, const bf::path& path2) { return true; } -bool removeFile(const bf::path& path) { - if (!bf::exists(path)) { +bool removeFile(const bf::path& path) +{ + if (!exist(path)) { return true; } bs::error_code error; @@ -466,8 +670,9 @@ bool removeFile(const bf::path& path) { return true; } -bool removeAll(const bf::path& path) { - if (!exists(path)) { +bool removeAll(const bf::path& path) +{ + if (!exist(path)) { return true; } bs::error_code error; @@ -477,4 +682,172 @@ bool removeAll(const bf::path& path) { return false; } return true; -} \ No newline at end of file +} + +void setCmdName(const std::string& name) +{ + #define PRC_NAME_LENGTH 16 + + char processName[PRC_NAME_LENGTH] = {0, }; + + if (name.empty()) + return; + + memset(processName, '\0', PRC_NAME_LENGTH); + snprintf(processName, PRC_NAME_LENGTH, "%s", name.c_str()); + prctl(PR_SET_NAME, processName); +} + +std::string getFileName(const std::string& path) +{ + std::string ret(path); + size_t index = ret.find_last_of(PATH_SEPARATOR); + return index == std::string::npos ? ret : ret.substr(index + 1); +} + +std::string SHA256(const std::string& path) +{ + std::string output = ""; + FILE *file = fopen(path.c_str(), "rb"); + if (!file) { + return output; + } + + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha256; + SHA256_Init(&sha256); + int bytesRead = 0; + const int bufSize = 32768; + char *buffer = (char*)malloc(bufSize); + if (!buffer) { + fclose(file); + return output; + } + + while ((bytesRead = fread(buffer, 1, bufSize, file))) { + SHA256_Update(&sha256, buffer, bytesRead); + } + SHA256_Final(hash, &sha256); + + std::stringstream ss; + for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { + ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i]; + } + output = ss.str(); + + fclose(file); + free(buffer); + + return output; +} + +int pkgmgrGetPkgInfo(const std::string& pkgId, pkgmgrinfo_pkginfo_h* handle) +{ + uid_t uid = 0; + int ret = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, handle); + if (ret != PMINFO_R_OK) { + _ERR("Failed to get pkginfo (%d)", ret); + return -1; + } + + return 0; +} + +int pkgmgrGetAppInfo(const std::string& appId, pkgmgrinfo_appinfo_h* handle) +{ + uid_t uid = 0; + int ret = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(appId.c_str(), uid, handle); + if (ret != PMINFO_R_OK) { + _ERR("Failed to get appinfo (%d)", ret); + return -1; + } + + return 0; +} + +int pkgmgrMDFilterForeach(pkgmgrinfo_appinfo_metadata_filter_h handle, + pkgmgrinfo_app_list_cb app_cb, + void *user_data) +{ + uid_t uid = 0; + int ret = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + + ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle, app_cb, user_data, uid); + if (ret != PMINFO_R_OK) { + _ERR("Failed to execute the metadata filter query (%d)", ret); + return -1; + } + + return 0; +} + +void printHWClockLog(const char* format, ...) +{ + char buf[1024] = {0,}; + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + prctl(PR_TASK_PERF_USER_TRACE, buf, strlen(buf)); +} + +const char* getNCDBStartupHook() +{ + return "/home/owner/share/tmp/sdk_tools/netcoredbg/ncdbhook.dll"; +} + +bool isNCDBStartupHookProvided() +{ + char *env = nullptr; + env = getenv("DOTNET_STARTUP_HOOKS"); + if (env == nullptr) + return false; + + // Note, `DOTNET_STARTUP_HOOKS` env could provide list of dlls with ':' delimiter, + // for example: "/path1/name1.dll:/path2/name2.dll" + while (*env != '\0') + { + const char *ncdbCur = getNCDBStartupHook(); + while (*ncdbCur != '\0' && *env != '\0' && *env != ':') + { + if (*ncdbCur != *env) + break; + + ncdbCur++; + env++; + + if (*ncdbCur == '\0' && (*env == '\0' || *env == ':')) + return true; + } + while (*env != '\0' && *env != ':') + { + env++; + } + if (*env == ':') + env++; + } + + return false; +}