/*! Checks recursively if the requirements of the specified job can be launched, if they are not running already. Calling this method will not trigger a demand for the requirements. */ bool LaunchDaemon::_CanLaunchJobRequirements(Job* job, uint32 options) { int32 count = job->Requirements().CountStrings(); for (int32 index = 0; index < count; index++) { Job* requirement = FindJob(job->Requirements().StringAt(index)); if (requirement != NULL && !requirement->IsRunning() && !requirement->IsLaunching() && (!_CanLaunchJob(requirement, options, true) || _CanLaunchJobRequirements(requirement, options))) { requirement->AddPending(job->Name()); return false; } } return true; }
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); }