launch_daemon: Added basic support for conditions.
* Admittedly not very well thought out, but it should be good enough for now; it doesn't really make sense to initialize jobs that is never run due to failed conditions. * Job, and Target now have a common base class BaseJob that deals with the conditions.
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "BaseJob.h"
|
||||||
|
|
||||||
|
#include "Conditions.h"
|
||||||
|
|
||||||
|
|
||||||
|
BaseJob::BaseJob(const char* name)
|
||||||
|
:
|
||||||
|
BJob(name),
|
||||||
|
fCondition(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
BaseJob::Name() const
|
||||||
|
{
|
||||||
|
return Title().String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const ::Condition*
|
||||||
|
BaseJob::Condition() const
|
||||||
|
{
|
||||||
|
return fCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseJob::SetCondition(const ::Condition* condition)
|
||||||
|
{
|
||||||
|
fCondition = condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BaseJob::CheckCondition(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
if (fCondition != NULL)
|
||||||
|
return fCondition->Test(context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef BASE_JOB_H
|
||||||
|
#define BASE_JOB_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Job.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace BSupportKit;
|
||||||
|
|
||||||
|
class Condition;
|
||||||
|
class ConditionContext;
|
||||||
|
|
||||||
|
|
||||||
|
class BaseJob : public BJob {
|
||||||
|
public:
|
||||||
|
BaseJob(const char* name);
|
||||||
|
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
|
const ::Condition* Condition() const;
|
||||||
|
void SetCondition(const ::Condition* condition);
|
||||||
|
bool CheckCondition(ConditionContext& context) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const ::Condition* fCondition;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BASE_JOB_H
|
||||||
@@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Conditions.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <StringList.h>
|
||||||
|
|
||||||
|
#include <DiskDevice.h>
|
||||||
|
#include <DiskDeviceRoster.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ConditionContainer : public Condition {
|
||||||
|
protected:
|
||||||
|
ConditionContainer(const BMessage& args);
|
||||||
|
|
||||||
|
void AddCondition(Condition* condition);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BObjectList<Condition> fConditions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AndCondition : public ConditionContainer {
|
||||||
|
public:
|
||||||
|
AndCondition(const BMessage& args);
|
||||||
|
|
||||||
|
virtual bool Test(ConditionContext& context) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class OrCondition : public ConditionContainer {
|
||||||
|
public:
|
||||||
|
OrCondition(const BMessage& args);
|
||||||
|
|
||||||
|
virtual bool Test(ConditionContext& context) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class NotCondition : public ConditionContainer {
|
||||||
|
public:
|
||||||
|
NotCondition(const BMessage& args);
|
||||||
|
|
||||||
|
virtual bool Test(ConditionContext& context) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SafeModeCondition : public Condition {
|
||||||
|
public:
|
||||||
|
virtual bool Test(ConditionContext& context) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ReadOnlyCondition : public Condition {
|
||||||
|
public:
|
||||||
|
ReadOnlyCondition(const BMessage& args);
|
||||||
|
|
||||||
|
virtual bool Test(ConditionContext& context) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
dev_t fDevice;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FileExistsCondition : public Condition {
|
||||||
|
public:
|
||||||
|
FileExistsCondition(const BMessage& args);
|
||||||
|
|
||||||
|
virtual bool Test(ConditionContext& context) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BStringList fPaths;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static Condition*
|
||||||
|
create_condition(const char* name, const BMessage& args)
|
||||||
|
{
|
||||||
|
if (strcmp(name, "and") == 0)
|
||||||
|
return new AndCondition(args);
|
||||||
|
if (strcmp(name, "or") == 0)
|
||||||
|
return new OrCondition(args);
|
||||||
|
if (strcmp(name, "not") == 0)
|
||||||
|
return new NotCondition(args);
|
||||||
|
|
||||||
|
if (strcmp(name, "safemode") == 0)
|
||||||
|
return new SafeModeCondition();
|
||||||
|
if (strcmp(name, "read_only") == 0)
|
||||||
|
return new ReadOnlyCondition(args);
|
||||||
|
if (strcmp(name, "file_exists") == 0)
|
||||||
|
return new FileExistsCondition(args);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
Condition::Condition()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Condition::~Condition()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
ConditionContainer::ConditionContainer(const BMessage& args)
|
||||||
|
{
|
||||||
|
char* name;
|
||||||
|
type_code type;
|
||||||
|
int32 count;
|
||||||
|
for (int32 index = 0; args.GetInfo(B_MESSAGE_TYPE, index, &name, &type,
|
||||||
|
&count) == B_OK; index++) {
|
||||||
|
BMessage message;
|
||||||
|
for (int32 messageIndex = 0; args.FindMessage(name, messageIndex,
|
||||||
|
&message) == B_OK; messageIndex++) {
|
||||||
|
AddCondition(create_condition(name, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ConditionContainer::AddCondition(Condition* condition)
|
||||||
|
{
|
||||||
|
if (condition != NULL)
|
||||||
|
fConditions.AddItem(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - and
|
||||||
|
|
||||||
|
|
||||||
|
AndCondition::AndCondition(const BMessage& args)
|
||||||
|
:
|
||||||
|
ConditionContainer(args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AndCondition::Test(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
for (int32 index = 0; index < fConditions.CountItems(); index++) {
|
||||||
|
Condition* condition = fConditions.ItemAt(index);
|
||||||
|
if (!condition->Test(context))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - or
|
||||||
|
|
||||||
|
|
||||||
|
OrCondition::OrCondition(const BMessage& args)
|
||||||
|
:
|
||||||
|
ConditionContainer(args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
OrCondition::Test(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
if (fConditions.IsEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (int32 index = 0; index < fConditions.CountItems(); index++) {
|
||||||
|
Condition* condition = fConditions.ItemAt(index);
|
||||||
|
if (condition->Test(context))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - or
|
||||||
|
|
||||||
|
|
||||||
|
NotCondition::NotCondition(const BMessage& args)
|
||||||
|
:
|
||||||
|
ConditionContainer(args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
NotCondition::Test(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
for (int32 index = 0; index < fConditions.CountItems(); index++) {
|
||||||
|
Condition* condition = fConditions.ItemAt(index);
|
||||||
|
if (condition->Test(context))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - safemode
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SafeModeCondition::Test(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
return context.IsSafeMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - read_only
|
||||||
|
|
||||||
|
|
||||||
|
ReadOnlyCondition::ReadOnlyCondition(const BMessage& args)
|
||||||
|
{
|
||||||
|
fDevice = dev_for_path(args.GetString("args", "/boot"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ReadOnlyCondition::Test(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
BVolume volume;
|
||||||
|
status_t status = volume.SetTo(fDevice);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to get BVolume for device %" B_PRIdDEV
|
||||||
|
": %s\n", fDevice, strerror(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BDiskDeviceRoster roster;
|
||||||
|
BDiskDevice diskDevice;
|
||||||
|
BPartition* partition;
|
||||||
|
status = roster.FindPartitionByVolume(volume, &diskDevice, &partition);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to get partition for device %" B_PRIdDEV
|
||||||
|
": %s\n", fDevice, strerror(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return partition->IsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - file_exists
|
||||||
|
|
||||||
|
|
||||||
|
FileExistsCondition::FileExistsCondition(const BMessage& args)
|
||||||
|
{
|
||||||
|
for (int32 index = 0;
|
||||||
|
const char* path = args.GetString("args", index, NULL); index++) {
|
||||||
|
fPaths.Add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FileExistsCondition::Test(ConditionContext& context) const
|
||||||
|
{
|
||||||
|
for (int32 index = 0; index < fPaths.CountStrings(); index++) {
|
||||||
|
BEntry entry;
|
||||||
|
if (entry.SetTo(fPaths.StringAt(index)) != B_OK
|
||||||
|
|| !entry.Exists())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ Condition*
|
||||||
|
Conditions::FromMessage(const BMessage& message)
|
||||||
|
{
|
||||||
|
return create_condition("and", message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef CONDITIONS_H
|
||||||
|
#define CONDITIONS_H
|
||||||
|
|
||||||
|
|
||||||
|
class BMessage;
|
||||||
|
|
||||||
|
|
||||||
|
class ConditionContext {
|
||||||
|
public:
|
||||||
|
virtual bool IsSafeMode() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Condition {
|
||||||
|
public:
|
||||||
|
Condition();
|
||||||
|
virtual ~Condition();
|
||||||
|
|
||||||
|
virtual bool Test(ConditionContext& context) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Conditions {
|
||||||
|
public:
|
||||||
|
static Condition* FromMessage(const BMessage& message);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CONDITIONS_H
|
||||||
@@ -8,6 +8,9 @@ UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
|
|||||||
Server launch_daemon
|
Server launch_daemon
|
||||||
:
|
:
|
||||||
LaunchDaemon.cpp
|
LaunchDaemon.cpp
|
||||||
|
|
||||||
|
BaseJob.cpp
|
||||||
|
Conditions.cpp
|
||||||
Job.cpp
|
Job.cpp
|
||||||
SettingsParser.cpp
|
SettingsParser.cpp
|
||||||
Target.cpp
|
Target.cpp
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
Job::Job(const char* name)
|
Job::Job(const char* name)
|
||||||
:
|
:
|
||||||
BJob(name),
|
BaseJob(name),
|
||||||
fEnabled(true),
|
fEnabled(true),
|
||||||
fService(false),
|
fService(false),
|
||||||
fCreateDefaultPort(false),
|
fCreateDefaultPort(false),
|
||||||
@@ -30,7 +30,7 @@ Job::Job(const char* name)
|
|||||||
|
|
||||||
Job::Job(const Job& other)
|
Job::Job(const Job& other)
|
||||||
:
|
:
|
||||||
BJob(other.Name()),
|
BaseJob(other.Name()),
|
||||||
fEnabled(other.IsEnabled()),
|
fEnabled(other.IsEnabled()),
|
||||||
fService(other.IsService()),
|
fService(other.IsService()),
|
||||||
fCreateDefaultPort(other.CreateDefaultPort()),
|
fCreateDefaultPort(other.CreateDefaultPort()),
|
||||||
@@ -39,6 +39,8 @@ Job::Job(const Job& other)
|
|||||||
fTeam(-1),
|
fTeam(-1),
|
||||||
fTarget(other.Target())
|
fTarget(other.Target())
|
||||||
{
|
{
|
||||||
|
fCondition = other.fCondition;
|
||||||
|
|
||||||
for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
|
for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
|
||||||
AddArgument(other.Arguments().StringAt(i));
|
AddArgument(other.Arguments().StringAt(i));
|
||||||
|
|
||||||
@@ -63,13 +65,6 @@ Job::~Job()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
|
||||||
Job::Name() const
|
|
||||||
{
|
|
||||||
return Title().String();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Job::IsEnabled() const
|
Job::IsEnabled() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#define JOB_H
|
#define JOB_H
|
||||||
|
|
||||||
|
|
||||||
#include <Job.h>
|
#include "BaseJob.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
@@ -25,14 +25,12 @@ class Target;
|
|||||||
typedef std::map<BString, BMessage> PortMap;
|
typedef std::map<BString, BMessage> PortMap;
|
||||||
|
|
||||||
|
|
||||||
class Job : public BJob {
|
class Job : public BaseJob {
|
||||||
public:
|
public:
|
||||||
Job(const char* name);
|
Job(const char* name);
|
||||||
Job(const Job& other);
|
Job(const Job& other);
|
||||||
virtual ~Job();
|
virtual ~Job();
|
||||||
|
|
||||||
const char* Name() const;
|
|
||||||
|
|
||||||
bool IsEnabled() const;
|
bool IsEnabled() const;
|
||||||
void SetEnabled(bool enable);
|
void SetEnabled(bool enable);
|
||||||
|
|
||||||
@@ -89,6 +87,7 @@ private:
|
|||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
team_id fTeam;
|
team_id fTeam;
|
||||||
::Target* fTarget;
|
::Target* fTarget;
|
||||||
|
::Condition* fCondition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "multiuser_utils.h"
|
#include "multiuser_utils.h"
|
||||||
|
|
||||||
|
#include "Conditions.h"
|
||||||
#include "InitRealTimeClockJob.h"
|
#include "InitRealTimeClockJob.h"
|
||||||
#include "InitSharedMemoryDirectoryJob.h"
|
#include "InitSharedMemoryDirectoryJob.h"
|
||||||
#include "InitTemporaryDirectoryJob.h"
|
#include "InitTemporaryDirectoryJob.h"
|
||||||
@@ -67,7 +68,7 @@ typedef std::map<uid_t, Session*> SessionMap;
|
|||||||
typedef std::map<BString, Target*> TargetMap;
|
typedef std::map<BString, Target*> TargetMap;
|
||||||
|
|
||||||
|
|
||||||
class LaunchDaemon : public BServer, public Finder {
|
class LaunchDaemon : public BServer, public Finder, public ConditionContext {
|
||||||
public:
|
public:
|
||||||
LaunchDaemon(bool userMode, status_t& error);
|
LaunchDaemon(bool userMode, status_t& error);
|
||||||
virtual ~LaunchDaemon();
|
virtual ~LaunchDaemon();
|
||||||
@@ -76,6 +77,8 @@ public:
|
|||||||
virtual Target* FindTarget(const char* name) const;
|
virtual Target* FindTarget(const char* name) const;
|
||||||
Session* FindSession(uid_t user) const;
|
Session* FindSession(uid_t user) const;
|
||||||
|
|
||||||
|
virtual bool IsSafeMode() const;
|
||||||
|
|
||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
@@ -104,8 +107,6 @@ private:
|
|||||||
void _InitSystem();
|
void _InitSystem();
|
||||||
void _AddInitJob(BJob* job);
|
void _AddInitJob(BJob* job);
|
||||||
|
|
||||||
bool _IsSafeMode() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JobMap fJobs;
|
JobMap fJobs;
|
||||||
TargetMap fTargets;
|
TargetMap fTargets;
|
||||||
@@ -205,6 +206,13 @@ LaunchDaemon::FindSession(uid_t user) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LaunchDaemon::IsSafeMode() const
|
||||||
|
{
|
||||||
|
return fSafeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LaunchDaemon::ReadyToRun()
|
LaunchDaemon::ReadyToRun()
|
||||||
{
|
{
|
||||||
@@ -250,6 +258,12 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
reply.what = B_NAME_NOT_FOUND;
|
reply.what = B_NAME_NOT_FOUND;
|
||||||
|
} else if (!job->IsLaunched() && !job->CheckCondition(*this)) {
|
||||||
|
// The job exists, but cannot be started yet, as its
|
||||||
|
// conditions are not met; don't make it available yet
|
||||||
|
// TODO: we may not want to initialize jobs with conditions
|
||||||
|
// that aren't met yet
|
||||||
|
reply.what = B_NO_INIT;
|
||||||
} else {
|
} else {
|
||||||
// If the job has not been launched yet, we'll pass on our
|
// If the job has not been launched yet, we'll pass on our
|
||||||
// team here. The rationale behind this is that this team
|
// team here. The rationale behind this is that this team
|
||||||
@@ -547,7 +561,7 @@ LaunchDaemon::_InitJobs()
|
|||||||
JobMap::iterator remove = iterator++;
|
JobMap::iterator remove = iterator++;
|
||||||
|
|
||||||
status_t status = B_NO_INIT;
|
status_t status = B_NO_INIT;
|
||||||
if (job->IsEnabled() && (!_IsSafeMode() || job->LaunchInSafeMode())) {
|
if (job->IsEnabled() && (!IsSafeMode() || job->LaunchInSafeMode())) {
|
||||||
std::set<BString> dependencies;
|
std::set<BString> dependencies;
|
||||||
status = job->Init(*this, dependencies);
|
status = job->Init(*this, dependencies);
|
||||||
}
|
}
|
||||||
@@ -570,6 +584,9 @@ LaunchDaemon::_InitJobs()
|
|||||||
void
|
void
|
||||||
LaunchDaemon::_LaunchJobs(Target* target)
|
LaunchDaemon::_LaunchJobs(Target* target)
|
||||||
{
|
{
|
||||||
|
if (target != NULL && !target->CheckCondition(*this))
|
||||||
|
return;
|
||||||
|
|
||||||
for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();
|
for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();
|
||||||
iterator++) {
|
iterator++) {
|
||||||
Job* job = iterator->second;
|
Job* job = iterator->second;
|
||||||
@@ -582,7 +599,7 @@ LaunchDaemon::_LaunchJobs(Target* target)
|
|||||||
void
|
void
|
||||||
LaunchDaemon::_AddLaunchJob(Job* job)
|
LaunchDaemon::_AddLaunchJob(Job* job)
|
||||||
{
|
{
|
||||||
if (!job->IsLaunched())
|
if (!job->IsLaunched() && job->CheckCondition(*this))
|
||||||
fJobQueue.AddJob(job);
|
fJobQueue.AddJob(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +694,7 @@ LaunchDaemon::_SetupEnvironment()
|
|||||||
{
|
{
|
||||||
// Determine safemode kernel option
|
// Determine safemode kernel option
|
||||||
BString safemode = "SAFEMODE=";
|
BString safemode = "SAFEMODE=";
|
||||||
safemode << (_IsSafeMode() ? "yes" : "no");
|
safemode << (IsSafeMode() ? "yes" : "no");
|
||||||
|
|
||||||
putenv(safemode.String());
|
putenv(safemode.String());
|
||||||
}
|
}
|
||||||
@@ -704,13 +721,6 @@ LaunchDaemon::_AddInitJob(BJob* job)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
LaunchDaemon::_IsSafeMode() const
|
|
||||||
{
|
|
||||||
return fSafeMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,11 @@
|
|||||||
|
|
||||||
Target::Target(const char* name)
|
Target::Target(const char* name)
|
||||||
:
|
:
|
||||||
BJob(name)
|
BaseJob(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
|
||||||
Target::Name() const
|
|
||||||
{
|
|
||||||
return Title().String();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Target::AddData(const char* name, BMessage& data)
|
Target::AddData(const char* name, BMessage& data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,19 +6,18 @@
|
|||||||
#define TARGET_H
|
#define TARGET_H
|
||||||
|
|
||||||
|
|
||||||
#include <Job.h>
|
#include "BaseJob.h"
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace BSupportKit;
|
using namespace BSupportKit;
|
||||||
|
|
||||||
|
|
||||||
class Target : public BJob {
|
class Target : public BaseJob {
|
||||||
public:
|
public:
|
||||||
Target(const char* name);
|
Target(const char* name);
|
||||||
|
|
||||||
const char* Name() const;
|
|
||||||
|
|
||||||
status_t AddData(const char* name, BMessage& data);
|
status_t AddData(const char* name, BMessage& data);
|
||||||
const BMessage& Data() const
|
const BMessage& Data() const
|
||||||
{ return fData; }
|
{ return fData; }
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ SettingsParserTest::TestConditionsMultiLineFlatNotWithArgs()
|
|||||||
{
|
{
|
||||||
BMessage message;
|
BMessage message;
|
||||||
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
|
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
|
||||||
"\tnot file_exists one\n"
|
"\tnot file_exists one two\n"
|
||||||
"}\n", message));
|
"}\n", message));
|
||||||
|
|
||||||
BMessage subMessage;
|
BMessage subMessage;
|
||||||
@@ -151,7 +151,9 @@ SettingsParserTest::TestConditionsMultiLineFlatNotWithArgs()
|
|||||||
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists", &args));
|
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists", &args));
|
||||||
CPPUNIT_ASSERT_EQUAL(BString("one"),
|
CPPUNIT_ASSERT_EQUAL(BString("one"),
|
||||||
BString(args.GetString("args", 0, "-")));
|
BString(args.GetString("args", 0, "-")));
|
||||||
CPPUNIT_ASSERT_EQUAL(1, args.CountNames(B_ANY_TYPE));
|
CPPUNIT_ASSERT_EQUAL(BString("two"),
|
||||||
|
BString(args.GetString("args", 1, "-")));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(2, args.CountNames(B_ANY_TYPE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user