// File: halfflat[P]tinyopt/test/googletest/googletest/src/gtest-port.cc
// Function: testing::internal::CapturedStream::CapturedStream(int)
explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
#ifdef GTEST_OS_WINDOWS
    char temp_dir_path[MAX_PATH + 1] = {'\0'};   // NOLINT
    char temp_file_path[MAX_PATH + 1] = {'\0'};  // NOLINT

    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
    const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir",
                                            0,  // Generate unique file name.
                                            temp_file_path);
    GTEST_CHECK_(success != 0)
        << "Unable to create a temporary file in " << temp_dir_path;
    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
    GTEST_CHECK_(captured_fd != -1)
        << "Unable to open temporary file " << temp_file_path;
    filename_ = temp_file_path;
#else
    // There's no guarantee that a test has write access to the current
    // directory, so we create the temporary file in a temporary directory.
    std::string name_template;

#ifdef GTEST_OS_LINUX_ANDROID
    // Note: Android applications are expected to call the framework's
    // Context.getExternalStorageDirectory() method through JNI to get
    // the location of the world-writable SD Card directory. However,
    // this requires a Context handle, which cannot be retrieved
    // globally from native code. Doing so also precludes running the
    // code as part of a regular standalone executable, which doesn't
    // run in a Dalvik process (e.g. when running it through 'adb shell').
    //
    // The location /data/local/tmp is directly accessible from native code.
    // '/sdcard' and other variants cannot be relied on, as they are not
    // guaranteed to be mounted, or may have a delay in mounting.
    //
    // However, prefer using the TMPDIR environment variable if set, as newer
    // devices may have /data/local/tmp read-only.
    name_template = TempDir();
    if (!EndsWithPathSeparator(name_template))
      name_template.push_back(GTEST_PATH_SEP_[0]);

#elif defined(GTEST_OS_IOS)
    char user_temp_dir[PATH_MAX + 1];

    // Documented alternative to NSTemporaryDirectory() (for obtaining creating
    // a temporary directory) at
    // https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10
    //
    // _CS_DARWIN_USER_TEMP_DIR (as well as _CS_DARWIN_USER_CACHE_DIR) is not
    // documented in the confstr() man page at
    // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/confstr.3.html#//apple_ref/doc/man/3/confstr
    // but are still available, according to the WebKit patches at
    // https://trac.webkit.org/changeset/262004/webkit
    // https://trac.webkit.org/changeset/263705/webkit
    //
    // The confstr() implementation falls back to getenv("TMPDIR"). See
    // https://opensource.apple.com/source/Libc/Libc-1439.100.3/gen/confstr.c.auto.html
    ::confstr(_CS_DARWIN_USER_TEMP_DIR, user_temp_dir, sizeof(user_temp_dir));

    name_template = user_temp_dir;
    if (!EndsWithPathSeparator(name_template))
      name_template.push_back(GTEST_PATH_SEP_[0]);
#else
    name_template = "/tmp/";
#endif
    name_template.append("gtest_captured_stream.XXXXXX");

    // mkstemp() modifies the string bytes in place, and does not go beyond the
    // string's length. This results in well-defined behavior in C++17.
    //
    // The const_cast is needed below C++17. The constraints on std::string
    // implementations in C++11 and above make assumption behind the const_cast
    // fairly safe.
    const int captured_fd = ::mkstemp(const_cast<char*>(name_template.data()));
    if (captured_fd == -1) {
      GTEST_LOG_(WARNING)
          << "Failed to create tmp file " << name_template
          << " for test; does the test have access to the /tmp directory?";
    }
    filename_ = std::move(name_template);
#endif  // GTEST_OS_WINDOWS
    fflush(nullptr);
    dup2(captured_fd, fd_);
    close(captured_fd);
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movl -0xc(%rbp), %ecx
movl %ecx, (%rax)
movl -0xc(%rbp), %edi
callq 0x10c90
movq -0x60(%rbp), %rdi
movl %eax, 0x4(%rdi)
addq $0x8, %rdi
movq %rdi, -0x58(%rbp)
callq 0x10b60
leaq -0x30(%rbp), %rdi
movq %rdi, -0x50(%rbp)
callq 0x10b60
movq -0x50(%rbp), %rdi
leaq 0x2193a(%rip), %rsi     # 0xcf4ad
callq 0x10b40
jmp 0xadb7a
leaq 0x21ca7(%rip), %rsi     # 0xcf828
leaq -0x30(%rbp), %rdi
callq 0x10f20
jmp 0xadb8c
leaq -0x30(%rbp), %rdi
callq 0x10440
movq %rax, %rdi
callq 0x10200
movl %eax, -0x64(%rbp)
jmp 0xadba2
movl -0x64(%rbp), %eax
movl %eax, -0x40(%rbp)
cmpl $-0x1, -0x40(%rbp)
jne 0xadc41
leaq 0x201bf(%rip), %rdx     # 0xcdd78
leaq -0x44(%rbp), %rdi
movl $0x1, %esi
movl $0x469, %ecx            # imm = 0x469
callq 0x7d880
jmp 0xadbce
leaq -0x44(%rbp), %rdi
callq 0x1f280
movq %rax, %rdi
leaq 0x21c64(%rip), %rsi     # 0xcf845
callq 0x10720
movq %rax, -0x70(%rbp)
jmp 0xadbec
movq -0x70(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x10680
movq %rax, -0x78(%rbp)
jmp 0xadbff
movq -0x78(%rbp), %rdi
leaq 0x21c56(%rip), %rsi     # 0xcf860
callq 0x10720
jmp 0xadc11
leaq -0x44(%rbp), %rdi
callq 0x7d9c0
jmp 0xadc41
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0xadc87
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x44(%rbp), %rdi
callq 0x7d9c0
jmp 0xadc87
movq -0x60(%rbp), %rdi
addq $0x8, %rdi
leaq -0x30(%rbp), %rsi
callq 0x109b0
xorl %eax, %eax
movl %eax, %edi
callq 0x10930
jmp 0xadc5d
movq -0x60(%rbp), %rax
movl -0x40(%rbp), %edi
movl (%rax), %esi
callq 0x106d0
movl -0x40(%rbp), %edi
callq 0x10f60
jmp 0xadc75
leaq -0x30(%rbp), %rdi
callq 0x10fc8
addq $0x80, %rsp
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x10fc8
movq -0x58(%rbp), %rdi
callq 0x10fc8
movq -0x38(%rbp), %rdi
callq 0x10e00
nopw %cs:(%rax,%rax)
nopl (%rax)