From 3282b758b0b9c0f46959b51efbc1f39f47138105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 4 Nov 2015 21:25:08 +0100 Subject: [PATCH] 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. --- headers/private/app/LaunchDaemonDefs.h | 4 + headers/private/app/LaunchRoster.h | 7 ++ src/kits/app/LaunchRoster.cpp | 88 +++++++++++++ src/servers/launch/Job.cpp | 8 +- src/servers/launch/LaunchDaemon.cpp | 167 +++++++++++++++++++++++-- 5 files changed, 262 insertions(+), 12 deletions(-) diff --git a/headers/private/app/LaunchDaemonDefs.h b/headers/private/app/LaunchDaemonDefs.h index f0452847c5..ba791aa7ab 100644 --- a/headers/private/app/LaunchDaemonDefs.h +++ b/headers/private/app/LaunchDaemonDefs.h @@ -32,6 +32,10 @@ enum { B_UNREGISTER_LAUNCH_EVENT = 'lnue', B_NOTIFY_LAUNCH_EVENT = 'lnne', 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', }; diff --git a/headers/private/app/LaunchRoster.h b/headers/private/app/LaunchRoster.h index 970b3120aa..785fe0a846 100644 --- a/headers/private/app/LaunchRoster.h +++ b/headers/private/app/LaunchRoster.h @@ -45,6 +45,11 @@ public: status_t ResetStickyEvent(const BMessenger& source, 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; private: @@ -54,6 +59,8 @@ private: status_t _UpdateEvent(uint32 what, const BMessenger& source, const char* name, uint32 flags = 0); + status_t _GetInfo(uint32 what, const char* name, + BMessage& info); private: BMessenger fMessenger; diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp index eec0128555..1290b28190 100644 --- a/src/kits/app/LaunchRoster.cpp +++ b/src/kits/app/LaunchRoster.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -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 BLaunchRoster::_InitMessenger() { @@ -277,3 +340,28 @@ BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source, 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; +} diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index d34b3f5e3c..d7858116be 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -17,6 +17,7 @@ #include #include "Target.h" +#include "Utility.h" Job::Job(const char* name) @@ -314,18 +315,21 @@ Job::Launch() // Build argument vector 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) { _SetLaunchStatus(status); return status; } + std::vector strings; std::vector args; size_t count = fArguments.CountStrings() - 1; if (count > 0) { 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); } diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 71f46189d7..5caf90fd5c 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -44,6 +44,13 @@ #include "Worker.h" +#ifdef DEBUG +# define TRACE(x, ...) debug_printf(x, __VA_ARGS__) +#else +# define TRACE(x, ...) ; +#endif + + using namespace ::BPrivate; using namespace BSupportKit; using BSupportKit::BPrivate::JobQueue; @@ -180,6 +187,8 @@ private: ExternalEventSource* event, const BString& name); void _ResolveExternalEvents(BaseJob* job); + void _GetTargetInfo(Target* target, BMessage& info); + void _GetJobInfo(Job* job, BMessage& info); void _ForwardEventMessage(uid_t user, BMessage* message); @@ -468,6 +477,125 @@ LaunchDaemon::MessageReceived(BMessage* message) _HandleResetStickyLaunchEvent(message); 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: { // An internal event has been triggered. @@ -854,6 +982,7 @@ LaunchDaemon::_ReadFile(const char* context, BEntry& entry) BMessage message; status = parser.ParseFile(path.Path(), message); if (status == B_OK) { + TRACE("launch_daemon: read file %s\n", path.Path()); _AddJobs(NULL, message); _AddTargets(message); _AddRunTargets(message); @@ -977,6 +1106,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) Job* job = FindJob(name); if (job == NULL) { + TRACE(" add job \"%s\"\n", name.String()); + job = new (std::nothrow) Job(name); if (job == NULL) return; @@ -984,7 +1115,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) job->SetService(service); job->SetCreateDefaultPort(service); job->SetTarget(target); - } + } else + TRACE(" amend job \"%s\"\n", name.String()); if (message.HasBool("disabled")) job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled())); @@ -1002,15 +1134,8 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) job->AddPort(portMessage); } - if (message.HasString("launch")) { - job->Arguments().MakeEmpty(); - - const char* argument; - for (int32 index = 0; message.FindString("launch", index, &argument) - == B_OK; index++) { - job->AddArgument(Utility::TranslatePath(argument)); - } - } + if (message.HasString("launch")) + message.FindStrings("launch", &job->Arguments()); const char* requirement; for (int32 index = 0; @@ -1182,6 +1307,7 @@ LaunchDaemon::_SetEvent(BaseJob* job, const BMessage& message) } if (updated) { + TRACE(" event: %s\n", event->ToString().String()); job->SetEvent(event); _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 LaunchDaemon::_ForwardEventMessage(uid_t user, BMessage* message) {