示例#1
0
void
LaunchDaemon::_HandleGetLaunchData(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

	BMessage reply((uint32)B_OK);
	bool launchJob = true;

	Job* job = FindJob(get_leaf(message->GetString("name")));
	if (job == NULL) {
		Session* session = FindSession(user);
		if (session != NULL) {
			// Forward request to user launch_daemon
			if (session->Daemon().SendMessage(message) == B_OK)
				return;
		}
		reply.what = B_NAME_NOT_FOUND;
	} else if (job->IsService() && !job->IsLaunched()) {
		if (job->InitCheck() == B_NO_INIT || !job->CheckCondition(*this)) {
			// The job exists, but cannot be started yet, as its
			// conditions are not met; don't make it available yet
			// TODO: we may not want to initialize jobs with conditions
			// that aren't met yet
			reply.what = B_NO_INIT;
		} else if (job->Event() != NULL) {
			if (!Events::TriggerDemand(job->Event())) {
				// The job is not triggered by demand; we cannot start it now
				reply.what = B_NO_INIT;
			} else {
				// The job has already been triggered, don't launch it again
				launchJob = false;
			}
		}
	} else
		launchJob = false;

	bool ownsMessage = false;
	if (reply.what == B_OK) {
		// Launch the job if it hasn't been launched already
		if (launchJob)
			_LaunchJob(job, TRIGGER_DEMAND);

		DetachCurrentMessage();
		status_t result = job->HandleGetLaunchData(message);
		if (result == B_OK) {
			// Replying is delegated to the job.
			return;
		}

		ownsMessage = true;
		reply.what = result;
	}

	message->SendReply(&reply);
	if (ownsMessage)
		delete message;
}
示例#2
0
void
LaunchDaemon::_HandleGetLaunchJobInfo(BMessage* message)
{
	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);
		return;
	}

	BMessage info(uint32(job != NULL ? B_OK : B_NAME_NOT_FOUND));
	if (job != NULL) {
		_GetBaseJobInfo(job, info);

		info.SetInt32("team", job->Team());
		info.SetBool("enabled", job->IsEnabled());
		info.SetBool("running", job->IsRunning());
		info.SetBool("launched", job->IsLaunched());
		info.SetBool("service", job->IsService());

		if (job->Target() != NULL)
			info.SetString("target", job->Target()->Name());

		for (int32 i = 0; i < job->Arguments().CountStrings(); i++)
			info.AddString("launch", job->Arguments().StringAt(i));

		for (int32 i = 0; i < job->Requirements().CountStrings(); i++)
			info.AddString("requires", job->Requirements().StringAt(i));

		PortMap::const_iterator iterator = job->Ports().begin();
		for (; iterator != job->Ports().end(); iterator++)
			info.AddMessage("port", &iterator->second);
	}
	message->SendReply(&info);
}
示例#3
0
Job::Job(const Job& other)
    :
    BaseJob(other.Name()),
    fEnabled(other.IsEnabled()),
    fService(other.IsService()),
    fCreateDefaultPort(other.CreateDefaultPort()),
    fLaunching(other.IsLaunching()),
    fInitStatus(B_NO_INIT),
    fTeam(-1),
    fDefaultPort(-1),
    fToken((uint32)B_PREFERRED_TOKEN),
    fLaunchStatus(B_NO_INIT),
    fTarget(other.Target()),
    fPendingLaunchDataReplies(0, false)
{
    mutex_init(&fLaunchStatusLock, "launch status lock");

    fCondition = other.fCondition;
    // TODO: copy events
    //fEvent = other.fEvent;
    fEnvironment = other.fEnvironment;
    fSourceFiles = other.fSourceFiles;

    for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
        AddArgument(other.Arguments().StringAt(i));

    for (int32 i = 0; i < other.Requirements().CountStrings(); i++)
        AddRequirement(other.Requirements().StringAt(i));

    PortMap::const_iterator constIterator = other.Ports().begin();
    for (; constIterator != other.Ports().end(); constIterator++) {
        fPortMap.insert(
            std::make_pair(constIterator->first, constIterator->second));
    }

    PortMap::iterator iterator = fPortMap.begin();
    for (; iterator != fPortMap.end(); iterator++)
        iterator->second.RemoveData("port");
}
示例#4
0
void
LaunchDaemon::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case B_SYSTEM_OBJECT_UPDATE:
		{
			int32 opcode = message->GetInt32("opcode", 0);
			team_id team = (team_id)message->GetInt32("team", -1);
			if (opcode != B_TEAM_DELETED || team < 0)
				break;

			MutexLocker locker(fTeamsLock);

			TeamMap::iterator found = fTeams.find(team);
			if (found != fTeams.end()) {
				Job* job = found->second;
				TRACE("Job %s ended!\n", job->Name());
				job->TeamDeleted();

				if (job->IsService()) {
					// TODO: take restart throttle into account
					// TODO: don't restart on shutdown
					_LaunchJob(job);
				}
			}
			break;
		}
		case B_SOME_APP_LAUNCHED:
		{
			team_id team = (team_id)message->GetInt32("be:team", -1);
			Job* job = NULL;

			MutexLocker locker(fTeamsLock);

			TeamMap::iterator found = fTeams.find(team);
			if (found != fTeams.end()) {
				job = found->second;
				locker.Unlock();
			} else {
				locker.Unlock();

				// Find job by name instead
				const char* signature = message->GetString("be:signature");
				job = FindJob(get_leaf(signature));
				if (job != NULL) {
					TRACE("Updated default port of untracked team %d, %s\n",
						(int)team, signature);
				}
			}

			if (job != NULL) {
				// Update port info
				app_info info;
				status_t status = be_roster->GetRunningAppInfo(team, &info);
				if (status == B_OK && info.port != job->DefaultPort()) {
					TRACE("Update default port for %s to %d\n", job->Name(),
						(int)info.port);
					job->SetDefaultPort(info.port);
				}
			}
			break;
		}

		case B_GET_LAUNCH_DATA:
			_HandleGetLaunchData(message);
			break;

		case B_LAUNCH_TARGET:
			_HandleLaunchTarget(message);
			break;
		case B_LAUNCH_JOB:
			_HandleLaunchJob(message);
			break;
		case B_ENABLE_LAUNCH_JOB:
			_HandleEnableLaunchJob(message);
			break;
		case B_STOP_LAUNCH_JOB:
			_HandleStopLaunchJob(message);
			break;

		case B_LAUNCH_SESSION:
			_HandleLaunchSession(message);
			break;
		case B_REGISTER_SESSION_DAEMON:
			_HandleRegisterSessionDaemon(message);
			break;

		case B_REGISTER_LAUNCH_EVENT:
			_HandleRegisterLaunchEvent(message);
			break;
		case B_UNREGISTER_LAUNCH_EVENT:
			_HandleUnregisterLaunchEvent(message);
			break;
		case B_NOTIFY_LAUNCH_EVENT:
			_HandleNotifyLaunchEvent(message);
			break;
		case B_RESET_STICKY_LAUNCH_EVENT:
			_HandleResetStickyLaunchEvent(message);
			break;

		case B_GET_LAUNCH_TARGETS:
			_HandleGetLaunchTargets(message);
			break;
		case B_GET_LAUNCH_TARGET_INFO:
			_HandleGetLaunchTargetInfo(message);
			break;
		case B_GET_LAUNCH_JOBS:
			_HandleGetLaunchJobs(message);
			break;
		case B_GET_LAUNCH_JOB_INFO:
			_HandleGetLaunchJobInfo(message);
			break;

		case kMsgEventTriggered:
		{
			// An internal event has been triggered.
			// Check if its job can be launched now.
			const char* name = message->GetString("owner");
			if (name == NULL)
				break;

			Job* job = FindJob(name);
			if (job != NULL) {
				_LaunchJob(job);
				break;
			}

			Target* target = FindTarget(name);
			if (target != NULL) {
				_LaunchJobs(target);
				break;
			}
			break;
		}

		default:
			BServer::MessageReceived(message);
			break;
	}
}