From 78e39852fad37b7ce43c29d0f22c41405513c119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 17 Jun 2015 17:03:20 +0200 Subject: [PATCH] launch_daemon: Use BRoster::Launch() without registrar. * BRoster now allows settings a "no-registrar" mode that is currently only honored in _LaunchApp(), though. * Job::Launch() is now using this, which also allows launching applications by signature (ie. if the job name matches the signature, you can omit the "launch" option). --- headers/os/app/Roster.h | 5 ++++- headers/private/app/RosterPrivate.h | 5 ++++- src/kits/app/Roster.cpp | 22 +++++++++++++++++----- src/servers/launch/Job.cpp | 25 +++++++------------------ src/servers/launch/LaunchDaemon.cpp | 5 +++++ 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/headers/os/app/Roster.h b/headers/os/app/Roster.h index 32caaf898e..595b8a070e 100644 --- a/headers/os/app/Roster.h +++ b/headers/os/app/Roster.h @@ -212,6 +212,8 @@ private: const entry_ref* ref, bool readyToRun) const; + void _SetWithoutRegistrar(bool noRegistrar); + void _InitMessenger(); static status_t _InitMimeMessenger(void* data); @@ -229,7 +231,8 @@ private: BMessenger fMessenger; BMessenger fMimeMessenger; int32 fMimeMessengerInitOnce; - uint32 _reserved[2]; + bool fNoRegistrar; + uint32 _reserved[1]; }; // global BRoster instance diff --git a/headers/private/app/RosterPrivate.h b/headers/private/app/RosterPrivate.h index 344c5ae705..415779351c 100644 --- a/headers/private/app/RosterPrivate.h +++ b/headers/private/app/RosterPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -52,6 +52,9 @@ class BRoster::Private { { return fRoster->_IsAppRegistered(ref, team, token, preRegistered, info); } + void SetWithoutRegistrar(bool noRegistrar) const + { fRoster->_SetWithoutRegistrar(noRegistrar); } + status_t RemoveApp(team_id team) const { return fRoster->_RemoveApp(team); } diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index 23ecb83238..c017d4b621 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -554,7 +554,8 @@ BRoster::BRoster() : fMessenger(), fMimeMessenger(), - fMimeMessengerInitOnce(INIT_ONCE_UNINITIALIZED) + fMimeMessengerInitOnce(INIT_ONCE_UNINITIALIZED), + fNoRegistrar(false) { _InitMessenger(); } @@ -1871,7 +1872,7 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, uint32 appToken = 0; app_info appInfo; bool isScript = wasDocument && docRef != NULL && *docRef == appRef; - if (!isScript) { + if (!isScript && !fNoRegistrar) { error = _AddApplication(signature, &appRef, appFlags, -1, -1, -1, false, &appToken, &team); if (error == B_ALREADY_RUNNING) { @@ -1910,7 +1911,7 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, DBG(OUT(" load image: %s (%lx)\n", strerror(error), error)); // finish the registration - if (error == B_OK && !isScript) + if (error == B_OK && !isScript && !fNoRegistrar) error = _SetThreadAndTeam(appToken, appThread, team); DBG(OUT(" set thread and team: %s (%lx)\n", strerror(error), @@ -1926,7 +1927,8 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, kill_thread(appThread); if (!isScript) { - _RemovePreRegApp(appToken); + if (!fNoRegistrar) + _RemovePreRegApp(appToken); if (!wasDocument) { // Remove app hint if it's this one @@ -1953,7 +1955,7 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, } // send "on launch" messages - if (error == B_OK) { + if (error == B_OK && !fNoRegistrar) { // If the target app is B_ARGV_ONLY, only if it is newly launched // messages are sent to it (namely B_ARGV_RECEIVED and B_READY_TO_RUN). // An already running B_ARGV_ONLY app won't get any messages. @@ -2581,6 +2583,16 @@ BRoster::_SendToRunning(team_id team, int argc, const char* const* args, } +/*! Allows to use certain functionality of the BRoster class without + accessing the registrar. +*/ +void +BRoster::_SetWithoutRegistrar(bool noRegistrar) +{ + fNoRegistrar = noRegistrar; +} + + void BRoster::_InitMessenger() { diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index 01a6fdb213..40263e123a 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "Target.h" @@ -317,13 +318,10 @@ status_t Job::Launch() { if (fArguments.IsEmpty()) { - // TODO: Launch via signature - // We cannot use the BRoster here as it tries to pre-register - // the application. + // Launch by signature BString signature("application/"); signature << Name(); - return B_NOT_SUPPORTED; - //return be_roster->Launch(signature.String(), (BMessage*)NULL, &fTeam); + return be_roster->Launch(signature.String(), (BMessage*)NULL, &fTeam); } entry_ref ref; @@ -331,23 +329,14 @@ Job::Launch() if (status != B_OK) return status; - size_t count = fArguments.CountStrings(); + size_t count = fArguments.CountStrings() - 1; const char* args[count + 1]; - for (int32 i = 0; i < fArguments.CountStrings(); i++) { - args[i] = fArguments.StringAt(i); + for (int32 i = 1; i < fArguments.CountStrings(); i++) { + args[i - 1] = fArguments.StringAt(i); } args[count] = NULL; - thread_id thread = load_image(count, args, - const_cast(environ)); - if (thread >= 0) - resume_thread(thread); - - thread_info info; - if (get_thread_info(thread, &info) == B_OK) - fTeam = info.team; - return B_OK; -// return be_roster->Launch(&ref, count, args, &fTeam); + return be_roster->Launch(&ref, count, args, &fTeam); } diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 25d4064a05..a6fc56697c 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "multiuser_utils.h" @@ -185,6 +186,10 @@ LaunchDaemon::LaunchDaemon(bool userMode, status_t& error) fMainWorker = new MainWorker(fJobQueue); if (fInitTarget != NULL) _AddTarget(fInitTarget); + + // We may not be able to talk to the registrar + if (!fUserMode) + BRoster::Private().SetWithoutRegistrar(true); }