// File: /workspace/github_cpp_makefile_star2_O3/davmac314[P]dinit/src/includes/dinit-util.h
// Function: open_with_dir(char const*, char const*, int)
inline std::pair<int,int> open_with_dir(const char *dirname, const char *basename,
        int resolve_fd = AT_FDCWD) noexcept
{
    // For a file /x/y/z, if the final component 'z' is a link to /a/b/c, then the real parent
    // directory is /a/b (not /x/y).

    // This vector is used as backing for the next path if we need to "recurse" (i.e. if we need
    // to manually follow a symlink).
    std::vector<char> path_vec;

    // Whether to close resolve_fd after use (initially false because it is supplied by caller,
    // and we don't want to close the caller's fd):
    bool close_resolve_fd = false;
    bool close_parent_dir_fd;

    long link_resolve_times = sysconf(_SC_SYMLOOP_MAX);

    // strip the basename and open as a directory
    #ifdef O_SEARCH
        constexpr int dir_search_flag = O_SEARCH;
    #else
        // O_SEARCH is not available on Linux
        constexpr int dir_search_flag = O_PATH;
    #endif

    begin:

    int parent_dir_fd;
    if (*dirname == '\0') {
        parent_dir_fd = resolve_fd;
        close_parent_dir_fd = close_resolve_fd;
    }
    else {
        parent_dir_fd = bp_sys::openat(resolve_fd, dirname, dir_search_flag | O_DIRECTORY);
        if (close_resolve_fd) bp_sys::close(resolve_fd);
        if (parent_dir_fd == -1) {
            return {-1, errno};
        }
        close_parent_dir_fd = true;
    }

    // open the final file (basename) without following symlinks
    int file_fd = bp_sys::openat(parent_dir_fd, basename, O_RDONLY | O_NOFOLLOW);
    if (file_fd == -1) {
        if (errno == ELOOP) {
            // It's a symlink
            if (link_resolve_times == 0) {
                // We've tried to resolve as many as the system normally would, so give up.
                if (close_parent_dir_fd) bp_sys::close(parent_dir_fd);
                return {-1, ELOOP};
            }

            link_resolve_times--;

            // read the next path
            auto link_path_r = readlink_at_str(parent_dir_fd, basename);
            if (!link_path_r.first) {
                // If EINVAL, it's supposedly not a symbolic link. Maybe it changed out from
                // underneath us. The risk of handling this by looping back and trying as a file
                // again seems greater than the risk that this will actually happen, so let's not
                // worry about it, and just error out now:
                if (close_parent_dir_fd) bp_sys::close(parent_dir_fd);
                return {-1, errno};
            }

            // Ok, we successfully read the link target. We need to extract the parent directory
            // name and base name, and then we'll jump back to 'begin' to iterate:
            path_vec = std::move(link_path_r.second);
            char *path = path_vec.data();
            dirname = path;
            basename = base_name(dirname);
            if (basename == dirname) {
                dirname = "";
            }
            else if (*basename == '\0') {
                if (close_parent_dir_fd) bp_sys::close(parent_dir_fd);
                return {-1, ENOENT};
            }
            else {
                string_view path_ish {path, (size_t)(basename - path)};
                string_view parent_path_v = parent_path(path_ish);
                if (parent_path_v.length() == 1) {
                    // Parent path must be '/'. Inserting nul might overwrite base name string,
                    // so we need a separate string:
                    dirname = "/";
                }
                else if (parent_path_v.empty()) {
                    dirname = "";
                }
                else {
                    path[parent_path_v.length()] = '\0';
                }
            }

            resolve_fd = parent_dir_fd;
            close_resolve_fd = true;
            goto begin;
        }

        // Other errors: bail out
        if (close_parent_dir_fd) bp_sys::close(parent_dir_fd);
        return {-1, errno};
    }

    return {parent_dir_fd, file_fd};
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %edx, 0x4(%rsp)
movq %rsi, %r13
movq %rdi, %r12
movl $0xad, %edi
callq 0x4210
movq %rax, 0x30(%rsp)
movq $0x0, 0x10(%rsp)
movq $0x0, 0x8(%rsp)
movq $0x0, 0x20(%rsp)
cmpb $0x0, (%r12)
je 0xfcfd
movl 0x4(%rsp), %edi
movq %r12, %rbx
movq %r12, %rsi
movl $0x210000, %edx         # imm = 0x210000
xorl %eax, %eax
callq 0x4530
movl %eax, %r14d
testb $0x1, 0x20(%rsp)
je 0xfcee
movl 0x4(%rsp), %edi
callq 0x4560
cmpl $-0x1, %r14d
je 0xff93
movb $0x1, %r12b
jmp 0xfd0d
movq %r12, %rbx
movl 0x4(%rsp), %r14d
movq 0x20(%rsp), %rax
movl %eax, %r12d
movl %r14d, %edi
movq %r13, %rsi
movl $0x20000, %edx          # imm = 0x20000
xorl %eax, %eax
callq 0x4530
cmpl $-0x1, %eax
jne 0xff8b
callq 0x4040
movq %rax, %rbp
movl (%rax), %r15d
cmpl $0x28, %r15d
jne 0xff43
movq 0x30(%rsp), %rax
subq $0x1, %rax
jb 0xff61
movq %rax, 0x30(%rsp)
leaq 0x48(%rsp), %rdi
movl %r14d, %esi
movq %r13, %rdx
callq 0x10733
cmpb $0x0, 0x48(%rsp)
je 0xfe2e
movq 0x50(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x60(%rsp), %r15
leaq 0x50(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0xfda5
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x42f0
movq 0x18(%rsp), %r13
leaq 0x1(%r13), %rax
movzbl -0x1(%rax), %ecx
cmpl $0x2f, %ecx
je 0xfdbd
testl %ecx, %ecx
jne 0xfdc0
jmp 0xfdc5
movq %rax, %r13
incq %rax
jmp 0xfdae
movq %r13, %rax
movq 0x18(%rsp), %rcx
subq %rcx, %rax
je 0xfe4d
cmpb $0x0, (%r13)
je 0xfe72
movq 0x18(%rsp), %rcx
movq %rcx, 0x38(%rsp)
movq %rax, 0x40(%rsp)
leaq 0x38(%rsp), %rdi
movl $0x2f, %esi
callq 0x11d78
testq %rax, %rax
je 0xfeb2
cmpq $-0x1, %rax
jne 0xfe9b
movb $0x1, %al
movq %rax, 0x20(%rsp)
movq %r15, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movb $0x1, %bpl
movl %r14d, 0x4(%rsp)
jmp 0xfe69
testb $0x1, %r12b
je 0xfe3c
movl %r14d, %edi
callq 0x4560
movl (%rbp), %eax
movl %eax, 0x2c(%rsp)
xorl %ebp, %ebp
movq %rbx, %r12
jmp 0xfed7
movb $0x1, %al
movq %rax, 0x20(%rsp)
movq %r15, 0x10(%rsp)
movq %rcx, 0x8(%rsp)
movb $0x1, %bpl
movl %r14d, 0x4(%rsp)
movq %rcx, %r13
leaq 0x6c91(%rip), %r12      # 0x16b01
jmp 0xfed7
movl $0x2, 0x2c(%rsp)
testb $0x1, %r12b
je 0xfe88
movl %r14d, %edi
callq 0x4560
xorl %ebp, %ebp
movq %r15, 0x10(%rsp)
movq 0x18(%rsp), %r12
movq %r12, 0x8(%rsp)
jmp 0xfed7
movq 0x38(%rsp), %rcx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
addl %eax, %edx
cmpb $0x2f, (%rcx,%rdx)
jne 0xfefc
decq %rax
jne 0xfea0
movb $0x1, %al
movq %rax, 0x20(%rsp)
movq %r15, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movb $0x1, %bpl
movl %r14d, 0x4(%rsp)
leaq 0x6da8(%rip), %r12      # 0x16c7f
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0xfeee
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x42f0
testb %bpl, %bpl
jne 0xfcbe
jmp 0xff81
movq 0x40(%rsp), %rcx
cmpq %rax, %rcx
cmovbq %rcx, %rax
testq %rax, %rax
je 0xfe0e
movb $0x1, %cl
movq %rcx, 0x20(%rsp)
cmpq $0x1, %rax
je 0xfeb9
movq 0x18(%rsp), %r12
movb $0x0, (%r12,%rax)
movb $0x1, %al
movq %rax, 0x20(%rsp)
movq %r15, 0x10(%rsp)
movq %r12, 0x8(%rsp)
movb $0x1, %bpl
movl %r14d, 0x4(%rsp)
jmp 0xfed7
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testb $0x1, %r12b
je 0xffa0
movl %r14d, %edi
callq 0x4560
movq 0x8(%rsp), %rdi
movl (%rbp), %r15d
jmp 0xffa5
movl $0x28, %r15d
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testb $0x1, %r12b
je 0xffa0
movl %r14d, %edi
callq 0x4560
movq 0x8(%rsp), %rdi
jmp 0xffa5
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movl 0x2c(%rsp), %eax
movl %r14d, %ebx
movl %eax, %r15d
jmp 0xffa0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
callq 0x4040
movl (%rax), %r15d
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0xffb7
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x42f0
shlq $0x20, %r15
orq %rbx, %r15
movq %r15, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xffd2
movq %rax, %rdi
callq 0xe590