1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: AppMisc.cpp 23 // Author: Ingo Weinhold (bonefish@users.sf.net) 24 // Description: Miscellaneous private functionality. 25 //------------------------------------------------------------------------------ 26 27 #include <string.h> 28 #include <sys/utsname.h> 29 30 #include <AppMisc.h> 31 #include <Entry.h> 32 #include <image.h> 33 #include <OS.h> 34 35 namespace BPrivate { 36 37 // get_app_path 38 /*! \brief Returns the path to the application's executable. 39 \param buffer A pointer to a pre-allocated character array of at least 40 size B_PATH_NAME_LENGTH to be filled in by this function. 41 \return 42 - \c B_OK: Everything went fine. 43 - \c B_BAD_VALUE: \c NULL \a buffer. 44 - another error code 45 */ 46 status_t 47 get_app_path(char *buffer) 48 { 49 // The only way to get the path to the application's executable seems to 50 // be to get an image_info of its image, which also contains a path. 51 // Several images may belong to the team (libraries, add-ons), but only 52 // the one in question should be typed B_APP_IMAGE. 53 status_t error = (buffer ? B_OK : B_BAD_VALUE); 54 image_info info; 55 int32 cookie = 0; 56 bool found = false; 57 if (error == B_OK) { 58 while (!found && get_next_image_info(0, &cookie, &info) == B_OK) { 59 if (info.type == B_APP_IMAGE) { 60 strncpy(buffer, info.name, B_PATH_NAME_LENGTH - 1); 61 buffer[B_PATH_NAME_LENGTH - 1] = 0; 62 found = true; 63 } 64 } 65 } 66 if (error == B_OK && !found) 67 error = B_ENTRY_NOT_FOUND; 68 return error; 69 } 70 71 // get_app_ref 72 /*! \brief Returns an entry_ref referring to the application's exectable. 73 \param ref A pointer to a pre-allocated entry_ref to be initialized 74 to an entry_ref referring to the application's executable. 75 \param traverse If \c true, the function traverses symbolic links. 76 \return 77 - \c B_OK: Everything went fine. 78 - \c B_BAD_VALUE: \c NULL \a ref. 79 - another error code 80 */ 81 status_t 82 get_app_ref(entry_ref *ref, bool traverse) 83 { 84 status_t error = (ref ? B_OK : B_BAD_VALUE); 85 char appFilePath[B_PATH_NAME_LENGTH]; 86 if (error == B_OK) 87 error = get_app_path(appFilePath); 88 if (error == B_OK) { 89 BEntry entry(appFilePath, traverse); 90 error = entry.GetRef(ref); 91 } 92 return error; 93 } 94 95 // current_team 96 /*! \brief Returns the ID of the current team. 97 \return The ID of the current team. 98 */ 99 team_id 100 current_team() 101 { 102 team_id team = -1; 103 thread_info info; 104 if (get_thread_info(find_thread(NULL), &info) == B_OK) 105 team = info.team; 106 return team; 107 } 108 109 // main_thread_for 110 /*! Returns the ID of the supplied team's main thread. 111 \param team The team. 112 \return 113 - The thread ID of the supplied team's main thread 114 - \c B_BAD_TEAM_ID: The supplied team ID does not identify a running team. 115 - another error code 116 */ 117 thread_id 118 main_thread_for(team_id team) 119 { 120 // For I can't find any trace of how to explicitly get the main thread, 121 // I assume the main thread is the one with the least thread ID. 122 thread_id thread = B_BAD_TEAM_ID; 123 int32 cookie = 0; 124 thread_info info; 125 while (get_next_thread_info(team, &cookie, &info) == B_OK) { 126 if (thread < 0 || info.thread < thread) 127 thread = info.thread; 128 } 129 return thread; 130 } 131 132 // is_running_on_haiku 133 /*! Returns whether we're running under Haiku natively. 134 135 This is a runtime check for components compiled only once for both 136 BeOS and Haiku and nevertheless need to behave differently on the two 137 systems, like the registrar, which uses another MIME database directory 138 under BeOS. 139 140 \return \c true, if we're running under Haiku, \c false otherwise. 141 */ 142 bool 143 is_running_on_haiku() 144 { 145 struct utsname info; 146 return (uname(&info) == 0 && strcmp(info.sysname, "Haiku") == 0); 147 } 148 149 } // namespace BPrivate 150 151