docs/ikteam: Delete most files.
[haiku.git] / src / servers / launch / BaseJob.cpp
blobef27fa134d158c0060bfbe75e3584e1d3535de7c
1 /*
2 * Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "BaseJob.h"
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
14 #include <Message.h>
16 #include "Conditions.h"
17 #include "Events.h"
20 BaseJob::BaseJob(const char* name)
22 BJob(name),
23 fCondition(NULL),
24 fEvent(NULL)
29 BaseJob::~BaseJob()
31 delete fCondition;
35 const char*
36 BaseJob::Name() const
38 return Title().String();
42 const ::Condition*
43 BaseJob::Condition() const
45 return fCondition;
49 ::Condition*
50 BaseJob::Condition()
52 return fCondition;
56 void
57 BaseJob::SetCondition(::Condition* condition)
59 fCondition = condition;
63 bool
64 BaseJob::CheckCondition(ConditionContext& context) const
66 if (fCondition != NULL)
67 return fCondition->Test(context);
69 return true;
73 const ::Event*
74 BaseJob::Event() const
76 return fEvent;
80 ::Event*
81 BaseJob::Event()
83 return fEvent;
87 void
88 BaseJob::SetEvent(::Event* event)
90 fEvent = event;
91 if (event != NULL)
92 event->SetOwner(this);
96 /*! Determines whether the events of this job has been triggered
97 already or not.
98 Note, if this job does not have any events, this method returns
99 \c true.
101 bool
102 BaseJob::EventHasTriggered() const
104 return Event() == NULL || Event()->Triggered();
108 const BStringList&
109 BaseJob::Environment() const
111 return fEnvironment;
115 BStringList&
116 BaseJob::Environment()
118 return fEnvironment;
122 const BStringList&
123 BaseJob::EnvironmentSourceFiles() const
125 return fSourceFiles;
129 BStringList&
130 BaseJob::EnvironmentSourceFiles()
132 return fSourceFiles;
136 void
137 BaseJob::SetEnvironment(const BMessage& message)
139 char* name;
140 type_code type;
141 int32 count;
142 for (int32 index = 0; message.GetInfo(B_STRING_TYPE, index, &name, &type,
143 &count) == B_OK; index++) {
144 if (strcmp(name, "from_script") == 0) {
145 const char* fromScript;
146 for (int32 scriptIndex = 0; message.FindString(name, scriptIndex,
147 &fromScript) == B_OK; scriptIndex++) {
148 fSourceFiles.Add(fromScript);
150 continue;
153 BString variable = name;
154 variable << "=";
156 const char* argument;
157 for (int32 argumentIndex = 0; message.FindString(name, argumentIndex,
158 &argument) == B_OK; argumentIndex++) {
159 if (argumentIndex > 0)
160 variable << " ";
161 variable += argument;
164 fEnvironment.Add(variable);
169 void
170 BaseJob::GetSourceFilesEnvironment(BStringList& environment)
172 int32 count = fSourceFiles.CountStrings();
173 for (int32 index = 0; index < count; index++) {
174 _GetSourceFileEnvironment(fSourceFiles.StringAt(index), environment);
179 /*! Gets the environment by evaluating the source files, and move that
180 environment to the static environment.
182 When this method returns, the source files list will be empty.
184 void
185 BaseJob::ResolveSourceFiles()
187 if (fSourceFiles.IsEmpty())
188 return;
190 GetSourceFilesEnvironment(fEnvironment);
191 fSourceFiles.MakeEmpty();
195 void
196 BaseJob::_GetSourceFileEnvironment(const char* script, BStringList& environment)
198 int pipes[2];
199 if (pipe(&pipes[0]) != 0) {
200 // TODO: log error
201 return;
204 pid_t child = fork();
205 if (child < 0) {
206 // TODO: log error
207 debug_printf("could not fork: %s\n", strerror(errno));
208 } else if (child == 0) {
209 // We're the child, redirect stdout
210 close(STDOUT_FILENO);
211 close(STDERR_FILENO);
212 dup2(pipes[1], STDOUT_FILENO);
213 dup2(pipes[1], STDERR_FILENO);
215 for (int32 i = 0; i < 2; i++)
216 close(pipes[i]);
218 BString command;
219 command.SetToFormat(". \"%s\"; export -p", script);
220 execl("/bin/sh", "/bin/sh", "-c", command.String(), NULL);
221 exit(1);
222 } else {
223 // Retrieve environment from child
225 close(pipes[1]);
227 BString line;
228 char buffer[4096];
229 while (true) {
230 ssize_t bytesRead = read(pipes[0], buffer, sizeof(buffer) - 1);
231 if (bytesRead <= 0)
232 break;
234 // Make sure the buffer is null terminated
235 buffer[bytesRead] = 0;
237 const char* chunk = buffer;
238 while (true) {
239 const char* separator = strchr(chunk, '\n');
240 if (separator == NULL) {
241 line.Append(chunk, bytesRead);
242 break;
244 line.Append(chunk, separator - chunk);
245 chunk = separator + 1;
247 _ParseExportVariable(environment, line);
248 line.Truncate(0);
251 if (!line.IsEmpty())
252 _ParseExportVariable(environment, line);
254 close(pipes[0]);
259 void
260 BaseJob::_ParseExportVariable(BStringList& environment, const BString& line)
262 if (!line.StartsWith("export "))
263 return;
265 int separator = line.FindFirst("=\"");
266 if (separator < 0)
267 return;
269 BString variable;
270 line.CopyInto(variable, 7, separator - 7);
272 BString value;
273 line.CopyInto(value, separator + 2, line.Length() - separator - 3);
275 variable << "=" << value;
276 environment.Add(variable);