1 /* 2 * Copyright 2001-2007, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold, bonefish@@users.sf.net 7 */ 8 9 10 #include <AppMisc.h> 11 #include <Entry.h> 12 #include <image.h> 13 #include <OS.h> 14 15 #include <string.h> 16 #include <sys/utsname.h> 17 18 19 namespace BPrivate { 20 21 BLocker gInitializationLock("global init lock"); 22 23 24 // get_app_path 25 /*! \brief Returns the path to an application's executable. 26 \param team The application's team ID. 27 \param buffer A pointer to a pre-allocated character array of at least 28 size B_PATH_NAME_LENGTH to be filled in by this function. 29 \return 30 - \c B_OK: Everything went fine. 31 - \c B_BAD_VALUE: \c NULL \a buffer. 32 - another error code 33 */ 34 status_t 35 get_app_path(team_id team, char *buffer) 36 { 37 // The only way to get the path to the application's executable seems to 38 // be to get an image_info of its image, which also contains a path. 39 // Several images may belong to the team (libraries, add-ons), but only 40 // the one in question should be typed B_APP_IMAGE. 41 if (!buffer) 42 return B_BAD_VALUE; 43 44 image_info info; 45 int32 cookie = 0; 46 47 while (get_next_image_info(team, &cookie, &info) == B_OK) { 48 if (info.type == B_APP_IMAGE) { 49 strlcpy(buffer, info.name, B_PATH_NAME_LENGTH - 1); 50 return B_OK; 51 } 52 } 53 54 return B_ENTRY_NOT_FOUND; 55 } 56 57 // get_app_path 58 /*! \brief Returns the path to the application's executable. 59 \param buffer A pointer to a pre-allocated character array of at least 60 size B_PATH_NAME_LENGTH to be filled in by this function. 61 \return 62 - \c B_OK: Everything went fine. 63 - \c B_BAD_VALUE: \c NULL \a buffer. 64 - another error code 65 */ 66 status_t 67 get_app_path(char *buffer) 68 { 69 return get_app_path(B_CURRENT_TEAM, buffer); 70 } 71 72 // get_app_ref 73 /*! \brief Returns an entry_ref referring to an application's executable. 74 \param team The application's team ID. 75 \param ref A pointer to a pre-allocated entry_ref to be initialized 76 to an entry_ref referring to the application's executable. 77 \param traverse If \c true, the function traverses symbolic links. 78 \return 79 - \c B_OK: Everything went fine. 80 - \c B_BAD_VALUE: \c NULL \a ref. 81 - another error code 82 */ 83 status_t 84 get_app_ref(team_id team, entry_ref *ref, bool traverse) 85 { 86 status_t error = (ref ? B_OK : B_BAD_VALUE); 87 char appFilePath[B_PATH_NAME_LENGTH]; 88 89 if (error == B_OK) 90 error = get_app_path(team, appFilePath); 91 92 if (error == B_OK) { 93 BEntry entry(appFilePath, traverse); 94 error = entry.GetRef(ref); 95 } 96 97 return error; 98 } 99 100 // get_app_ref 101 /*! \brief Returns an entry_ref referring to the application's executable. 102 \param ref A pointer to a pre-allocated entry_ref to be initialized 103 to an entry_ref referring to the application's executable. 104 \param traverse If \c true, the function traverses symbolic links. 105 \return 106 - \c B_OK: Everything went fine. 107 - \c B_BAD_VALUE: \c NULL \a ref. 108 - another error code 109 */ 110 status_t 111 get_app_ref(entry_ref *ref, bool traverse) 112 { 113 return get_app_ref(B_CURRENT_TEAM, ref, traverse); 114 } 115 116 // current_team 117 /*! \brief Returns the ID of the current team. 118 \return The ID of the current team. 119 */ 120 team_id 121 current_team() 122 { 123 static team_id team = -1; 124 if (team < 0) { 125 thread_info info; 126 if (get_thread_info(find_thread(NULL), &info) == B_OK) 127 team = info.team; 128 } 129 return team; 130 } 131 132 // main_thread_for 133 /*! Returns the ID of the supplied team's main thread. 134 \param team The team. 135 \return 136 - The thread ID of the supplied team's main thread 137 - \c B_BAD_TEAM_ID: The supplied team ID does not identify a running team. 138 - another error code 139 */ 140 thread_id 141 main_thread_for(team_id team) 142 { 143 #ifdef __HAIKU__ 144 // Under Haiku the team ID is equal to it's main thread ID. We just get 145 // a team info to verify the existence of the team. 146 team_info info; 147 status_t error = get_team_info(team, &info); 148 return (error == B_OK ? team : error); 149 #else 150 // For I can't find any trace of how to explicitly get the main thread, 151 // I assume the main thread is the one with the least thread ID. 152 thread_id thread = B_BAD_TEAM_ID; 153 int32 cookie = 0; 154 thread_info info; 155 while (get_next_thread_info(team, &cookie, &info) == B_OK) { 156 if (thread < 0 || info.thread < thread) 157 thread = info.thread; 158 } 159 return thread; 160 #endif 161 } 162 163 // is_running_on_haiku 164 /*! Returns whether we're running under Haiku natively. 165 166 This is a runtime check for components compiled only once for both 167 BeOS and Haiku and nevertheless need to behave differently on the two 168 systems, like the registrar, which uses another MIME database directory 169 under BeOS. 170 171 \return \c true, if we're running under Haiku, \c false otherwise. 172 */ 173 bool 174 is_running_on_haiku() 175 { 176 struct utsname info; 177 return (uname(&info) == 0 && strcmp(info.sysname, "Haiku") == 0); 178 } 179 180 // is_app_showing_modal_window 181 /*! \brief Returns whether the application identified by the supplied 182 \c team_id is currently showing a modal window. 183 \param team the ID of the application in question. 184 \return \c true, if the application is showing a modal window, \c false 185 otherwise. 186 */ 187 bool 188 is_app_showing_modal_window(team_id team) 189 { 190 // TODO: Implement! 191 return true; 192 } 193 194 } // namespace BPrivate 195 196