launch_daemon: actually launch the jobs.

* BRoster::Launch() cannot be used (yet), as it pre-registers the
  application we're launching, and that won't work for the registrar or
  anything else until the registrar is up and running.
* Renamed B_GET_LAUNCH_CONNECTIONS to B_GET_LAUNCH_DATA.
* Add the team ID to the get-launch-data reply.
* Added BLaunchRoster::GetPort() for convenience.
* Removed some superfluous debug output, but temporarily dump all stdio
  to /dev/dprintf (ie. the syslog).
* Made job matching case insensitive (as MIME types should be).
This commit is contained in:
Axel Dörfler 2015-04-15 17:40:18 +02:00
parent e489a80da0
commit d482c7ca5b
5 changed files with 88 additions and 26 deletions

View File

@ -24,7 +24,7 @@ namespace BPrivate {
// message constants
enum {
B_GET_LAUNCH_CONNECTIONS = 'lncc',
B_GET_LAUNCH_DATA = 'lncd',
};

View File

@ -17,6 +17,8 @@ public:
status_t InitCheck() const;
status_t GetData(const char* signature, BMessage& data);
port_id GetPort(const char* signature,
const char* name = NULL);
private:
void _InitMessenger();

View File

@ -518,7 +518,7 @@ BApplication::_InitData(const char* signature, bool initGUI, status_t* _error)
// Return the error or exit, if there was an error and no error variable
// has been supplied.
if (_error) {
if (_error != NULL) {
*_error = fInitError;
} else if (fInitError != B_OK) {
DBG(OUT("BApplication::InitData() failed: %s\n", strerror(fInitError)));
@ -531,16 +531,7 @@ DBG(OUT("BApplication::InitData() done\n"));
port_id
BApplication::_GetPort(const char* signature)
{
BLaunchRoster launchRoster;
BMessage data;
status_t status = launchRoster.GetData(signature, data);
if (status == B_OK) {
port_id port = data.GetInt32("port", B_NAME_NOT_FOUND);
if (port >= 0)
return port;
}
return -1;
return BLaunchRoster().GetPort(signature);
}
@ -1265,7 +1256,8 @@ BApplication::ScriptReceived(BMessage* message, int32 index,
case B_ID_SPECIFIER:
{
// TODO
debug_printf("Looper's ID specifier used but not implemented.\n");
debug_printf("Looper's ID specifier used but not "
"implemented.\n");
break;
}
}

View File

@ -9,6 +9,8 @@
#include <LaunchRoster.h>
#include <String.h>
#include <LaunchDaemonDefs.h>
#include <MessengerPrivate.h>
@ -43,7 +45,7 @@ BLaunchRoster::GetData(const char* signature, BMessage& data)
if (signature == NULL || signature[0] == '\0')
return B_BAD_VALUE;
BMessage request(B_GET_LAUNCH_CONNECTIONS);
BMessage request(B_GET_LAUNCH_DATA);
status_t status = request.AddString("name", signature);
if (status != B_OK)
return status;
@ -59,6 +61,29 @@ BLaunchRoster::GetData(const char* signature, BMessage& data)
}
port_id
BLaunchRoster::GetPort(const char* signature, const char* name)
{
BLaunchRoster launchRoster;
BMessage data;
status_t status = launchRoster.GetData(signature, data);
if (status == B_OK) {
BString fieldName;
if (name == NULL)
fieldName = "port";
else {
fieldName = name;
fieldName << "_port";
}
port_id port = data.GetInt32(fieldName.String(), B_NAME_NOT_FOUND);
if (port >= 0)
return port;
}
return -1;
}
void
BLaunchRoster::_InitMessenger()
{

View File

@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <Directory.h>
#include <driver_settings.h>
@ -17,6 +18,7 @@
#include <PathFinder.h>
#include <Server.h>
#include <AppMisc.h>
#include <DriverSettingsMessageAdapter.h>
#include <LaunchDaemonDefs.h>
#include <syscalls.h>
@ -70,6 +72,7 @@ public:
status_t Init();
status_t InitCheck() const;
team_id Team() const;
port_id Port() const;
status_t Launch();
@ -144,6 +147,7 @@ Job::Job(const char* name)
fInitStatus(B_NO_INIT),
fTeam(-1)
{
fName.ToLower();
}
@ -248,8 +252,6 @@ Job::Init()
fPort = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY, Name());
if (fPort < 0)
fInitStatus = fPort;
printf("PORT %s: %s\n", Name(), strerror(fPort));
}
return fInitStatus;
@ -263,6 +265,13 @@ Job::InitCheck() const
}
team_id
Job::Team() const
{
return fTeam;
}
port_id
Job::Port() const
{
@ -274,11 +283,37 @@ status_t
Job::Launch()
{
if (fArguments.IsEmpty()) {
// TODO: launch via signature
} else {
printf("LAUNCH %s\n", fArguments.StringAt(0).String());
// TODO: Launch via signature
// We cannot use the BRoster here as it tries to pre-register
// the application.
BString signature("application/");
signature << fName;
return B_NOT_SUPPORTED;
//return be_roster->Launch(signature.String(), (BMessage*)NULL, &fTeam);
}
entry_ref ref;
status_t status = get_ref_for_path(fArguments.StringAt(0).String(), &ref);
if (status != B_OK)
return status;
size_t count = fArguments.CountStrings();
const char* args[count + 1];
for (int32 i = 0; i < fArguments.CountStrings(); i++) {
args[i] = fArguments.StringAt(i);
}
args[count] = NULL;
thread_id thread = load_image(count, args,
const_cast<const char**>(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);
}
@ -329,13 +364,18 @@ void
LaunchDaemon::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_GET_LAUNCH_CONNECTIONS:
case B_GET_LAUNCH_DATA:
{
BMessage reply;
Job* job = _Job(get_leaf(message->GetString("name")));
if (job == NULL) {
reply.AddInt32("error", B_NAME_NOT_FOUND);
} else {
// If the job has not been launched yet, we'll pass on our
// team here. The rationale behind this is that this team
// will temporarily own the synchronous reply ports.
reply.AddInt32("team", job->Team() < 0
? current_team() : job->Team());
if (job->CreatePort())
reply.AddInt32("port", job->Port());
@ -358,7 +398,6 @@ void
LaunchDaemon::_ReadPaths(const BStringList& paths)
{
for (int32 i = 0; i < paths.CountStrings(); i++) {
printf("----- %s -------\n", paths.StringAt(i).String());
BEntry entry(paths.StringAt(i));
if (entry.InitCheck() != B_OK || !entry.Exists())
continue;
@ -377,11 +416,11 @@ LaunchDaemon::_ReadEntry(const char* context, BEntry& entry)
_ReadFile(context, entry);
}
void
LaunchDaemon::_ReadDirectory(const char* context, BEntry& directoryEntry)
{
BDirectory directory(&directoryEntry);
printf("DIR %s\n", directoryEntry.Name());
BEntry entry;
while (directory.GetNextEntry(&entry) == B_OK) {
@ -393,7 +432,6 @@ LaunchDaemon::_ReadDirectory(const char* context, BEntry& directoryEntry)
status_t
LaunchDaemon::_ReadFile(const char* context, BEntry& entry)
{
printf("FILE %s\n", entry.Name());
DriverSettingsMessageAdapter adapter;
BPath path;
@ -426,7 +464,6 @@ void
LaunchDaemon::_AddJob(bool service, BMessage& message)
{
const char* name = message.GetString("name");
printf("JOB %s\n", name);
if (name == NULL || name[0] == '\0') {
// Invalid job description
return;
@ -458,7 +495,7 @@ LaunchDaemon::_Job(const char* name)
if (name == NULL)
return NULL;
JobMap::const_iterator found = fJobs.find(name);
JobMap::const_iterator found = fJobs.find(BString(name).ToLower());
if (found != fJobs.end())
return found->second;
@ -472,7 +509,6 @@ LaunchDaemon::_InitJobs()
for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();
iterator++) {
Job* job = iterator->second;
printf(" enabled? %s - %d\n", job->Name(), job->IsEnabled());
if (job->IsEnabled() && (!_IsSafeMode() || job->LaunchInSafeMode()))
job->Init();
}
@ -524,6 +560,13 @@ LaunchDaemon::_IsSafeMode() const
int
main()
{
// TODO: remove this again
close(STDOUT_FILENO);
int fd = open("/dev/dprintf", O_WRONLY);
if (fd != STDOUT_FILENO)
dup2(fd, STDOUT_FILENO);
puts("launch_daemon is alive and kicking.");
status_t status;
LaunchDaemon* daemon = new LaunchDaemon(status);
if (status == B_OK)