From d0276ac85a7f857ab9bf46596b0f527bc5c7e8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 11 Oct 2009 17:05:28 +0000 Subject: [PATCH] * Changed the way BRoster launches apps by signature: before, only the version info would decide which one to start. Now, this is only the last comparison taken into account: first, the search path will be checked, then, any apps in the /system folder are selected. Only after that, the version check will be performed. * This should improve the choices made, especially when you have a second set of binaries around due to having built Haiku. * This therefore also fixes that Haiku would wait for the wrong input_server on shutdown, as the registrar didn't (and rightly so) recognize the input_server as a system app since the wrong one had been started. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33528 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/app/Roster.cpp | 53 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index 1f926531e7..e38297247c 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -185,7 +185,11 @@ compare_version_infos(const version_info& info1, const version_info& info2) } -/*! \brief Compares the version of two applications. +/*! \brief Compares two applications to decide which one should be rather + returned as a query result. + + First, it checks if both apps are in the path, and prefers the app that + appears earlier. If both files have a version info, then those are compared. If one file has a version info, it is said to be greater. If both @@ -198,8 +202,51 @@ compare_version_infos(const version_info& info1, const version_info& info2) \c 0, if both are equal. */ static int32 -compare_app_versions(const entry_ref* app1, const entry_ref* app2) +compare_queried_apps(const entry_ref* app1, const entry_ref* app2) { + BPath path1(app1); + BPath path2(app2); + + // Check search path + + const char* searchPathes = getenv("PATH"); + if (searchPathes != NULL) { + char* searchBuffer = strdup(searchPathes); + if (searchBuffer != NULL) { + char* last; + const char* path = strtok_r(searchBuffer, ":", &last); + while (path != NULL) { + // Check if any app path matches + size_t length = strlen(path); + bool found1 = !strncmp(path, path1.Path(), length) + && path1.Path()[length] == '/'; + bool found2 = !strncmp(path, path2.Path(), length) + && path2.Path()[length] == '/';; + + if (found1 != found2) { + free(searchBuffer); + return found1 ? 1 : -1; + } + + path = strtok_r(NULL, ":", &last); + } + + free(searchBuffer); + } + } + + // Check system folder + + static const char* kSystemPath = "/boot/system/servers/"; + size_t length = strlen(kSystemPath); + + bool inSystem1 = !strncmp(kSystemPath, path1.Path(), length); + bool inSystem2 = !strncmp(kSystemPath, path2.Path(), length); + if (inSystem1 != inSystem2) + return inSystem1 ? 1 : -1; + + // Check version info + BFile file1, file2; BAppFileInfo appFileInfo1, appFileInfo2; file1.SetTo(app1, B_READ_ONLY); @@ -305,7 +352,7 @@ query_for_app(const char* signature, entry_ref* appRef) status_t foundAppError = B_OK; entry_ref ref; while (query.GetNextRef(&ref) == B_OK) { - if ((!appFound || compare_app_versions(appRef, &ref) < 0) + if ((!appFound || compare_queried_apps(appRef, &ref) < 0) && (foundAppError = can_app_be_used(&ref)) == B_OK) { *appRef = ref; appFound = true;