launch_daemon: Add API to get information on jobs.
* Ie. a listing of all targets/jobs, as well as specific (basic) info on each. * Also added a bit of optional debug output. * Moved translating the path to launch time -- we should take the job's environment into account here at some point.
This commit is contained in:
parent
7e45dd1057
commit
3282b758b0
@ -32,6 +32,10 @@ enum {
|
|||||||
B_UNREGISTER_LAUNCH_EVENT = 'lnue',
|
B_UNREGISTER_LAUNCH_EVENT = 'lnue',
|
||||||
B_NOTIFY_LAUNCH_EVENT = 'lnne',
|
B_NOTIFY_LAUNCH_EVENT = 'lnne',
|
||||||
B_RESET_STICKY_LAUNCH_EVENT = 'lnRe',
|
B_RESET_STICKY_LAUNCH_EVENT = 'lnRe',
|
||||||
|
B_GET_LAUNCH_TARGETS = 'lngt',
|
||||||
|
B_GET_LAUNCH_JOBS = 'lngj',
|
||||||
|
B_GET_LAUNCH_TARGET_INFO = 'lntI',
|
||||||
|
B_GET_LAUNCH_JOB_INFO = 'lnjI',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,11 @@ public:
|
|||||||
status_t ResetStickyEvent(const BMessenger& source,
|
status_t ResetStickyEvent(const BMessenger& source,
|
||||||
const char* name);
|
const char* name);
|
||||||
|
|
||||||
|
status_t GetTargets(BStringList& targets);
|
||||||
|
status_t GetTargetInfo(const char* name, BMessage& info);
|
||||||
|
status_t GetJobs(const char* target, BStringList& jobs);
|
||||||
|
status_t GetJobInfo(const char* name, BMessage& info);
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -54,6 +59,8 @@ private:
|
|||||||
status_t _UpdateEvent(uint32 what,
|
status_t _UpdateEvent(uint32 what,
|
||||||
const BMessenger& source, const char* name,
|
const BMessenger& source, const char* name,
|
||||||
uint32 flags = 0);
|
uint32 flags = 0);
|
||||||
|
status_t _GetInfo(uint32 what, const char* name,
|
||||||
|
BMessage& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessenger fMessenger;
|
BMessenger fMessenger;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
#include <StringList.h>
|
||||||
|
|
||||||
#include <launch.h>
|
#include <launch.h>
|
||||||
#include <LaunchDaemonDefs.h>
|
#include <LaunchDaemonDefs.h>
|
||||||
@ -234,6 +235,68 @@ BLaunchRoster::ResetStickyEvent(const BMessenger& source, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::GetTargets(BStringList& targets)
|
||||||
|
{
|
||||||
|
BMessage request(B_GET_LAUNCH_TARGETS);
|
||||||
|
status_t status = request.AddInt32("user", getuid());
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// send the request
|
||||||
|
BMessage result;
|
||||||
|
status = fMessenger.SendMessage(&request, &result);
|
||||||
|
|
||||||
|
// evaluate the reply
|
||||||
|
if (status == B_OK)
|
||||||
|
status = result.what;
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
|
status = result.FindStrings("target", &targets);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::GetTargetInfo(const char* name, BMessage& info)
|
||||||
|
{
|
||||||
|
return _GetInfo(B_GET_LAUNCH_TARGET_INFO, name, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::GetJobs(const char* target, BStringList& jobs)
|
||||||
|
{
|
||||||
|
BMessage request(B_GET_LAUNCH_JOBS);
|
||||||
|
status_t status = request.AddInt32("user", getuid());
|
||||||
|
if (status == B_OK && target != NULL)
|
||||||
|
status = request.AddString("target", target);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// send the request
|
||||||
|
BMessage result;
|
||||||
|
status = fMessenger.SendMessage(&request, &result);
|
||||||
|
|
||||||
|
// evaluate the reply
|
||||||
|
if (status == B_OK)
|
||||||
|
status = result.what;
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
|
status = result.FindStrings("job", &jobs);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::GetJobInfo(const char* name, BMessage& info)
|
||||||
|
{
|
||||||
|
return _GetInfo(B_GET_LAUNCH_JOB_INFO, name, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BLaunchRoster::_InitMessenger()
|
BLaunchRoster::_InitMessenger()
|
||||||
{
|
{
|
||||||
@ -277,3 +340,28 @@ BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source,
|
|||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::_GetInfo(uint32 what, const char* name, BMessage& info)
|
||||||
|
{
|
||||||
|
if (name == NULL || name[0] == '\0')
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BMessage request(what);
|
||||||
|
status_t status = request.AddInt32("user", getuid());
|
||||||
|
if (status == B_OK)
|
||||||
|
status = request.AddString("name", name);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// send the request
|
||||||
|
BMessage result;
|
||||||
|
status = fMessenger.SendMessage(&request, &info);
|
||||||
|
|
||||||
|
// evaluate the reply
|
||||||
|
if (status == B_OK)
|
||||||
|
status = result.what;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <user_group.h>
|
#include <user_group.h>
|
||||||
|
|
||||||
#include "Target.h"
|
#include "Target.h"
|
||||||
|
#include "Utility.h"
|
||||||
|
|
||||||
|
|
||||||
Job::Job(const char* name)
|
Job::Job(const char* name)
|
||||||
@ -314,18 +315,21 @@ Job::Launch()
|
|||||||
// Build argument vector
|
// Build argument vector
|
||||||
|
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
status_t status = get_ref_for_path(fArguments.StringAt(0).String(), &ref);
|
status_t status = get_ref_for_path(
|
||||||
|
Utility::TranslatePath(fArguments.StringAt(0).String()), &ref);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
_SetLaunchStatus(status);
|
_SetLaunchStatus(status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<BString> strings;
|
||||||
std::vector<const char*> args;
|
std::vector<const char*> args;
|
||||||
|
|
||||||
size_t count = fArguments.CountStrings() - 1;
|
size_t count = fArguments.CountStrings() - 1;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
for (int32 i = 1; i < fArguments.CountStrings(); i++) {
|
for (int32 i = 1; i < fArguments.CountStrings(); i++) {
|
||||||
args.push_back(fArguments.StringAt(i));
|
strings.push_back(Utility::TranslatePath(fArguments.StringAt(i)));
|
||||||
|
args.push_back(strings.back());
|
||||||
}
|
}
|
||||||
args.push_back(NULL);
|
args.push_back(NULL);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,13 @@
|
|||||||
#include "Worker.h"
|
#include "Worker.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
# define TRACE(x, ...) debug_printf(x, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# define TRACE(x, ...) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using namespace ::BPrivate;
|
using namespace ::BPrivate;
|
||||||
using namespace BSupportKit;
|
using namespace BSupportKit;
|
||||||
using BSupportKit::BPrivate::JobQueue;
|
using BSupportKit::BPrivate::JobQueue;
|
||||||
@ -180,6 +187,8 @@ private:
|
|||||||
ExternalEventSource* event,
|
ExternalEventSource* event,
|
||||||
const BString& name);
|
const BString& name);
|
||||||
void _ResolveExternalEvents(BaseJob* job);
|
void _ResolveExternalEvents(BaseJob* job);
|
||||||
|
void _GetTargetInfo(Target* target, BMessage& info);
|
||||||
|
void _GetJobInfo(Job* job, BMessage& info);
|
||||||
void _ForwardEventMessage(uid_t user,
|
void _ForwardEventMessage(uid_t user,
|
||||||
BMessage* message);
|
BMessage* message);
|
||||||
|
|
||||||
@ -468,6 +477,125 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
|||||||
_HandleResetStickyLaunchEvent(message);
|
_HandleResetStickyLaunchEvent(message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case B_GET_LAUNCH_TARGETS:
|
||||||
|
{
|
||||||
|
uid_t user = _GetUserID(message);
|
||||||
|
if (user < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage reply;
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
if (!fUserMode) {
|
||||||
|
// Request the data from the user's daemon, too
|
||||||
|
Session* session = FindSession(user);
|
||||||
|
if (session != NULL) {
|
||||||
|
BMessage request(B_GET_LAUNCH_TARGETS);
|
||||||
|
status = request.AddInt32("user", 0);
|
||||||
|
if (status == B_OK) {
|
||||||
|
status = session->Daemon().SendMessage(&request,
|
||||||
|
&reply);
|
||||||
|
}
|
||||||
|
if (status == B_OK)
|
||||||
|
status = reply.what;
|
||||||
|
} else
|
||||||
|
status = B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
TargetMap::const_iterator iterator = fTargets.begin();
|
||||||
|
for (; iterator != fTargets.end(); iterator++)
|
||||||
|
reply.AddString("target", iterator->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.what = status;
|
||||||
|
message->SendReply(&reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_GET_LAUNCH_TARGET_INFO:
|
||||||
|
{
|
||||||
|
uid_t user = _GetUserID(message);
|
||||||
|
if (user < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* name = message->GetString("name");
|
||||||
|
Target* target = FindTarget(name);
|
||||||
|
if (target == NULL && !fUserMode) {
|
||||||
|
_ForwardEventMessage(user, message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage reply(uint32(target != NULL ? B_OK : B_NAME_NOT_FOUND));
|
||||||
|
if (target != NULL)
|
||||||
|
_GetTargetInfo(target, reply);
|
||||||
|
message->SendReply(&reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_GET_LAUNCH_JOBS:
|
||||||
|
{
|
||||||
|
uid_t user = _GetUserID(message);
|
||||||
|
if (user < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* targetName = message->GetString("target");
|
||||||
|
|
||||||
|
BMessage reply;
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
if (!fUserMode) {
|
||||||
|
// Request the data from the user's daemon, too
|
||||||
|
Session* session = FindSession(user);
|
||||||
|
if (session != NULL) {
|
||||||
|
BMessage request(B_GET_LAUNCH_JOBS);
|
||||||
|
status = request.AddInt32("user", 0);
|
||||||
|
if (status == B_OK && targetName != NULL)
|
||||||
|
status = request.AddString("target", targetName);
|
||||||
|
if (status == B_OK) {
|
||||||
|
status = session->Daemon().SendMessage(&request,
|
||||||
|
&reply);
|
||||||
|
}
|
||||||
|
if (status == B_OK)
|
||||||
|
status = reply.what;
|
||||||
|
} else
|
||||||
|
status = B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
JobMap::const_iterator iterator = fJobs.begin();
|
||||||
|
for (; iterator != fJobs.end(); iterator++) {
|
||||||
|
Job* job = iterator->second;
|
||||||
|
if (targetName != NULL && (job->Target() == NULL
|
||||||
|
|| job->Target()->Title() != targetName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
reply.AddString("job", iterator->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.what = status;
|
||||||
|
message->SendReply(&reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case B_GET_LAUNCH_JOB_INFO:
|
||||||
|
{
|
||||||
|
uid_t user = _GetUserID(message);
|
||||||
|
if (user < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* name = message->GetString("name");
|
||||||
|
Job* job = FindJob(name);
|
||||||
|
if (job == NULL && !fUserMode) {
|
||||||
|
_ForwardEventMessage(user, message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage reply(uint32(job != NULL ? B_OK : B_NAME_NOT_FOUND));
|
||||||
|
if (job != NULL)
|
||||||
|
_GetJobInfo(job, reply);
|
||||||
|
message->SendReply(&reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kMsgEventTriggered:
|
case kMsgEventTriggered:
|
||||||
{
|
{
|
||||||
// An internal event has been triggered.
|
// An internal event has been triggered.
|
||||||
@ -854,6 +982,7 @@ LaunchDaemon::_ReadFile(const char* context, BEntry& entry)
|
|||||||
BMessage message;
|
BMessage message;
|
||||||
status = parser.ParseFile(path.Path(), message);
|
status = parser.ParseFile(path.Path(), message);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
|
TRACE("launch_daemon: read file %s\n", path.Path());
|
||||||
_AddJobs(NULL, message);
|
_AddJobs(NULL, message);
|
||||||
_AddTargets(message);
|
_AddTargets(message);
|
||||||
_AddRunTargets(message);
|
_AddRunTargets(message);
|
||||||
@ -977,6 +1106,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
|
|||||||
|
|
||||||
Job* job = FindJob(name);
|
Job* job = FindJob(name);
|
||||||
if (job == NULL) {
|
if (job == NULL) {
|
||||||
|
TRACE(" add job \"%s\"\n", name.String());
|
||||||
|
|
||||||
job = new (std::nothrow) Job(name);
|
job = new (std::nothrow) Job(name);
|
||||||
if (job == NULL)
|
if (job == NULL)
|
||||||
return;
|
return;
|
||||||
@ -984,7 +1115,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
|
|||||||
job->SetService(service);
|
job->SetService(service);
|
||||||
job->SetCreateDefaultPort(service);
|
job->SetCreateDefaultPort(service);
|
||||||
job->SetTarget(target);
|
job->SetTarget(target);
|
||||||
}
|
} else
|
||||||
|
TRACE(" amend job \"%s\"\n", name.String());
|
||||||
|
|
||||||
if (message.HasBool("disabled"))
|
if (message.HasBool("disabled"))
|
||||||
job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled()));
|
job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled()));
|
||||||
@ -1002,15 +1134,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
|
|||||||
job->AddPort(portMessage);
|
job->AddPort(portMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.HasString("launch")) {
|
if (message.HasString("launch"))
|
||||||
job->Arguments().MakeEmpty();
|
message.FindStrings("launch", &job->Arguments());
|
||||||
|
|
||||||
const char* argument;
|
|
||||||
for (int32 index = 0; message.FindString("launch", index, &argument)
|
|
||||||
== B_OK; index++) {
|
|
||||||
job->AddArgument(Utility::TranslatePath(argument));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* requirement;
|
const char* requirement;
|
||||||
for (int32 index = 0;
|
for (int32 index = 0;
|
||||||
@ -1182,6 +1307,7 @@ LaunchDaemon::_SetEvent(BaseJob* job, const BMessage& message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
|
TRACE(" event: %s\n", event->ToString().String());
|
||||||
job->SetEvent(event);
|
job->SetEvent(event);
|
||||||
_ResolveExternalEvents(job);
|
_ResolveExternalEvents(job);
|
||||||
}
|
}
|
||||||
@ -1253,6 +1379,27 @@ LaunchDaemon::_ResolveExternalEvents(BaseJob* job)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LaunchDaemon::_GetTargetInfo(Target* target, BMessage& info)
|
||||||
|
{
|
||||||
|
info.SetString("name", target->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LaunchDaemon::_GetJobInfo(Job* job, BMessage& info)
|
||||||
|
{
|
||||||
|
info.SetString("name", job->Name());
|
||||||
|
info.SetInt32("team", job->Team());
|
||||||
|
info.SetBool("running", job->IsRunning());
|
||||||
|
info.SetBool("launched", job->IsLaunched());
|
||||||
|
|
||||||
|
PortMap::const_iterator iterator = job->Ports().begin();
|
||||||
|
for (; iterator != job->Ports().end(); iterator++)
|
||||||
|
info.AddMessage("port", &iterator->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LaunchDaemon::_ForwardEventMessage(uid_t user, BMessage* message)
|
LaunchDaemon::_ForwardEventMessage(uid_t user, BMessage* message)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user