// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_ZYGOTE_ZYGOTE_LINUX_H_
#define CONTENT_ZYGOTE_ZYGOTE_LINUX_H_

#include <stddef.h>

#include <string>

#include "base/containers/small_map.h"
#include "base/files/scoped_file.h"
#include "base/memory/scoped_vector.h"
#include "base/posix/global_descriptors.h"
#include "base/process/kill.h"
#include "base/process/process.h"

namespace base {
class Pickle;
class PickleIterator;
}

namespace content {

class ZygoteForkDelegate;

// This is the object which implements the zygote. The ZygoteMain function,
// which is called from ChromeMain, simply constructs one of these objects and
// runs it.
class Zygote {
 public:
  Zygote(int sandbox_flags, ScopedVector<ZygoteForkDelegate> helpers,
         const std::vector<base::ProcessHandle>& extra_children,
         const std::vector<int>& extra_fds);
  ~Zygote();

  bool ProcessRequests();

 private:
  struct ZygoteProcessInfo {
    // Pid from inside the Zygote's PID namespace.
    base::ProcessHandle internal_pid;
    // Keeps track of which fork delegate helper the process was started from.
    ZygoteForkDelegate* started_from_helper;
  };
  typedef base::SmallMap< std::map<base::ProcessHandle, ZygoteProcessInfo> >
      ZygoteProcessMap;

  // Retrieve a ZygoteProcessInfo from the process_info_map_.
  // Returns true and write to process_info if |pid| can be found, return
  // false otherwise.
  bool GetProcessInfo(base::ProcessHandle pid,
                      ZygoteProcessInfo* process_info);

  // Returns true if the SUID sandbox is active.
  bool UsingSUIDSandbox() const;
  // Returns true if the NS sandbox is active.
  bool UsingNSSandbox() const;

  // ---------------------------------------------------------------------------
  // Requests from the browser...

  // Read and process a request from the browser. Returns true if we are in a
  // new process and thus need to unwind back into ChromeMain.
  bool HandleRequestFromBrowser(int fd);

  void HandleReapRequest(int fd, base::PickleIterator iter);

  // Get the termination status of |real_pid|. |real_pid| is the PID as it
  // appears outside of the sandbox.
  // Return true if it managed to get the termination status and return the
  // status in |status| and the exit code in |exit_code|.
  bool GetTerminationStatus(base::ProcessHandle real_pid, bool known_dead,
                            base::TerminationStatus* status,
                            int* exit_code);

  void HandleGetTerminationStatus(int fd,
                                  base::PickleIterator iter);

  // This is equivalent to fork(), except that, when using the SUID sandbox, it
  // returns the real PID of the child process as it appears outside the
  // sandbox, rather than returning the PID inside the sandbox.  The child's
  // real PID is determined by having it call content::SendZygoteChildPing(int)
  // using the |pid_oracle| descriptor.
  // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|,
  // and |uma_boundary_value| may be set if the helper wants to make a UMA
  // report via UMA_HISTOGRAM_ENUMERATION.
  int ForkWithRealPid(const std::string& process_type,
                      const base::GlobalDescriptors::Mapping& fd_mapping,
                      const std::string& channel_id,
                      base::ScopedFD pid_oracle,
                      std::string* uma_name,
                      int* uma_sample,
                      int* uma_boundary_value);

  // Unpacks process type and arguments from |iter| and forks a new process.
  // Returns -1 on error, otherwise returns twice, returning 0 to the child
  // process and the child process ID to the parent process, like fork().
  base::ProcessId ReadArgsAndFork(base::PickleIterator iter,
                                  ScopedVector<base::ScopedFD> fds,
                                  std::string* uma_name,
                                  int* uma_sample,
                                  int* uma_boundary_value);

  // Handle a 'fork' request from the browser: this means that the browser
  // wishes to start a new renderer. Returns true if we are in a new process,
  // otherwise writes the child_pid back to the browser via |fd|. Writes a
  // child_pid of -1 on error.
  bool HandleForkRequest(int fd,
                         base::PickleIterator iter,
                         ScopedVector<base::ScopedFD> fds);

  bool HandleGetSandboxStatus(int fd,
                              base::PickleIterator iter);

  // The Zygote needs to keep some information about each process. Most
  // notably what the PID of the process is inside the PID namespace of
  // the Zygote and whether or not a process was started by the
  // ZygoteForkDelegate helper.
  ZygoteProcessMap process_info_map_;

  const int sandbox_flags_;
  ScopedVector<ZygoteForkDelegate> helpers_;

  // Count of how many fork delegates for which we've invoked InitialUMA().
  size_t initial_uma_index_;

  // This vector contains the PIDs of any child processes which have been
  // created prior to the construction of the Zygote object, and must be reaped
  // before the Zygote exits. The Zygote will perform a blocking wait on these
  // children, so they must be guaranteed to be exiting by the time the Zygote
  // exits.
  std::vector<base::ProcessHandle> extra_children_;

  // This vector contains the FDs that must be closed before reaping the extra
  // children.
  std::vector<int> extra_fds_;
};

}  // namespace content

#endif  // CONTENT_ZYGOTE_ZYGOTE_LINUX_H_
