launch_daemon: Added stop target ability.

* Before, you had to stop each job by itself.
This commit is contained in:
Axel Dörfler 2016-11-29 23:14:36 +01:00
parent 4d99bf9af7
commit 852e09d61f
4 changed files with 78 additions and 0 deletions

View File

@ -26,6 +26,7 @@ namespace BPrivate {
enum {
B_GET_LAUNCH_DATA = 'lnda',
B_LAUNCH_TARGET = 'lntg',
B_STOP_LAUNCH_TARGET = 'lnst',
B_LAUNCH_JOB = 'lnjo',
B_ENABLE_LAUNCH_JOB = 'lnje',
B_STOP_LAUNCH_JOB = 'lnsj',

View File

@ -33,6 +33,8 @@ public:
status_t Target(const char* name,
const BMessage* data = NULL,
const char* baseName = NULL);
status_t StopTarget(const char* name,
bool force = false);
status_t Start(const char* name);
status_t Stop(const char* name, bool force = false);

View File

@ -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
BLaunchRoster::Start(const char* name)
{

View File

@ -153,6 +153,7 @@ public:
private:
void _HandleGetLaunchData(BMessage* message);
void _HandleLaunchTarget(BMessage* message);
void _HandleStopLaunchTarget(BMessage* message);
void _HandleLaunchJob(BMessage* message);
void _HandleEnableLaunchJob(BMessage* message);
void _HandleStopLaunchJob(BMessage* message);
@ -185,6 +186,7 @@ private:
void _InitJobs(Target* target);
void _LaunchJobs(Target* target,
bool forceNow = false);
void _StopJobs(Target* target, bool force);
bool _CanLaunchJob(Job* job, uint32 options,
bool testOnly = false);
bool _CanLaunchJobRequirements(Job* job,
@ -553,6 +555,9 @@ LaunchDaemon::MessageReceived(BMessage* message)
case B_LAUNCH_TARGET:
_HandleLaunchTarget(message);
break;
case B_STOP_LAUNCH_TARGET:
_HandleStopLaunchTarget(message);
break;
case B_LAUNCH_JOB:
_HandleLaunchJob(message);
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
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.
If \a testOnly is \c false, calling this method will trigger a demand
to the \a job.