launch_daemon: Added basic logging facility
* The daemon now stores many events in am internal log. * You can use "launch_roster log" to retrieve it.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2017, Haiku, Inc. All Rights Reserved.
|
* Copyright 2015-2018, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -45,6 +45,7 @@ enum {
|
|||||||
B_GET_LAUNCH_JOBS = 'lngj',
|
B_GET_LAUNCH_JOBS = 'lngj',
|
||||||
B_GET_LAUNCH_TARGET_INFO = 'lntI',
|
B_GET_LAUNCH_TARGET_INFO = 'lntI',
|
||||||
B_GET_LAUNCH_JOB_INFO = 'lnjI',
|
B_GET_LAUNCH_JOB_INFO = 'lnjI',
|
||||||
|
B_GET_LAUNCH_LOG = 'lnLL',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 Haiku, Inc. All rights reserved.
|
* Copyright 2015-2018 Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _LAUNCH_ROSTER_H
|
#ifndef _LAUNCH_ROSTER_H
|
||||||
@@ -56,6 +56,9 @@ public:
|
|||||||
status_t GetJobs(const char* target, BStringList& jobs);
|
status_t GetJobs(const char* target, BStringList& jobs);
|
||||||
status_t GetJobInfo(const char* name, BMessage& info);
|
status_t GetJobInfo(const char* name, BMessage& info);
|
||||||
|
|
||||||
|
status_t GetLog(BMessage& info);
|
||||||
|
status_t GetLog(const BMessage& filter, BMessage& info);
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -70,6 +73,7 @@ private:
|
|||||||
uint32 flags = 0);
|
uint32 flags = 0);
|
||||||
status_t _GetInfo(uint32 what, const char* name,
|
status_t _GetInfo(uint32 what, const char* name,
|
||||||
BMessage& info);
|
BMessage& info);
|
||||||
|
status_t _GetLog(const BMessage* filter, BMessage& info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessenger fMessenger;
|
BMessenger fMessenger;
|
||||||
|
|||||||
+137
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016, Axel Dörfler, [email protected].
|
* Copyright 2015-2018, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -10,11 +10,12 @@
|
|||||||
#include <LaunchRoster.h>
|
#include <LaunchRoster.h>
|
||||||
#include <StringList.h>
|
#include <StringList.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
static struct option const kLongOptions[] = {
|
static struct option const kLongOptions[] = {
|
||||||
@@ -23,6 +24,16 @@ static struct option const kLongOptions[] = {
|
|||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct option const kLogLongOptions[] = {
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"raw", no_argument, 0, 'r'},
|
||||||
|
{"user", no_argument, 0, 'u'},
|
||||||
|
{"system", no_argument, 0, 's'},
|
||||||
|
{"event", required_argument, 0, 'e'},
|
||||||
|
{"limit", required_argument, 0, 'l'},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
static const char *kProgramName = __progname;
|
static const char *kProgramName = __progname;
|
||||||
|
|
||||||
@@ -61,6 +72,127 @@ list_targets(bool verbose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_log(const BMessage& log)
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
bigtime_t runtime = system_time();
|
||||||
|
|
||||||
|
for (int32 index = 0;; index++) {
|
||||||
|
BMessage item;
|
||||||
|
if (log.FindMessage("item", index, &item) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint64 when;
|
||||||
|
const char* message;
|
||||||
|
if (item.FindUInt64("when", &when) != B_OK
|
||||||
|
|| item.FindString("message", &message) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
time_t at = now - (runtime - when) / 1000000l;
|
||||||
|
struct tm tm;
|
||||||
|
localtime_r(&at, &tm);
|
||||||
|
char label[256];
|
||||||
|
strftime(label, sizeof(label), "%F %X", &tm);
|
||||||
|
printf("%s %s\n", label, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_usage(int status)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s log [-rusel] [<job-name>]\n"
|
||||||
|
"Where the following options are allowed:\n"
|
||||||
|
" -u --user List only user log entries\n"
|
||||||
|
" -s --system List only system log entries\n"
|
||||||
|
" -e --event Filter by event name (partial names accepted)\n"
|
||||||
|
" -l --limit <n> Limit output to <n> events\n"
|
||||||
|
"<job-name>, if given, filters the jobs by name.\n",
|
||||||
|
kProgramName);
|
||||||
|
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_log(int argCount, char** args)
|
||||||
|
{
|
||||||
|
bool raw = false;
|
||||||
|
bool userOnly = false;
|
||||||
|
bool systemOnly = false;
|
||||||
|
int32 limit = 0;
|
||||||
|
const char* event = NULL;
|
||||||
|
const char* job = NULL;
|
||||||
|
|
||||||
|
optind = 0;
|
||||||
|
int c;
|
||||||
|
while ((c = getopt_long(argCount, args, "hruse:l:", kLogLongOptions, NULL))
|
||||||
|
!= -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
log_usage(0);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
raw = true;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
userOnly = true;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
systemOnly = true;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
event = optarg;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
limit = strtol(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argCount - optind >= 1)
|
||||||
|
job = args[optind];
|
||||||
|
|
||||||
|
BLaunchRoster roster;
|
||||||
|
BMessage filter;
|
||||||
|
if (userOnly)
|
||||||
|
filter.AddBool("userOnly", true);
|
||||||
|
if (systemOnly)
|
||||||
|
filter.AddBool("systemOnly", true);
|
||||||
|
if (event != NULL)
|
||||||
|
filter.AddString("event", event);
|
||||||
|
if (job != NULL)
|
||||||
|
filter.AddString("job", job);
|
||||||
|
if (limit != 0)
|
||||||
|
filter.AddInt32("limit", limit);
|
||||||
|
|
||||||
|
BMessage info;
|
||||||
|
status_t status = roster.GetLog(filter, info);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "%s: Could not get log: %s\n", kProgramName,
|
||||||
|
strerror(status));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw) {
|
||||||
|
info.PrintToStream();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_log(info);
|
||||||
|
|
||||||
|
BMessage user;
|
||||||
|
if (info.FindMessage("user", &user) == B_OK) {
|
||||||
|
if (user.HasMessage("item"))
|
||||||
|
puts("User log:");
|
||||||
|
print_log(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_info(const char* name)
|
get_info(const char* name)
|
||||||
{
|
{
|
||||||
@@ -165,7 +297,7 @@ main(int argc, char** argv)
|
|||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt_long(argc, argv, "hv", kLongOptions, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "+hv", kLongOptions, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
@@ -188,6 +320,8 @@ main(int argc, char** argv)
|
|||||||
list_jobs(verbose);
|
list_jobs(verbose);
|
||||||
} else if (strcmp(command, "list-targets") == 0) {
|
} else if (strcmp(command, "list-targets") == 0) {
|
||||||
list_targets(verbose);
|
list_targets(verbose);
|
||||||
|
} else if (strcmp(command, "log") == 0) {
|
||||||
|
get_log(argc - optind, &argv[optind]);
|
||||||
} else if (argc == optind + 1) {
|
} else if (argc == optind + 1) {
|
||||||
// For convenience (the "info" command can be omitted)
|
// For convenience (the "info" command can be omitted)
|
||||||
get_info(command);
|
get_info(command);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 Haiku, Inc. All rights reserved.
|
* Copyright 2015-2017 Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -338,6 +338,20 @@ BLaunchRoster::GetJobInfo(const char* name, BMessage& info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::GetLog(BMessage& info)
|
||||||
|
{
|
||||||
|
return _GetLog(NULL, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::GetLog(const BMessage& filter, BMessage& info)
|
||||||
|
{
|
||||||
|
return _GetLog(&filter, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BLaunchRoster::_InitMessenger()
|
BLaunchRoster::_InitMessenger()
|
||||||
{
|
{
|
||||||
@@ -414,3 +428,17 @@ BLaunchRoster::_GetInfo(uint32 what, const char* name, BMessage& info)
|
|||||||
|
|
||||||
return _SendRequest(request, info);
|
return _SendRequest(request, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BLaunchRoster::_GetLog(const BMessage* filter, BMessage& info)
|
||||||
|
{
|
||||||
|
BMessage request(B_GET_LAUNCH_LOG);
|
||||||
|
status_t status = request.AddInt32("user", getuid());
|
||||||
|
if (status == B_OK && filter != NULL)
|
||||||
|
status = request.AddMessage("filter", filter);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return _SendRequest(request, info);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015, Axel Dörfler, [email protected].
|
* Copyright 2015-2018, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
virtual status_t Register(EventRegistrator& registrator);
|
virtual status_t Register(EventRegistrator& registrator);
|
||||||
virtual void Unregister(EventRegistrator& registrator);
|
virtual void Unregister(EventRegistrator& registrator);
|
||||||
|
|
||||||
virtual void Trigger();
|
virtual void Trigger(Event* origin);
|
||||||
|
|
||||||
virtual BaseJob* Owner() const;
|
virtual BaseJob* Owner() const;
|
||||||
virtual void SetOwner(BaseJob* owner);
|
virtual void SetOwner(BaseJob* owner);
|
||||||
@@ -205,11 +205,11 @@ Event::Triggered() const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Event::Trigger()
|
Event::Trigger(Event* origin)
|
||||||
{
|
{
|
||||||
fTriggered = true;
|
fTriggered = true;
|
||||||
if (fParent != NULL)
|
if (fParent != NULL)
|
||||||
fParent->Trigger();
|
fParent->Trigger(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -336,12 +336,13 @@ EventContainer::Unregister(EventRegistrator& registrator)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EventContainer::Trigger()
|
EventContainer::Trigger(Event* origin)
|
||||||
{
|
{
|
||||||
Event::Trigger();
|
Event::Trigger(origin);
|
||||||
|
|
||||||
if (Parent() == NULL && Owner() != NULL) {
|
if (Parent() == NULL && Owner() != NULL) {
|
||||||
BMessage message(kMsgEventTriggered);
|
BMessage message(kMsgEventTriggered);
|
||||||
|
message.AddPointer("event", origin);
|
||||||
message.AddString("owner", Owner()->Name());
|
message.AddString("owner", Owner()->Name());
|
||||||
fTarget.SendMessage(&message);
|
fTarget.SendMessage(&message);
|
||||||
}
|
}
|
||||||
@@ -620,7 +621,7 @@ VolumeMountedEvent::ToString() const
|
|||||||
void
|
void
|
||||||
VolumeMountedEvent::VolumeMounted(dev_t device)
|
VolumeMountedEvent::VolumeMounted(dev_t device)
|
||||||
{
|
{
|
||||||
Trigger();
|
Trigger(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -667,7 +668,7 @@ void
|
|||||||
NetworkAvailableEvent::NetworkAvailabilityChanged(bool available)
|
NetworkAvailableEvent::NetworkAvailabilityChanged(bool available)
|
||||||
{
|
{
|
||||||
if (available)
|
if (available)
|
||||||
Trigger();
|
Trigger(this);
|
||||||
else
|
else
|
||||||
ResetSticky();
|
ResetSticky();
|
||||||
}
|
}
|
||||||
@@ -737,7 +738,7 @@ Events::TriggerExternalEvent(Event* event, const char* name)
|
|||||||
Event* event = container->Events().ItemAt(index);
|
Event* event = container->Events().ItemAt(index);
|
||||||
if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) {
|
if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) {
|
||||||
if (external->Name() == name) {
|
if (external->Name() == name) {
|
||||||
external->Trigger();
|
external->Trigger(container);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (dynamic_cast<EventContainer*>(event) != NULL) {
|
} else if (dynamic_cast<EventContainer*>(event) != NULL) {
|
||||||
@@ -794,7 +795,7 @@ Events::TriggerDemand(Event* event, bool testOnly)
|
|||||||
if (testOnly)
|
if (testOnly)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
childEvent->Trigger();
|
childEvent->Trigger(childEvent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dynamic_cast<EventContainer*>(childEvent) != NULL) {
|
if (dynamic_cast<EventContainer*>(childEvent) != NULL) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015, Axel Dörfler, [email protected].
|
* Copyright 2015-2018, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef EVENTS_H
|
#ifndef EVENTS_H
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
EventRegistrator& registrator) = 0;
|
EventRegistrator& registrator) = 0;
|
||||||
|
|
||||||
bool Triggered() const;
|
bool Triggered() const;
|
||||||
virtual void Trigger();
|
virtual void Trigger(Event* origin);
|
||||||
virtual void ResetTrigger();
|
virtual void ResetTrigger();
|
||||||
|
|
||||||
virtual BaseJob* Owner() const;
|
virtual BaseJob* Owner() const;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
SubDir HAIKU_TOP src servers launch ;
|
SubDir HAIKU_TOP src servers launch ;
|
||||||
|
|
||||||
UsePrivateHeaders app libroot shared storage support ;
|
UsePrivateHeaders app kernel libroot shared storage support ;
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
|
||||||
@@ -13,6 +13,7 @@ Server launch_daemon
|
|||||||
Conditions.cpp
|
Conditions.cpp
|
||||||
Events.cpp
|
Events.cpp
|
||||||
Job.cpp
|
Job.cpp
|
||||||
|
Log.cpp
|
||||||
NetworkWatcher.cpp
|
NetworkWatcher.cpp
|
||||||
SettingsParser.cpp
|
SettingsParser.cpp
|
||||||
Target.cpp
|
Target.cpp
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016, Axel Dörfler, [email protected].
|
* Copyright 2015-2018, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -34,7 +34,8 @@ Job::Job(const char* name)
|
|||||||
fToken((uint32)B_PREFERRED_TOKEN),
|
fToken((uint32)B_PREFERRED_TOKEN),
|
||||||
fLaunchStatus(B_NO_INIT),
|
fLaunchStatus(B_NO_INIT),
|
||||||
fTarget(NULL),
|
fTarget(NULL),
|
||||||
fPendingLaunchDataReplies(0, false)
|
fPendingLaunchDataReplies(0, false),
|
||||||
|
fTeamListener(NULL)
|
||||||
{
|
{
|
||||||
mutex_init(&fLaunchStatusLock, "launch status lock");
|
mutex_init(&fLaunchStatusLock, "launch status lock");
|
||||||
}
|
}
|
||||||
@@ -694,7 +695,7 @@ Job::_Launch(const char* signature, entry_ref* ref, int argCount,
|
|||||||
resume_thread(mainThread);
|
resume_thread(mainThread);
|
||||||
|
|
||||||
if (fTeamListener != NULL)
|
if (fTeamListener != NULL)
|
||||||
fTeamListener->TeamLaunched(this);
|
fTeamListener->TeamLaunched(this, result);
|
||||||
} else
|
} else
|
||||||
kill_thread(mainThread);
|
kill_thread(mainThread);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015, Axel Dörfler, [email protected].
|
* Copyright 2015-2018, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef JOB_H
|
#ifndef JOB_H
|
||||||
@@ -34,7 +34,7 @@ typedef std::map<BString, BMessage> PortMap;
|
|||||||
|
|
||||||
class TeamListener {
|
class TeamListener {
|
||||||
public:
|
public:
|
||||||
virtual void TeamLaunched(Job* job) = 0;
|
virtual void TeamLaunched(Job* job, status_t status) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2017, Axel Dörfler, [email protected].
|
* Copyright 2015-2018, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "InitSharedMemoryDirectoryJob.h"
|
#include "InitSharedMemoryDirectoryJob.h"
|
||||||
#include "InitTemporaryDirectoryJob.h"
|
#include "InitTemporaryDirectoryJob.h"
|
||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
|
#include "Log.h"
|
||||||
#include "SettingsParser.h"
|
#include "SettingsParser.h"
|
||||||
#include "Target.h"
|
#include "Target.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
@@ -147,7 +148,7 @@ public:
|
|||||||
const char* name);
|
const char* name);
|
||||||
|
|
||||||
// TeamListener
|
// TeamListener
|
||||||
virtual void TeamListener(Job* job);
|
virtual void TeamLaunched(Job* job, status_t status);
|
||||||
|
|
||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
@@ -170,6 +171,7 @@ private:
|
|||||||
void _HandleGetLaunchTargetInfo(BMessage* message);
|
void _HandleGetLaunchTargetInfo(BMessage* message);
|
||||||
void _HandleGetLaunchJobs(BMessage* message);
|
void _HandleGetLaunchJobs(BMessage* message);
|
||||||
void _HandleGetLaunchJobInfo(BMessage* message);
|
void _HandleGetLaunchJobInfo(BMessage* message);
|
||||||
|
void _HandleGetLaunchLog(BMessage* message);
|
||||||
uid_t _GetUserID(BMessage* message);
|
uid_t _GetUserID(BMessage* message);
|
||||||
|
|
||||||
void _ReadPaths(const BStringList& paths);
|
void _ReadPaths(const BStringList& paths);
|
||||||
@@ -222,6 +224,7 @@ private:
|
|||||||
void _AddInitJob(BJob* job);
|
void _AddInitJob(BJob* job);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Log fLog;
|
||||||
JobMap fJobs;
|
JobMap fJobs;
|
||||||
TargetMap fTargets;
|
TargetMap fTargets;
|
||||||
BStringList fRunTargets;
|
BStringList fRunTargets;
|
||||||
@@ -425,8 +428,10 @@ LaunchDaemon::UnregisterExternalEvent(Event* event, const char* name)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LaunchDaemon::RegisterTeam(Job* job)
|
LaunchDaemon::TeamLaunched(Job* job, status_t status)
|
||||||
{
|
{
|
||||||
|
fLog.JobLaunched(job, status);
|
||||||
|
|
||||||
MutexLocker locker(fTeamsLock);
|
MutexLocker locker(fTeamsLock);
|
||||||
fTeams.insert(std::make_pair(job->Team(), job));
|
fTeams.insert(std::make_pair(job->Team(), job));
|
||||||
}
|
}
|
||||||
@@ -514,6 +519,11 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
|||||||
if (found != fTeams.end()) {
|
if (found != fTeams.end()) {
|
||||||
Job* job = found->second;
|
Job* job = found->second;
|
||||||
TRACE("Job %s ended!\n", job->Name());
|
TRACE("Job %s ended!\n", job->Name());
|
||||||
|
|
||||||
|
// Get the exit status, and pass it on to the log
|
||||||
|
status_t exitStatus = B_OK;
|
||||||
|
wait_for_thread(team, &exitStatus);
|
||||||
|
fLog.JobTerminated(job, exitStatus);
|
||||||
job->TeamDeleted();
|
job->TeamDeleted();
|
||||||
|
|
||||||
if (job->IsService()) {
|
if (job->IsService()) {
|
||||||
@@ -613,22 +623,30 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
|||||||
_HandleGetLaunchJobInfo(message);
|
_HandleGetLaunchJobInfo(message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case B_GET_LAUNCH_LOG:
|
||||||
|
_HandleGetLaunchLog(message);
|
||||||
|
break;
|
||||||
|
|
||||||
case kMsgEventTriggered:
|
case kMsgEventTriggered:
|
||||||
{
|
{
|
||||||
// An internal event has been triggered.
|
// An internal event has been triggered.
|
||||||
// Check if its job can be launched now.
|
// Check if its job(s) can be launched now.
|
||||||
const char* name = message->GetString("owner");
|
const char* name = message->GetString("owner");
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Event* event = (Event*)message->GetPointer("event");
|
||||||
|
|
||||||
Job* job = FindJob(name);
|
Job* job = FindJob(name);
|
||||||
if (job != NULL) {
|
if (job != NULL) {
|
||||||
|
fLog.EventTriggered(job, event);
|
||||||
_LaunchJob(job);
|
_LaunchJob(job);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Target* target = FindTarget(name);
|
Target* target = FindTarget(name);
|
||||||
if (target != NULL) {
|
if (target != NULL) {
|
||||||
|
fLog.EventTriggered(target, event);
|
||||||
_LaunchJobs(target);
|
_LaunchJobs(target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -785,7 +803,9 @@ LaunchDaemon::_HandleStopLaunchTarget(BMessage* message)
|
|||||||
if (message->FindMessage("data", &data) == B_OK)
|
if (message->FindMessage("data", &data) == B_OK)
|
||||||
target->AddData(data.GetString("name"), data);
|
target->AddData(data.GetString("name"), data);
|
||||||
|
|
||||||
_StopJobs(target, message->GetBool("force"));
|
bool force = message->GetBool("force");
|
||||||
|
fLog.JobStopped(target, force);
|
||||||
|
_StopJobs(target, force);
|
||||||
|
|
||||||
BMessage reply((uint32)B_OK);
|
BMessage reply((uint32)B_OK);
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
@@ -848,6 +868,7 @@ LaunchDaemon::_HandleEnableLaunchJob(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
job->SetEnabled(enable);
|
job->SetEnabled(enable);
|
||||||
|
fLog.JobEnabled(job, enable);
|
||||||
|
|
||||||
BMessage reply((uint32)B_OK);
|
BMessage reply((uint32)B_OK);
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
@@ -877,7 +898,9 @@ LaunchDaemon::_HandleStopLaunchJob(BMessage* message)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_StopJob(job, message->GetBool("force"));
|
bool force = message->GetBool("force");
|
||||||
|
fLog.JobStopped(job, force);
|
||||||
|
_StopJob(job, force);
|
||||||
|
|
||||||
BMessage reply((uint32)B_OK);
|
BMessage reply((uint32)B_OK);
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
@@ -965,6 +988,8 @@ LaunchDaemon::_HandleRegisterLaunchEvent(BMessage* message)
|
|||||||
eventName.Prepend(ownerName);
|
eventName.Prepend(ownerName);
|
||||||
fEvents.insert(std::make_pair(eventName, event));
|
fEvents.insert(std::make_pair(eventName, event));
|
||||||
_ResolveExternalEvents(event, eventName);
|
_ResolveExternalEvents(event, eventName);
|
||||||
|
|
||||||
|
fLog.ExternalEventRegistered(name);
|
||||||
} else
|
} else
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
} else
|
} else
|
||||||
@@ -1002,6 +1027,8 @@ LaunchDaemon::_HandleUnregisterLaunchEvent(BMessage* message)
|
|||||||
eventName.Prepend("/");
|
eventName.Prepend("/");
|
||||||
eventName.Prepend(ownerName);
|
eventName.Prepend(ownerName);
|
||||||
fEvents.erase(eventName);
|
fEvents.erase(eventName);
|
||||||
|
|
||||||
|
fLog.ExternalEventRegistered(name);
|
||||||
} else
|
} else
|
||||||
status = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
|
|
||||||
@@ -1028,6 +1055,8 @@ LaunchDaemon::_HandleNotifyLaunchEvent(BMessage* message)
|
|||||||
|
|
||||||
ExternalEventSource* event = _FindEvent(ownerName, name);
|
ExternalEventSource* event = _FindEvent(ownerName, name);
|
||||||
if (event != NULL) {
|
if (event != NULL) {
|
||||||
|
fLog.ExternalEventTriggered(name);
|
||||||
|
|
||||||
// Evaluate all of its jobs
|
// Evaluate all of its jobs
|
||||||
int32 count = event->CountListeners();
|
int32 count = event->CountListeners();
|
||||||
for (int32 index = 0; index < count; index++) {
|
for (int32 index = 0; index < count; index++) {
|
||||||
@@ -1223,6 +1252,90 @@ LaunchDaemon::_HandleGetLaunchJobInfo(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LaunchDaemon::_HandleGetLaunchLog(BMessage* message)
|
||||||
|
{
|
||||||
|
uid_t user = _GetUserID(message);
|
||||||
|
if (user < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage filter;
|
||||||
|
BString jobName;
|
||||||
|
const char* event = NULL;
|
||||||
|
int32 limit = 0;
|
||||||
|
bool systemOnly = false;
|
||||||
|
bool userOnly = false;
|
||||||
|
if (message->FindMessage("filter", &filter) == B_OK) {
|
||||||
|
limit = filter.GetInt32("limit", 0);
|
||||||
|
jobName = filter.GetString("job");
|
||||||
|
jobName.ToLower();
|
||||||
|
event = filter.GetString("event");
|
||||||
|
systemOnly = filter.GetBool("systemOnly");
|
||||||
|
userOnly = filter.GetBool("userOnly");
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage info((uint32)B_OK);
|
||||||
|
int32 count = 0;
|
||||||
|
|
||||||
|
if (user == 0 || !userOnly) {
|
||||||
|
LogItemList::Iterator iterator = fLog.Iterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
LogItem* item = iterator.Next();
|
||||||
|
if (!item->Matches(jobName.IsEmpty() ? NULL : jobName.String(),
|
||||||
|
event)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage itemMessage;
|
||||||
|
itemMessage.AddUInt64("when", item->When());
|
||||||
|
itemMessage.AddInt32("type", (int32)item->Type());
|
||||||
|
itemMessage.AddString("message", item->Message());
|
||||||
|
|
||||||
|
BMessage parameter;
|
||||||
|
item->GetParameter(parameter);
|
||||||
|
itemMessage.AddMessage("parameter", ¶meter);
|
||||||
|
|
||||||
|
info.AddMessage("item", &itemMessage);
|
||||||
|
|
||||||
|
// limit == 0 means no limit
|
||||||
|
if (++count == limit)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the list from the user daemon, and merge it into our reply
|
||||||
|
Session* session = FindSession(user);
|
||||||
|
if (session != NULL && !systemOnly) {
|
||||||
|
if (limit != 0) {
|
||||||
|
// Update limit for user daemon
|
||||||
|
limit -= count;
|
||||||
|
if (limit <= 0) {
|
||||||
|
message->SendReply(&info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage reply;
|
||||||
|
|
||||||
|
BMessage request(B_GET_LAUNCH_LOG);
|
||||||
|
status_t status = request.AddInt32("user", 0);
|
||||||
|
if (status == B_OK && (limit != 0 || !jobName.IsEmpty()
|
||||||
|
|| event != NULL)) {
|
||||||
|
// Forward filter specification when needed
|
||||||
|
status = filter.SetInt32("limit", limit);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = request.AddMessage("filter", &filter);
|
||||||
|
}
|
||||||
|
if (status == B_OK)
|
||||||
|
status = session->Daemon().SendMessage(&request, &reply);
|
||||||
|
if (status == B_OK)
|
||||||
|
info.AddMessage("user", &reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
message->SendReply(&info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uid_t
|
uid_t
|
||||||
LaunchDaemon::_GetUserID(BMessage* message)
|
LaunchDaemon::_GetUserID(BMessage* message)
|
||||||
{
|
{
|
||||||
@@ -1419,8 +1532,10 @@ LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
|
|||||||
} else
|
} else
|
||||||
TRACE(" amend job \"%s\"\n", name.String());
|
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()));
|
||||||
|
fLog.JobEnabled(job, job->IsEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
if (message.HasBool("legacy"))
|
if (message.HasBool("legacy"))
|
||||||
job->SetCreateDefaultPort(!message.GetBool("legacy", !service));
|
job->SetCreateDefaultPort(!message.GetBool("legacy", !service));
|
||||||
@@ -1477,12 +1592,15 @@ LaunchDaemon::_InitJobs(Target* target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status == B_OK) {
|
||||||
|
fLog.JobInitialized(job);
|
||||||
|
} else {
|
||||||
if (status != B_NO_INIT) {
|
if (status != B_NO_INIT) {
|
||||||
// TODO: log error
|
// TODO: log error
|
||||||
debug_printf("Init \"%s\" failed: %s\n", job->Name(),
|
debug_printf("Init \"%s\" failed: %s\n", job->Name(),
|
||||||
strerror(status));
|
strerror(status));
|
||||||
}
|
}
|
||||||
|
fLog.JobIgnored(job, status);
|
||||||
|
|
||||||
// Remove jobs that won't be used later on
|
// Remove jobs that won't be used later on
|
||||||
fJobs.erase(remove);
|
fJobs.erase(remove);
|
||||||
|
|||||||
@@ -0,0 +1,810 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017-2018, Axel Dörfler, axeld@pinc-software.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include "Events.h"
|
||||||
|
#include "Job.h"
|
||||||
|
|
||||||
|
|
||||||
|
const size_t kMaxItems = 10000;
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractJobLogItem : public LogItem {
|
||||||
|
public:
|
||||||
|
AbstractJobLogItem(BaseJob* job);
|
||||||
|
virtual ~AbstractJobLogItem();
|
||||||
|
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
virtual bool Matches(const char* jobName,
|
||||||
|
const char* eventName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseJob* fJob;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JobInitializedLogItem : public AbstractJobLogItem {
|
||||||
|
public:
|
||||||
|
JobInitializedLogItem(Job* job);
|
||||||
|
virtual ~JobInitializedLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JobIgnoredLogItem : public LogItem {
|
||||||
|
public:
|
||||||
|
JobIgnoredLogItem(Job* job, status_t error);
|
||||||
|
virtual ~JobIgnoredLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
virtual bool Matches(const char* jobName,
|
||||||
|
const char* eventName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BString fJobName;
|
||||||
|
status_t fError;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JobLaunchedLogItem : public AbstractJobLogItem {
|
||||||
|
public:
|
||||||
|
JobLaunchedLogItem(Job* job, status_t status);
|
||||||
|
virtual ~JobLaunchedLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t fStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JobTerminatedLogItem : public AbstractJobLogItem {
|
||||||
|
public:
|
||||||
|
JobTerminatedLogItem(Job* job, status_t status);
|
||||||
|
virtual ~JobTerminatedLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t fStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JobEnabledLogItem : public AbstractJobLogItem {
|
||||||
|
public:
|
||||||
|
JobEnabledLogItem(Job* job, bool enabled);
|
||||||
|
virtual ~JobEnabledLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fEnabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JobStoppedLogItem : public AbstractJobLogItem {
|
||||||
|
public:
|
||||||
|
JobStoppedLogItem(BaseJob* job, bool force);
|
||||||
|
virtual ~JobStoppedLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fForce;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class EventLogItem : public AbstractJobLogItem {
|
||||||
|
public:
|
||||||
|
EventLogItem(BaseJob* job, Event* event);
|
||||||
|
virtual ~EventLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
virtual bool Matches(const char* jobName,
|
||||||
|
const char* eventName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Event* fEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractExternalEventLogItem : public LogItem {
|
||||||
|
public:
|
||||||
|
AbstractExternalEventLogItem(const char* name);
|
||||||
|
virtual ~AbstractExternalEventLogItem();
|
||||||
|
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const;
|
||||||
|
virtual bool Matches(const char* jobName,
|
||||||
|
const char* eventName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BString fEventName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ExternalEventLogItem : public AbstractExternalEventLogItem {
|
||||||
|
public:
|
||||||
|
ExternalEventLogItem(const char* name);
|
||||||
|
virtual ~ExternalEventLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ExternalEventRegisteredLogItem : public AbstractExternalEventLogItem {
|
||||||
|
public:
|
||||||
|
ExternalEventRegisteredLogItem(
|
||||||
|
const char* name);
|
||||||
|
virtual ~ExternalEventRegisteredLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ExternalEventUnregisteredLogItem : public AbstractExternalEventLogItem {
|
||||||
|
public:
|
||||||
|
ExternalEventUnregisteredLogItem(
|
||||||
|
const char* name);
|
||||||
|
virtual ~ExternalEventUnregisteredLogItem();
|
||||||
|
|
||||||
|
virtual LogItemType Type() const;
|
||||||
|
virtual status_t GetMessage(BString& target) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
LogItem::LogItem()
|
||||||
|
:
|
||||||
|
fWhen(system_time())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItem::~LogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BString
|
||||||
|
LogItem::Message() const
|
||||||
|
{
|
||||||
|
BString message;
|
||||||
|
GetMessage(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - Log
|
||||||
|
|
||||||
|
|
||||||
|
Log::Log()
|
||||||
|
:
|
||||||
|
fCount(0)
|
||||||
|
{
|
||||||
|
mutex_init(&fLock, "log lock");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::Add(LogItem* item)
|
||||||
|
{
|
||||||
|
MutexLocker locker(fLock);
|
||||||
|
if (fCount == kMaxItems)
|
||||||
|
fItems.Remove(fItems.First());
|
||||||
|
else
|
||||||
|
fCount++;
|
||||||
|
|
||||||
|
fItems.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::JobInitialized(Job* job)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) JobInitializedLogItem(job);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else
|
||||||
|
debug_printf("Initialized job \"%s\"\n", job->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::JobIgnored(Job* job, status_t status)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) JobIgnoredLogItem(job, status);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else {
|
||||||
|
debug_printf("Ignored job \"%s\": %s\n", job->Name(),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::JobLaunched(Job* job, status_t status)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) JobLaunchedLogItem(job, status);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else {
|
||||||
|
debug_printf("Launched job \"%s\": %s\n", job->Name(),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::JobTerminated(Job* job, status_t status)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) JobTerminatedLogItem(job, status);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else {
|
||||||
|
debug_printf("Terminated job \"%s\": %s\n", job->Name(),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::JobEnabled(Job* job, bool enabled)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) JobEnabledLogItem(job, enabled);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else
|
||||||
|
debug_printf("Enabled job \"%s\": %d\n", job->Name(), enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::JobStopped(BaseJob* job, bool force)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) JobStoppedLogItem(job, force);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else
|
||||||
|
debug_printf("Stopped job \"%s\"\n", job->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::EventTriggered(BaseJob* job, Event* event)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) EventLogItem(job, event);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else {
|
||||||
|
debug_printf("Event triggered for \"%s\": %s\n", job->Name(),
|
||||||
|
event->ToString().String());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::ExternalEventTriggered(const char* name)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) ExternalEventLogItem(name);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else
|
||||||
|
debug_printf("External event triggered: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::ExternalEventRegistered(const char* name)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) ExternalEventRegisteredLogItem(name);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else
|
||||||
|
debug_printf("External event registered: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Log::ExternalEventUnregistered(const char* name)
|
||||||
|
{
|
||||||
|
LogItem* item = new(std::nothrow) ExternalEventUnregisteredLogItem(name);
|
||||||
|
if (item != NULL)
|
||||||
|
Add(item);
|
||||||
|
else
|
||||||
|
debug_printf("External event unregistered: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - AbstractJobLogItem
|
||||||
|
|
||||||
|
|
||||||
|
AbstractJobLogItem::AbstractJobLogItem(BaseJob* job)
|
||||||
|
:
|
||||||
|
fJob(job)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AbstractJobLogItem::~AbstractJobLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AbstractJobLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
return parameter.AddString("job", fJob->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AbstractJobLogItem::Matches(const char* jobName, const char* eventName)
|
||||||
|
{
|
||||||
|
if (jobName == NULL && eventName == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (jobName != NULL && strcmp(fJob->Name(), jobName) == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - JobInitializedLogItem
|
||||||
|
|
||||||
|
|
||||||
|
JobInitializedLogItem::JobInitializedLogItem(Job* job)
|
||||||
|
:
|
||||||
|
AbstractJobLogItem(job)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JobInitializedLogItem::~JobInitializedLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
JobInitializedLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kJobInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobInitializedLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Job \"%s\" initialized.", fJob->Name());
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - JobIgnoredLogItem
|
||||||
|
|
||||||
|
|
||||||
|
JobIgnoredLogItem::JobIgnoredLogItem(Job* job, status_t error)
|
||||||
|
:
|
||||||
|
fJobName(job->Name()),
|
||||||
|
fError(error)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JobIgnoredLogItem::~JobIgnoredLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
JobIgnoredLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kJobIgnored;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobIgnoredLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Ignored job \"%s\" due %s", fJobName.String(),
|
||||||
|
strerror(fError));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobIgnoredLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
status_t status = parameter.AddString("job", fJobName);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = parameter.AddInt32("error", fError);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
JobIgnoredLogItem::Matches(const char* jobName, const char* eventName)
|
||||||
|
{
|
||||||
|
if (jobName == NULL && eventName == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (jobName != NULL && fJobName == jobName)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - JobLaunchedLogItem
|
||||||
|
|
||||||
|
|
||||||
|
JobLaunchedLogItem::JobLaunchedLogItem(Job* job, status_t status)
|
||||||
|
:
|
||||||
|
AbstractJobLogItem(job),
|
||||||
|
fStatus(status)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JobLaunchedLogItem::~JobLaunchedLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
JobLaunchedLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kJobLaunched;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobLaunchedLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Job \"%s\" launched: %s", fJob->Name(),
|
||||||
|
strerror(fStatus));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobLaunchedLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
status_t status = AbstractJobLogItem::GetParameter(parameter);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = parameter.AddInt32("status", fStatus);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - JobTerminatedLogItem
|
||||||
|
|
||||||
|
|
||||||
|
JobTerminatedLogItem::JobTerminatedLogItem(Job* job, status_t status)
|
||||||
|
:
|
||||||
|
AbstractJobLogItem(job),
|
||||||
|
fStatus(status)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JobTerminatedLogItem::~JobTerminatedLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
JobTerminatedLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kJobTerminated;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobTerminatedLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Job \"%s\" terminated: %s", fJob->Name(),
|
||||||
|
strerror(fStatus));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobTerminatedLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
status_t status = AbstractJobLogItem::GetParameter(parameter);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = parameter.AddInt32("status", fStatus);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - JobEnabledLogItem
|
||||||
|
|
||||||
|
|
||||||
|
JobEnabledLogItem::JobEnabledLogItem(Job* job, bool enabled)
|
||||||
|
:
|
||||||
|
AbstractJobLogItem(job),
|
||||||
|
fEnabled(enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JobEnabledLogItem::~JobEnabledLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
JobEnabledLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kJobEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobEnabledLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Job \"%s\" %sabled", fJob->Name(),
|
||||||
|
fEnabled ? "en" : "dis");
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobEnabledLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
status_t status = AbstractJobLogItem::GetParameter(parameter);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = parameter.AddBool("enabled", fEnabled);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - JobStoppedLogItem
|
||||||
|
|
||||||
|
|
||||||
|
JobStoppedLogItem::JobStoppedLogItem(BaseJob* job, bool force)
|
||||||
|
:
|
||||||
|
AbstractJobLogItem(job),
|
||||||
|
fForce(force)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JobStoppedLogItem::~JobStoppedLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
JobStoppedLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kJobStopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobStoppedLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Job \"%s\" %sstopped", fJob->Name(),
|
||||||
|
fForce ? "force " : "");
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
JobStoppedLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
status_t status = AbstractJobLogItem::GetParameter(parameter);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = parameter.AddBool("force", fForce);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - EventLogItem
|
||||||
|
|
||||||
|
|
||||||
|
EventLogItem::EventLogItem(BaseJob* job, Event* event)
|
||||||
|
:
|
||||||
|
AbstractJobLogItem(job),
|
||||||
|
fEvent(event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EventLogItem::~EventLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
EventLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EventLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("Event triggered \"%s\": \"%s\"", fJob->Name(),
|
||||||
|
fEvent->ToString().String());
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EventLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
status_t status = AbstractJobLogItem::GetParameter(parameter);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = parameter.AddString("event", fEvent->ToString());
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EventLogItem::Matches(const char* jobName, const char* eventName)
|
||||||
|
{
|
||||||
|
if (eventName != NULL && strstr(fEvent->ToString(), eventName) == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return AbstractJobLogItem::Matches(jobName, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ExternalEventLogItem
|
||||||
|
|
||||||
|
|
||||||
|
AbstractExternalEventLogItem::AbstractExternalEventLogItem(const char* name)
|
||||||
|
:
|
||||||
|
fEventName(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AbstractExternalEventLogItem::~AbstractExternalEventLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AbstractExternalEventLogItem::GetParameter(BMessage& parameter) const
|
||||||
|
{
|
||||||
|
return parameter.AddString("event", fEventName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AbstractExternalEventLogItem::Matches(const char* jobName,
|
||||||
|
const char* eventName)
|
||||||
|
{
|
||||||
|
if (jobName == NULL && eventName == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (eventName != NULL && strstr(fEventName.String(), eventName) != NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ExternalEventLogItem
|
||||||
|
|
||||||
|
|
||||||
|
ExternalEventLogItem::ExternalEventLogItem(const char* name)
|
||||||
|
:
|
||||||
|
AbstractExternalEventLogItem(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExternalEventLogItem::~ExternalEventLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
ExternalEventLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kExternalEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ExternalEventLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("External event triggered: \"%s\"",
|
||||||
|
fEventName.String());
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ExternalEventRegisteredLogItem
|
||||||
|
|
||||||
|
|
||||||
|
ExternalEventRegisteredLogItem::ExternalEventRegisteredLogItem(const char* name)
|
||||||
|
:
|
||||||
|
AbstractExternalEventLogItem(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExternalEventRegisteredLogItem::~ExternalEventRegisteredLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
ExternalEventRegisteredLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kExternalEventRegistered;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ExternalEventRegisteredLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("External event registered: \"%s\"",
|
||||||
|
fEventName.String());
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - ExternalEventUnregisteredLogItem
|
||||||
|
|
||||||
|
|
||||||
|
ExternalEventUnregisteredLogItem::ExternalEventUnregisteredLogItem(
|
||||||
|
const char* name)
|
||||||
|
:
|
||||||
|
AbstractExternalEventLogItem(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExternalEventUnregisteredLogItem::~ExternalEventUnregisteredLogItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogItemType
|
||||||
|
ExternalEventUnregisteredLogItem::Type() const
|
||||||
|
{
|
||||||
|
return kExternalEventUnregistered;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ExternalEventUnregisteredLogItem::GetMessage(BString& target) const
|
||||||
|
{
|
||||||
|
target.SetToFormat("External event unregistered: \"%s\"",
|
||||||
|
fEventName.String());
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017-2018, Axel Dörfler, axeld@pinc-software.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef LOG_H
|
||||||
|
#define LOG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include <locks.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BMessage;
|
||||||
|
|
||||||
|
class BaseJob;
|
||||||
|
class Event;
|
||||||
|
class Job;
|
||||||
|
|
||||||
|
|
||||||
|
enum LogItemType {
|
||||||
|
kJobInitialized,
|
||||||
|
kJobIgnored,
|
||||||
|
kJobLaunched,
|
||||||
|
kJobTerminated,
|
||||||
|
kJobEnabled,
|
||||||
|
kJobStopped,
|
||||||
|
kEvent,
|
||||||
|
kExternalEvent,
|
||||||
|
kExternalEventRegistered,
|
||||||
|
kExternalEventUnregistered,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LogItem : public DoublyLinkedListLinkImpl<LogItem> {
|
||||||
|
public:
|
||||||
|
public:
|
||||||
|
LogItem();
|
||||||
|
virtual ~LogItem();
|
||||||
|
|
||||||
|
bigtime_t When()
|
||||||
|
{ return fWhen; }
|
||||||
|
BString Message() const;
|
||||||
|
|
||||||
|
virtual LogItemType Type() const = 0;
|
||||||
|
virtual status_t GetMessage(BString& target) const = 0;
|
||||||
|
virtual status_t GetParameter(BMessage& parameter) const = 0;
|
||||||
|
virtual bool Matches(const char* jobName,
|
||||||
|
const char* eventName) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bigtime_t fWhen;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<LogItem> LogItemList;
|
||||||
|
|
||||||
|
|
||||||
|
class Log {
|
||||||
|
public:
|
||||||
|
Log();
|
||||||
|
|
||||||
|
void Add(LogItem* item);
|
||||||
|
|
||||||
|
LogItemList::Iterator
|
||||||
|
Iterator()
|
||||||
|
{ return fItems.GetIterator(); }
|
||||||
|
|
||||||
|
mutex& Lock()
|
||||||
|
{ return fLock; }
|
||||||
|
|
||||||
|
void JobInitialized(Job* job);
|
||||||
|
void JobIgnored(Job* job, status_t status);
|
||||||
|
|
||||||
|
void JobLaunched(Job* job, status_t status);
|
||||||
|
void JobTerminated(Job* job, status_t status);
|
||||||
|
|
||||||
|
void JobEnabled(Job* job, bool enabled);
|
||||||
|
void JobStopped(BaseJob* job, bool force);
|
||||||
|
|
||||||
|
void EventTriggered(BaseJob* job, Event* event);
|
||||||
|
|
||||||
|
void ExternalEventTriggered(const char* name);
|
||||||
|
void ExternalEventRegistered(const char* name);
|
||||||
|
void ExternalEventUnregistered(const char* name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutex fLock;
|
||||||
|
LogItemList fItems;
|
||||||
|
size_t fCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // LOG_H
|
||||||
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src tests servers launch ;
|
|||||||
|
|
||||||
AddSubDirSupportedPlatforms libbe_test ;
|
AddSubDirSupportedPlatforms libbe_test ;
|
||||||
|
|
||||||
UsePrivateHeaders app libroot shared storage support ;
|
UsePrivateHeaders app kernel libroot shared storage support ;
|
||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
|
||||||
@@ -39,6 +39,7 @@ Server test_launch_daemon :
|
|||||||
Conditions.cpp
|
Conditions.cpp
|
||||||
Events.cpp
|
Events.cpp
|
||||||
Job.cpp
|
Job.cpp
|
||||||
|
Log.cpp
|
||||||
NetworkWatcher.cpp
|
NetworkWatcher.cpp
|
||||||
SettingsParser.cpp
|
SettingsParser.cpp
|
||||||
Target.cpp
|
Target.cpp
|
||||||
|
|||||||
Reference in New Issue
Block a user