示例#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;
}