launch_daemon: Added support for setting env.

* We cannot "source" files through a shell yet, though.
This commit is contained in:
Axel Dörfler
2015-07-22 20:44:07 +02:00
parent fb7dad2b49
commit ea19a80ed6
6 changed files with 123 additions and 9 deletions
+50
View File
@@ -6,6 +6,8 @@
#include "BaseJob.h"
#include <Message.h>
#include "Conditions.h"
@@ -59,3 +61,51 @@ BaseJob::CheckCondition(ConditionContext& context) const
return true;
}
const BStringList&
BaseJob::Environment() const
{
return fEnvironment;
}
const BStringList&
BaseJob::EnvironmentSourceFiles() const
{
return fSourceFiles;
}
void
BaseJob::SetEnvironment(const BMessage& message)
{
char* name;
type_code type;
int32 count;
for (int32 index = 0; message.GetInfo(B_STRING_TYPE, index, &name, &type,
&count) == B_OK; index++) {
if (strcmp(name, "from_file") == 0) {
const char* fromFile;
for (int32 fileIndex = 0; message.FindString(name, fileIndex,
&fromFile) == B_OK; fileIndex++) {
fSourceFiles.Add(fromFile);
}
continue;
}
BString variable = name;
variable << "='";
const char* argument;
for (int32 argumentIndex = 0; message.FindString(name, argumentIndex,
&argument) == B_OK; argumentIndex++) {
if (argumentIndex > 0)
variable << " ";
variable += argument;
}
variable << "'";
fEnvironment.Add(variable);
}
}
+8
View File
@@ -7,10 +7,12 @@
#include <Job.h>
#include <StringList.h>
using namespace BSupportKit;
class BMessage;
class Condition;
class ConditionContext;
@@ -27,8 +29,14 @@ public:
void SetCondition(::Condition* condition);
bool CheckCondition(ConditionContext& context) const;
const BStringList& Environment() const;
const BStringList& EnvironmentSourceFiles() const;
void SetEnvironment(const BMessage& message);
protected:
::Condition* fCondition;
BStringList fEnvironment;
BStringList fSourceFiles;
};
+42 -8
View File
@@ -11,6 +11,7 @@
#include <Message.h>
#include <Roster.h>
#include <RosterPrivate.h>
#include <user_group.h>
#include "Target.h"
@@ -303,26 +304,49 @@ Job::Port(const char* name) const
status_t
Job::Launch()
{
// Build environment
// TODO: resolve environment source files
std::vector<const char*> environment;
for (const char** variable = (const char**)environ; variable[0] != NULL;
variable++) {
environment.push_back(variable[0]);
}
if (Target() != NULL)
_AddStringList(environment, Target()->Environment());
_AddStringList(environment, Environment());
environment.push_back(NULL);
if (fArguments.IsEmpty()) {
// Launch by signature
BString signature("application/");
signature << Name();
return be_roster->Launch(signature.String(), (BMessage*)NULL, &fTeam);
return BRoster::Private().Launch(signature.String(), NULL, NULL,
0, NULL, environment.begin(), &fTeam);
}
// Build argument vector
entry_ref ref;
status_t status = get_ref_for_path(fArguments.StringAt(0).String(), &ref);
if (status != B_OK)
return status;
size_t count = fArguments.CountStrings() - 1;
const char* args[count + 1];
for (int32 i = 1; i < fArguments.CountStrings(); i++) {
args[i - 1] = fArguments.StringAt(i);
}
args[count] = NULL;
std::vector<const char*> args;
return be_roster->Launch(&ref, count, args, &fTeam);
size_t count = fArguments.CountStrings() - 1;
if (count > 0) {
for (int32 i = 1; i < fArguments.CountStrings(); i++) {
args.push_back(fArguments.StringAt(i));
}
args.push_back(NULL);
}
// Launch via entry_ref
return BRoster::Private().Launch(NULL, &ref, NULL, count, args.begin(),
environment.begin(), &fTeam);
}
@@ -380,3 +404,13 @@ Job::_AddRequirement(BJob* dependency)
return B_OK;
}
void
Job::_AddStringList(std::vector<const char*>& array, const BStringList& list)
{
int32 count = list.CountStrings();
for (int32 index = 0; index < count; index++) {
array.push_back(list.StringAt(index).String());
}
}
+3
View File
@@ -10,6 +10,7 @@
#include <map>
#include <set>
#include <vector>
#include <OS.h>
#include <StringList.h>
@@ -72,6 +73,8 @@ private:
Job& operator=(const Job& other);
void _DeletePorts();
status_t _AddRequirement(BJob* dependency);
void _AddStringList(std::vector<const char*>& array,
const BStringList& list);
private:
BStringList fArguments;
+13 -1
View File
@@ -104,6 +104,8 @@ private:
void _AddTarget(Target* target);
void _SetCondition(BaseJob* job,
const BMessage& message);
void _SetEnvironment(BaseJob* job,
const BMessage& message);
status_t _StartSession(const char* login);
@@ -523,6 +525,7 @@ LaunchDaemon::_AddTargets(BMessage& message)
}
_SetCondition(target, targetMessage);
_SetEnvironment(target, targetMessage);
_AddJobs(target, targetMessage);
}
}
@@ -600,7 +603,7 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
job->SetCreateDefaultPort(!message.GetBool("legacy", !service));
_SetCondition(job, message);
_SetEnvironment(job, message);
BMessage portMessage;
for (int32 index = 0;
@@ -715,6 +718,15 @@ LaunchDaemon::_SetCondition(BaseJob* job, const BMessage& message)
}
void
LaunchDaemon::_SetEnvironment(BaseJob* job, const BMessage& message)
{
BMessage environmentMessage;
if (message.FindMessage("env", &environmentMessage) == B_OK)
job->SetEnvironment(environmentMessage);
}
status_t
LaunchDaemon::_StartSession(const char* login)
{
+7
View File
@@ -110,6 +110,11 @@ const static settings_template kPortTemplate[] = {
{B_INT32_TYPE, "capacity", NULL},
};
const static settings_template kEnvTemplate[] = {
{B_STRING_TYPE, "from_file", NULL, true},
{B_STRING_TYPE, NULL, NULL},
};
const static settings_template kJobTemplate[] = {
{B_STRING_TYPE, "name", NULL, true},
{B_BOOL_TYPE, "disabled", NULL},
@@ -119,6 +124,7 @@ const static settings_template kJobTemplate[] = {
{B_MESSAGE_TYPE, "port", kPortTemplate},
{B_MESSAGE_TYPE, "if", kConditionTemplate},
{B_BOOL_TYPE, "no_safemode", NULL},
{B_MESSAGE_TYPE, "env", kEnvTemplate},
{0, NULL, NULL}
};
@@ -127,6 +133,7 @@ const static settings_template kTargetTemplate[] = {
{B_BOOL_TYPE, "reset", NULL},
{B_MESSAGE_TYPE, "if", kConditionTemplate},
{B_BOOL_TYPE, "no_safemode", NULL},
{B_MESSAGE_TYPE, "env", kEnvTemplate},
{B_MESSAGE_TYPE, "job", kJobTemplate},
{B_MESSAGE_TYPE, "service", kJobTemplate},
{0, NULL, NULL}