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 // message constants
enum { enum {
B_GET_LAUNCH_CONNECTIONS = 'lncc', B_GET_LAUNCH_DATA = 'lncd',
}; };

View File

@ -17,6 +17,8 @@ public:
status_t InitCheck() const; status_t InitCheck() const;
status_t GetData(const char* signature, BMessage& data); status_t GetData(const char* signature, BMessage& data);
port_id GetPort(const char* signature,
const char* name = NULL);
private: private:
void _InitMessenger(); 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 // Return the error or exit, if there was an error and no error variable
// has been supplied. // has been supplied.
if (_error) { if (_error != NULL) {
*_error = fInitError; *_error = fInitError;
} else if (fInitError != B_OK) { } else if (fInitError != B_OK) {
DBG(OUT("BApplication::InitData() failed: %s\n", strerror(fInitError))); DBG(OUT("BApplication::InitData() failed: %s\n", strerror(fInitError)));
@ -531,16 +531,7 @@ DBG(OUT("BApplication::InitData() done\n"));
port_id port_id
BApplication::_GetPort(const char* signature) BApplication::_GetPort(const char* signature)
{ {
BLaunchRoster launchRoster; return BLaunchRoster().GetPort(signature);
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;
} }
@ -1265,7 +1256,8 @@ BApplication::ScriptReceived(BMessage* message, int32 index,
case B_ID_SPECIFIER: case B_ID_SPECIFIER:
{ {
// TODO // TODO
debug_printf("Looper's ID specifier used but not implemented.\n"); debug_printf("Looper's ID specifier used but not "
"implemented.\n");
break; break;
} }
} }

View File

@ -9,6 +9,8 @@
#include <LaunchRoster.h> #include <LaunchRoster.h>
#include <String.h>
#include <LaunchDaemonDefs.h> #include <LaunchDaemonDefs.h>
#include <MessengerPrivate.h> #include <MessengerPrivate.h>
@ -43,7 +45,7 @@ BLaunchRoster::GetData(const char* signature, BMessage& data)
if (signature == NULL || signature[0] == '\0') if (signature == NULL || signature[0] == '\0')
return B_BAD_VALUE; return B_BAD_VALUE;
BMessage request(B_GET_LAUNCH_CONNECTIONS); BMessage request(B_GET_LAUNCH_DATA);
status_t status = request.AddString("name", signature); status_t status = request.AddString("name", signature);
if (status != B_OK) if (status != B_OK)
return status; 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 void
BLaunchRoster::_InitMessenger() BLaunchRoster::_InitMessenger()
{ {

View File

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