blob: e9c5126d94cad7feb292e9c87559c50b53146781 [file] [log] [blame]
mukesh agrawalae30e9e2013-05-28 14:09:16 -07001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_EXTERNAL_TASK_H_
6#define SHILL_EXTERNAL_TASK_H_
7
8#include <sys/types.h>
9
10#include <map>
11#include <string>
12#include <vector>
13
14#include <base/callback.h>
Ben Chana0ddf462014-02-06 11:32:42 -080015#include <base/files/file_path.h>
mukesh agrawalae30e9e2013-05-28 14:09:16 -070016#include <base/memory/scoped_ptr.h>
17#include <base/memory/weak_ptr.h>
18#include <gtest/gtest_prod.h> // for FRIEND_TEST
19
20#include "shill/glib.h"
21#include "shill/rpc_task.h"
22
23namespace shill {
24
25class ControlInterface;
26class Error;
mukesh agrawal9da07772013-05-15 14:15:17 -070027class EventDispatcher;
mukesh agrawalae30e9e2013-05-28 14:09:16 -070028class ProcessKiller;
29
30class ExternalTask : public RPCTaskDelegate {
31 public:
32 ExternalTask(ControlInterface *control,
33 GLib *glib,
34 const base::WeakPtr<RPCTaskDelegate> &task_delegate,
35 const base::Callback<void(pid_t, int)> &death_callback);
mukesh agrawal9da07772013-05-15 14:15:17 -070036 virtual ~ExternalTask(); // But consider DestroyLater...
37
38 // Schedule later deletion of the ExternalTask. Useful when in the
39 // middle of an ExternalTask callback. Note that the caller _must_
40 // release ownership of |this|. For example:
41 //
42 // class Foo : public SupportsWeakPtr<Foo>, public RPCTaskDelegate {
43 // public:
44 // Foo() {
45 // task_.reset(new ExternalTask(...));
46 // }
47 //
48 // void Notify(...) {
49 // task_.release()->DestroyLater(...); // Passes ownership.
50 // }
51 //
52 // private:
53 // scoped_ptr<ExternalTask> task_;
54 // }
55 void DestroyLater(EventDispatcher *dispatcher);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070056
57 // Forks off a process to run |program|, with the command-line
58 // arguments |arguments|, and the environment variables specified in
59 // |environment|.
60 //
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070061 // If |terminate_with_parent| is true, the child process will be
62 // configured to terminate itself if this process dies. Otherwise,
63 // the child process will retain its default behavior.
64 //
mukesh agrawalae30e9e2013-05-28 14:09:16 -070065 // On success, returns true, and leaves |error| unmodified.
66 // On failure, returns false, and sets |error|.
67 //
68 // |environment| SHOULD NOT contain kRPCTaskServiceVariable or
69 // kRPCTaskPathVariable, as that may prevent the child process
70 // from communicating back to the ExternalTask.
71 virtual bool Start(const base::FilePath &program,
72 const std::vector<std::string> &arguments,
73 const std::map<std::string, std::string> &environment,
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070074 bool terminate_with_parent,
mukesh agrawalae30e9e2013-05-28 14:09:16 -070075 Error *error);
76 virtual void Stop();
77
78 private:
79 friend class ExternalTaskTest;
80 FRIEND_TEST(ExternalTaskTest, Destructor);
81 FRIEND_TEST(ExternalTaskTest, GetLogin);
82 FRIEND_TEST(ExternalTaskTest, Notify);
83 FRIEND_TEST(ExternalTaskTest, OnTaskDied);
84 FRIEND_TEST(ExternalTaskTest, Start);
85 FRIEND_TEST(ExternalTaskTest, Stop);
86 FRIEND_TEST(ExternalTaskTest, StopNotStarted);
87
88 // Implements RPCTaskDelegate.
89 virtual void GetLogin(std::string *user, std::string *password) override;
90 virtual void Notify(
91 const std::string &event,
92 const std::map<std::string, std::string> &details) override;
93 // Called when the external process exits.
94 static void OnTaskDied(GPid pid, gint status, gpointer data);
95
mukesh agrawal9da07772013-05-15 14:15:17 -070096 static void Destroy(ExternalTask *task);
97
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070098 // This method is run in the child process (i.e. after fork(), but
99 // before exec()). It configures the child to receive a SIGTERM when
100 // the parent exits.
101 static void SetupTermination(gpointer glib_user_data);
102
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700103 ControlInterface *control_;
104 GLib *glib_;
105 ProcessKiller *process_killer_; // Field permits mocking.
106
107 scoped_ptr<RPCTask> rpc_task_;
108 base::WeakPtr<RPCTaskDelegate> task_delegate_;
109 base::Callback<void(pid_t, int)> death_callback_;
110
111 // The PID of the spawned process. May be 0 if no process has been
112 // spawned yet or the process has died.
113 pid_t pid_;
114
115 // Child exit watch callback source tag.
116 unsigned int child_watch_tag_;
117
118 DISALLOW_COPY_AND_ASSIGN(ExternalTask);
119};
120
121} // namespace shill
122
123#endif // SHILL_EXTERNAL_TASK_H_