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

#include "brillo/minijail/minijail.h"

#include <sys/types.h>
#include <sys/wait.h>

using std::vector;

namespace brillo {

static base::LazyInstance<Minijail>::DestructorAtExit g_minijail =
    LAZY_INSTANCE_INITIALIZER;

Minijail::Minijail() {}

Minijail::~Minijail() {}

// static
Minijail* Minijail::GetInstance() {
  return g_minijail.Pointer();
}

struct minijail* Minijail::New() {
  return minijail_new();
}

void Minijail::Destroy(struct minijail* jail) {
  minijail_destroy(jail);
}

void Minijail::DropRoot(struct minijail* jail, uid_t uid, gid_t gid) {
  minijail_change_uid(jail, uid);
  minijail_change_gid(jail, gid);
}

bool Minijail::DropRoot(struct minijail* jail,
                        const char* user,
                        const char* group) {
  // |user| and |group| are copied so the only reason either of these
  // calls can fail is ENOMEM.
  return !minijail_change_user(jail, user) &&
         !minijail_change_group(jail, group);
}

void Minijail::EnterNewPidNamespace(struct minijail* jail) {
  minijail_namespace_pids(jail);
}

void Minijail::MountTmp(struct minijail* jail) {
  minijail_mount_tmp(jail);
}

void Minijail::UseSeccompFilter(struct minijail* jail, const char* path) {
  minijail_no_new_privs(jail);
  minijail_use_seccomp_filter(jail);
  minijail_parse_seccomp_filters(jail, path);
}

void Minijail::UseCapabilities(struct minijail* jail, uint64_t capmask) {
  minijail_use_caps(jail, capmask);
}

void Minijail::ResetSignalMask(struct minijail* jail) {
  minijail_reset_signal_mask(jail);
}

void Minijail::CloseOpenFds(struct minijail* jail) {
  minijail_close_open_fds(jail);
}

void Minijail::PreserveFd(struct minijail* jail, int parent_fd, int child_fd) {
  minijail_preserve_fd(jail, parent_fd, child_fd);
}

void Minijail::Enter(struct minijail* jail) {
  minijail_enter(jail);
}

bool Minijail::Run(struct minijail* jail, vector<char*> args, pid_t* pid) {
  return minijail_run_pid(jail, args[0], args.data(), pid) == 0;
}

bool Minijail::RunSync(struct minijail* jail, vector<char*> args, int* status) {
  pid_t pid;
  if (Run(jail, args, &pid) && waitpid(pid, status, 0) == pid) {
    return true;
  }

  return false;
}

bool Minijail::RunPipe(struct minijail* jail,
                       vector<char*> args,
                       pid_t* pid,
                       int* stdin) {
#if defined(__ANDROID__)
  return minijail_run_pid_pipes_no_preload(jail, args[0], args.data(), pid,
                                           stdin, NULL, NULL) == 0;
#else
  return minijail_run_pid_pipes(jail, args[0], args.data(), pid, stdin, NULL,
                                NULL) == 0;
#endif  // __ANDROID__
}

bool Minijail::RunPipes(struct minijail* jail,
                        vector<char*> args,
                        pid_t* pid,
                        int* stdin,
                        int* stdout,
                        int* stderr) {
#if defined(__ANDROID__)
  return minijail_run_pid_pipes_no_preload(jail, args[0], args.data(), pid,
                                           stdin, stdout, stderr) == 0;
#else
  return minijail_run_pid_pipes(jail, args[0], args.data(), pid, stdin, stdout,
                                stderr) == 0;
#endif  // __ANDROID__
}

bool Minijail::RunEnvPipes(struct minijail* jail,
                           vector<char*> args,
                           vector<char*> env,
                           pid_t* pid,
                           int* stdin,
                           int* stdout,
                           int* stderr) {
#if defined(__ANDROID__)
  return minijail_run_env_pid_pipes_no_preload(jail, args[0], args.data(),
                                               env.data(), pid, stdin, stdout,
                                               stderr) == 0;
#else
  return minijail_run_env_pid_pipes(jail, args[0], args.data(), env.data(), pid,
                                    stdin, stdout, stderr) == 0;
#endif  // __ANDROID__
}

bool Minijail::RunAndDestroy(struct minijail* jail,
                             vector<char*> args,
                             pid_t* pid) {
  bool res = Run(jail, args, pid);
  Destroy(jail);
  return res;
}

bool Minijail::RunSyncAndDestroy(struct minijail* jail,
                                 vector<char*> args,
                                 int* status) {
  bool res = RunSync(jail, args, status);
  Destroy(jail);
  return res;
}

bool Minijail::RunPipeAndDestroy(struct minijail* jail,
                                 vector<char*> args,
                                 pid_t* pid,
                                 int* stdin) {
  bool res = RunPipe(jail, args, pid, stdin);
  Destroy(jail);
  return res;
}

bool Minijail::RunPipesAndDestroy(struct minijail* jail,
                                  vector<char*> args,
                                  pid_t* pid,
                                  int* stdin,
                                  int* stdout,
                                  int* stderr) {
  bool res = RunPipes(jail, args, pid, stdin, stdout, stderr);
  Destroy(jail);
  return res;
}

bool Minijail::RunEnvPipesAndDestroy(struct minijail* jail,
                                     vector<char*> args,
                                     vector<char*> env,
                                     pid_t* pid,
                                     int* stdin,
                                     int* stdout,
                                     int* stderr) {
  bool res = RunEnvPipes(jail, args, env, pid, stdin, stdout, stderr);
  Destroy(jail);
  return res;
}

}  // namespace brillo
