1// Copyright (c) 2012 The Chromium 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 CHROMEOS_PROCESS_PROXY_PROCESS_PROXY_H_
6#define CHROMEOS_PROCESS_PROXY_PROCESS_PROXY_H_
7
8#include <fcntl.h>
9#include <signal.h>
10
11#include <cstdio>
12#include <string>
13
14#include "base/memory/ref_counted.h"
15#include "chromeos/process_proxy/process_output_watcher.h"
16
17namespace base {
18class TaskRunner;
19class Thread;
20}  // namespace base
21
22namespace chromeos {
23
24// Proxy to a single ChromeOS process.
25// This is refcounted. Note that output watcher, when it gets triggered owns a
26// a callback with ref to this, so in order for this to be freed, the watcher
27// must be destroyed. This is done in Close.
28class ProcessProxy : public base::RefCountedThreadSafe<ProcessProxy> {
29 public:
30  ProcessProxy();
31
32  // Opens a process using command |command|. |pid| is set to new process' pid.
33  bool Open(const std::string& command, pid_t* pid);
34
35  // Triggers watcher object on |watch_thread|. |watch_thread| gets blocked, so
36  // it should not be one of commonly used threads. It should be thread created
37  // specifically for running process output watcher.
38  bool StartWatchingOnThread(base::Thread* watch_thread,
39                             const ProcessOutputCallback& callback);
40
41  // Sends some data to the process.
42  bool Write(const std::string& text);
43
44  // Closes the process.
45  // Must be called if we want this to be eventually deleted.
46  void Close();
47
48  // Notifies underlaying process of terminal size change.
49  bool OnTerminalResize(int width, int height);
50
51 private:
52  friend class base::RefCountedThreadSafe<ProcessProxy>;
53  // We want this be used as ref counted object only.
54  ~ProcessProxy();
55
56  // Create master and slave end of pseudo terminal that will be used to
57  // communicate with process.
58  // pt_pair[0] -> master, pt_pair[1] -> slave.
59  // pt_pair must be allocated (to size at least 2).
60  bool CreatePseudoTerminalPair(int *pt_pair);
61
62  bool LaunchProcess(const std::string& command, int slave_fd, pid_t* pid);
63
64  // Gets called by output watcher when the process writes something to its
65  // output streams.
66  void OnProcessOutput(ProcessOutputType type, const std::string& output);
67  void CallOnProcessOutputCallback(ProcessOutputType type,
68                                   const std::string& output);
69
70  bool StopWatching();
71
72  // Methods for cleaning up pipes.
73  void CloseAllFdPairs();
74  // Expects array of 2 file descripters.
75  void CloseFdPair(int* pipe);
76  // Expects pointer to single file descriptor.
77  void CloseFd(int* fd);
78  void ClearAllFdPairs();
79  // Expects array of 2 file descripters.
80  void ClearFdPair(int* pipe);
81
82  bool process_launched_;
83  pid_t pid_;
84
85  bool callback_set_;
86  ProcessOutputCallback callback_;
87  scoped_refptr<base::TaskRunner> callback_runner_;
88
89  bool watcher_started_;
90
91  int pt_pair_[2];
92  int shutdown_pipe_[2];
93
94  DISALLOW_COPY_AND_ASSIGN(ProcessProxy);
95};
96
97}  // namespace chromeos
98
99#endif  // CHROMEOS_PROCESS_PROXY_PROCESS_PROXY_H_
100