launch_daemon: Added stop target ability.
* Before, you had to stop each job by itself.
This commit is contained in:
@@ -26,6 +26,7 @@ namespace BPrivate {
|
|||||||
enum {
|
enum {
|
||||||
B_GET_LAUNCH_DATA = 'lnda',
|
B_GET_LAUNCH_DATA = 'lnda',
|
||||||
B_LAUNCH_TARGET = 'lntg',
|
B_LAUNCH_TARGET = 'lntg',
|
||||||
|
B_STOP_LAUNCH_TARGET = 'lnst',
|
||||||
B_LAUNCH_JOB = 'lnjo',
|
B_LAUNCH_JOB = 'lnjo',
|
||||||
B_ENABLE_LAUNCH_JOB = 'lnje',
|
B_ENABLE_LAUNCH_JOB = 'lnje',
|
||||||
B_STOP_LAUNCH_JOB = 'lnsj',
|
B_STOP_LAUNCH_JOB = 'lnsj',
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public:
|
|||||||
status_t Target(const char* name,
|
status_t Target(const char* name,
|
||||||
const BMessage* data = NULL,
|
const BMessage* data = NULL,
|
||||||
const char* baseName = NULL);
|
const char* baseName = NULL);
|
||||||
|
status_t StopTarget(const char* name,
|
||||||
|
bool force = false);
|
||||||
|
|
||||||
status_t Start(const char* name);
|
status_t Start(const char* name);
|
||||||
status_t Stop(const char* name, bool force = false);
|
status_t Stop(const char* name, bool force = false);
|
||||||
|
|||||||
@@ -166,6 +166,25 @@ BLaunchRoster::Target(const char* name, const BMessage* data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::StopTarget(const char* name, bool force)
|
||||||
|
{
|
||||||
|
if (name == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BMessage request(B_STOP_LAUNCH_TARGET);
|
||||||
|
status_t status = request.AddInt32("user", getuid());
|
||||||
|
if (status == B_OK)
|
||||||
|
status = request.AddString("target", name);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = request.AddBool("force", force);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return _SendRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BLaunchRoster::Start(const char* name)
|
BLaunchRoster::Start(const char* name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void _HandleGetLaunchData(BMessage* message);
|
void _HandleGetLaunchData(BMessage* message);
|
||||||
void _HandleLaunchTarget(BMessage* message);
|
void _HandleLaunchTarget(BMessage* message);
|
||||||
|
void _HandleStopLaunchTarget(BMessage* message);
|
||||||
void _HandleLaunchJob(BMessage* message);
|
void _HandleLaunchJob(BMessage* message);
|
||||||
void _HandleEnableLaunchJob(BMessage* message);
|
void _HandleEnableLaunchJob(BMessage* message);
|
||||||
void _HandleStopLaunchJob(BMessage* message);
|
void _HandleStopLaunchJob(BMessage* message);
|
||||||
@@ -185,6 +186,7 @@ private:
|
|||||||
void _InitJobs(Target* target);
|
void _InitJobs(Target* target);
|
||||||
void _LaunchJobs(Target* target,
|
void _LaunchJobs(Target* target,
|
||||||
bool forceNow = false);
|
bool forceNow = false);
|
||||||
|
void _StopJobs(Target* target, bool force);
|
||||||
bool _CanLaunchJob(Job* job, uint32 options,
|
bool _CanLaunchJob(Job* job, uint32 options,
|
||||||
bool testOnly = false);
|
bool testOnly = false);
|
||||||
bool _CanLaunchJobRequirements(Job* job,
|
bool _CanLaunchJobRequirements(Job* job,
|
||||||
@@ -553,6 +555,9 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
|||||||
case B_LAUNCH_TARGET:
|
case B_LAUNCH_TARGET:
|
||||||
_HandleLaunchTarget(message);
|
_HandleLaunchTarget(message);
|
||||||
break;
|
break;
|
||||||
|
case B_STOP_LAUNCH_TARGET:
|
||||||
|
_HandleStopLaunchTarget(message);
|
||||||
|
break;
|
||||||
case B_LAUNCH_JOB:
|
case B_LAUNCH_JOB:
|
||||||
_HandleLaunchJob(message);
|
_HandleLaunchJob(message);
|
||||||
break;
|
break;
|
||||||
@@ -741,6 +746,40 @@ LaunchDaemon::_HandleLaunchTarget(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LaunchDaemon::_HandleStopLaunchTarget(BMessage* message)
|
||||||
|
{
|
||||||
|
uid_t user = _GetUserID(message);
|
||||||
|
if (user < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* name = message->GetString("target");
|
||||||
|
|
||||||
|
Target* target = FindTarget(name);
|
||||||
|
if (target == NULL) {
|
||||||
|
Session* session = FindSession(user);
|
||||||
|
if (session != NULL) {
|
||||||
|
// Forward request to user launch_daemon
|
||||||
|
if (session->Daemon().SendMessage(message) == B_OK)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage reply(B_NAME_NOT_FOUND);
|
||||||
|
message->SendReply(&reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage data;
|
||||||
|
if (message->FindMessage("data", &data) == B_OK)
|
||||||
|
target->AddData(data.GetString("name"), data);
|
||||||
|
|
||||||
|
_StopJobs(target, message->GetBool("force"));
|
||||||
|
|
||||||
|
BMessage reply((uint32)B_OK);
|
||||||
|
message->SendReply(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LaunchDaemon::_HandleLaunchJob(BMessage* message)
|
LaunchDaemon::_HandleLaunchJob(BMessage* message)
|
||||||
{
|
{
|
||||||
@@ -1470,6 +1509,23 @@ LaunchDaemon::_LaunchJobs(Target* target, bool forceNow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Stops all running jobs of the specified target (may be \c NULL).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LaunchDaemon::_StopJobs(Target* target, bool force)
|
||||||
|
{
|
||||||
|
if (target != NULL && !target->HasLaunched())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (JobMap::reverse_iterator iterator = fJobs.rbegin();
|
||||||
|
iterator != fJobs.rend(); iterator++) {
|
||||||
|
Job* job = iterator->second;
|
||||||
|
if (job->Target() == target)
|
||||||
|
_StopJob(job, force);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Checks whether or not the specified \a job can be launched.
|
/*! Checks whether or not the specified \a job can be launched.
|
||||||
If \a testOnly is \c false, calling this method will trigger a demand
|
If \a testOnly is \c false, calling this method will trigger a demand
|
||||||
to the \a job.
|
to the \a job.
|
||||||
|
|||||||
Reference in New Issue
Block a user