chromium/third_party/crashpad/crashpad/util/posix/spawn_subprocess.cc

// Copyright 2017 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/posix/spawn_subprocess.h"

#include <errno.h>
#include <spawn.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include "base/check.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "util/posix/close_multiple.h"

#if BUILDFLAG(IS_ANDROID)
#include <android/api-level.h>
#endif

// crbug.com/1474421: Used to debug clusterfuzz in_process_fuzzer failures.
// Remove this once the bug is fixed.
#if __has_include("chrome/test/fuzzing/in_process_fuzzer_buildflags.h")
#include "chrome/test/fuzzing/in_process_fuzzer_buildflags.h"  // nogncheck
#define DEBUG_CLUSTERFUZZ_FAILURE
#else
#define DEBUG_CLUSTERFUZZ_FAILURE
#endif

extern char** environ;

namespace crashpad {

namespace {

#if BUILDFLAG(IS_APPLE)

class PosixSpawnAttr {
 public:
  PosixSpawnAttr() {
    PCHECK((errno = posix_spawnattr_init(&attr_)) == 0)
        << "posix_spawnattr_init";
  }

  PosixSpawnAttr(const PosixSpawnAttr&) = delete;
  PosixSpawnAttr& operator=(const PosixSpawnAttr&) = delete;

  ~PosixSpawnAttr() {
    PCHECK((errno = posix_spawnattr_destroy(&attr_)) == 0)
        << "posix_spawnattr_destroy";
  }

  void SetFlags(short flags) {
    PCHECK((errno = posix_spawnattr_setflags(&attr_, flags)) == 0)
        << "posix_spawnattr_setflags";
  }

  const posix_spawnattr_t* Get() const { return &attr_; }

 private:
  posix_spawnattr_t attr_;
};

class PosixSpawnFileActions {
 public:
  PosixSpawnFileActions() {
    PCHECK((errno = posix_spawn_file_actions_init(&file_actions_)) == 0)
        << "posix_spawn_file_actions_init";
  }

  PosixSpawnFileActions(const PosixSpawnFileActions&) = delete;
  PosixSpawnFileActions& operator=(const PosixSpawnFileActions&) = delete;

  ~PosixSpawnFileActions() {
    PCHECK((errno = posix_spawn_file_actions_destroy(&file_actions_)) == 0)
        << "posix_spawn_file_actions_destroy";
  }

  void AddInheritedFileDescriptor(int fd) {
    PCHECK((errno = posix_spawn_file_actions_addinherit_np(&file_actions_,
                                                           fd)) == 0)
        << "posix_spawn_file_actions_addinherit_np";
  }

  const posix_spawn_file_actions_t* Get() const { return &file_actions_; }

 private:
  posix_spawn_file_actions_t file_actions_;
};

#endif

}  // namespace

bool SpawnSubprocess(const std::vector<std::string>& argv,
                     const std::vector<std::string>* envp,
                     int preserve_fd,
                     bool use_path,
                     void (*child_function)()) {}

}  // namespace crashpad