launch_daemon: Added support for setting env.
* We cannot "source" files through a shell yet, though.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user