• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2013 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/external_task.h"
18 
19 #include <base/bind.h>
20 #include <base/bind_helpers.h>
21 
22 #include "shill/error.h"
23 #include "shill/event_dispatcher.h"
24 #include "shill/process_manager.h"
25 
26 namespace shill {
27 
28 using base::FilePath;
29 using std::map;
30 using std::string;
31 using std::vector;
32 
ExternalTask(ControlInterface * control,ProcessManager * process_manager,const base::WeakPtr<RPCTaskDelegate> & task_delegate,const base::Callback<void (pid_t,int)> & death_callback)33 ExternalTask::ExternalTask(
34     ControlInterface* control,
35     ProcessManager* process_manager,
36     const base::WeakPtr<RPCTaskDelegate>& task_delegate,
37     const base::Callback<void(pid_t, int)>& death_callback)
38     : control_(control),
39       process_manager_(process_manager),
40       task_delegate_(task_delegate),
41       death_callback_(death_callback),
42       pid_(0) {
43   CHECK(task_delegate_);
44 }
45 
~ExternalTask()46 ExternalTask::~ExternalTask() {
47   ExternalTask::Stop();
48 }
49 
DestroyLater(EventDispatcher * dispatcher)50 void ExternalTask::DestroyLater(EventDispatcher* dispatcher) {
51   // Passes ownership of |this| to Destroy.
52   dispatcher->PostTask(base::Bind(&Destroy, this));
53 }
54 
Start(const FilePath & program,const vector<string> & arguments,const map<string,string> & environment,bool terminate_with_parent,Error * error)55 bool ExternalTask::Start(const FilePath& program,
56                          const vector<string>& arguments,
57                          const map<string, string>& environment,
58                          bool terminate_with_parent,
59                          Error* error) {
60   CHECK(!pid_);
61   CHECK(!rpc_task_);
62 
63   // Setup full environment variables.
64   std::unique_ptr<RPCTask> local_rpc_task(new RPCTask(control_, this));
65   map<string, string> env = local_rpc_task->GetEnvironment();
66   env.insert(environment.begin(), environment.end());
67 
68   pid_t pid =
69       process_manager_->StartProcess(FROM_HERE,
70                                      program,
71                                      arguments,
72                                      env,
73                                      terminate_with_parent,
74                                      base::Bind(&ExternalTask::OnTaskDied,
75                                                 base::Unretained(this)));
76 
77   if (pid < 0) {
78     Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
79                           string("Unable to spawn: ") +
80                           program.value().c_str());
81     return false;
82   }
83   pid_ = pid;
84   rpc_task_.reset(local_rpc_task.release());
85   return true;
86 }
87 
Stop()88 void ExternalTask::Stop() {
89   if (pid_) {
90     process_manager_->StopProcess(pid_);
91     pid_ = 0;
92   }
93   rpc_task_.reset();
94 }
95 
GetLogin(string * user,string * password)96 void ExternalTask::GetLogin(string* user, string* password) {
97   return task_delegate_->GetLogin(user, password);
98 }
99 
Notify(const string & event,const map<string,string> & details)100 void ExternalTask::Notify(const string& event,
101                           const map<string, string>& details) {
102   return task_delegate_->Notify(event, details);
103 }
104 
OnTaskDied(int exit_status)105 void ExternalTask::OnTaskDied(int exit_status) {
106   CHECK(pid_);
107   LOG(INFO) << __func__ << "(" << pid_ << ", "
108             << exit_status << ")";
109   death_callback_.Run(pid_, exit_status);
110   pid_ = 0;
111   rpc_task_.reset();
112 }
113 
114 // static
Destroy(ExternalTask * task)115 void ExternalTask::Destroy(ExternalTask* task) {
116   delete task;
117 }
118 
119 }  // namespace shill
120