btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / debug / TeamDebugger.cpp
blobeb0abe65e924f7d866f6673e3d18ef1c0c171a0c
1 /*
2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <TeamDebugger.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/stat.h>
13 #include <string.h>
15 #include <Path.h>
16 #include <String.h>
18 #include <libroot_private.h>
19 #include <syscalls.h>
22 BTeamDebugger::BTeamDebugger()
24 fDebuggerPort(-1)
29 BTeamDebugger::~BTeamDebugger()
31 Uninstall();
35 status_t
36 BTeamDebugger::Install(team_id team)
38 Uninstall();
40 // create a debugger port
41 char name[B_OS_NAME_LENGTH];
42 snprintf(name, sizeof(name), "debugger for team %" B_PRId32, team);
43 fDebuggerPort = create_port(100, name);
44 if (fDebuggerPort < 0)
45 return fDebuggerPort;
47 port_id nubPort = install_team_debugger(team, fDebuggerPort);
48 if (nubPort < 0) {
49 delete_port(fDebuggerPort);
50 fDebuggerPort = -1;
51 return nubPort;
54 status_t error = BDebugContext::Init(team, nubPort);
55 if (error != B_OK) {
56 remove_team_debugger(team);
57 delete_port(fDebuggerPort);
58 fDebuggerPort = -1;
59 return error;
62 return B_OK;
66 status_t
67 BTeamDebugger::Uninstall()
69 if (Team() < 0)
70 return B_BAD_VALUE;
72 remove_team_debugger(Team());
74 delete_port(fDebuggerPort);
76 BDebugContext::Uninit();
78 fDebuggerPort = -1;
80 return B_OK;
84 status_t
85 BTeamDebugger::LoadProgram(const char* const* args, int32 argCount,
86 bool traceLoading)
88 // load the program
89 thread_id thread = _LoadProgram(args, argCount, traceLoading);
90 if (thread < 0)
91 return thread;
93 // install the debugger
94 status_t error = Install(thread);
95 if (error != B_OK) {
96 kill_team(thread);
97 return error;
100 return B_OK;
104 status_t
105 BTeamDebugger::ReadDebugMessage(int32& _messageCode,
106 debug_debugger_message_data& messageBuffer)
108 ssize_t bytesRead = read_port(fDebuggerPort, &_messageCode, &messageBuffer,
109 sizeof(messageBuffer));
110 if (bytesRead < 0)
111 return bytesRead;
113 return B_OK;
118 /*static*/ thread_id
119 BTeamDebugger::_LoadProgram(const char* const* args, int32 argCount,
120 bool traceLoading)
122 // clone the argument vector so that we can change it
123 const char** mutableArgs = new const char*[argCount];
124 for (int i = 0; i < argCount; i++)
125 mutableArgs[i] = args[i];
127 // resolve the program path
128 BPath programPath;
129 status_t error = _FindProgram(args[0], programPath);
130 if (error != B_OK) {
131 delete[] mutableArgs;
132 return error;
134 mutableArgs[0] = programPath.Path();
136 // count environment variables
137 int32 envCount = 0;
138 while (environ[envCount] != NULL)
139 envCount++;
141 // flatten the program args and environment
142 char** flatArgs = NULL;
143 size_t flatArgsSize;
144 error = __flatten_process_args(mutableArgs, argCount, environ, &envCount,
145 mutableArgs[0], &flatArgs, &flatArgsSize);
147 // load the program
148 thread_id thread;
149 if (error == B_OK) {
150 thread = _kern_load_image(flatArgs, flatArgsSize, argCount, envCount,
151 B_NORMAL_PRIORITY, (traceLoading ? 0 : B_WAIT_TILL_LOADED), -1, 0);
153 free(flatArgs);
154 } else
155 thread = error;
157 delete[] mutableArgs;
159 return thread;
163 /*static*/ status_t
164 BTeamDebugger::_FindProgram(const char* programName, BPath& resolvedPath)
166 // If the program name is absolute, then there's nothing to do.
167 // If the program name consists of more than one path element, then we
168 // consider it a relative path and don't search in PATH either.
169 if (*programName == '/' || strchr(programName, '/'))
170 return resolvedPath.SetTo(programName);
172 // get the PATH environment variable
173 const char* paths = getenv("PATH");
174 if (!paths)
175 return B_ENTRY_NOT_FOUND;
177 // iterate through the paths
178 do {
179 const char* pathEnd = strchr(paths, ':');
180 int pathLen = (pathEnd ? pathEnd - paths : strlen(paths));
182 // We skip empty paths.
183 if (pathLen > 0) {
184 // get the program path
185 BString directory(paths, pathLen);
186 if (directory.Length() == 0)
187 return B_NO_MEMORY;
189 BPath path;
190 status_t error = path.SetTo(directory, programName);
191 if (error != B_OK)
192 continue;
194 // stat() the path to be sure, there is a file
195 struct stat st;
196 if (stat(path.Path(), &st) == 0 && S_ISREG(st.st_mode)) {
197 resolvedPath = path;
198 return B_OK;
202 paths = (pathEnd ? pathEnd + 1 : NULL);
203 } while (paths);
205 // not found in PATH
206 return B_ENTRY_NOT_FOUND;