// File: /workspace/github_cpp_makefile_star2_O2/davmac314[P]dinit/src/dinit.cc
// Function: open_control_socket(bool)
static bool open_control_socket(bool report_ro_failure) noexcept
{
    if (control_socket_open) {
        struct stat stat_buf;
        if (stat(control_socket_path, &stat_buf) != 0 && errno == ENOENT) {
            // Looks like our control socket has disappeared from the filesystem. Close our control
            // socket and re-create it:
            control_socket_io.deregister(event_loop);
            close(control_socket_io.get_watched_fd());
            control_socket_open = false; // now re-open below
        }
    }

    if (!control_socket_open) {
        const char * saddrname = control_socket_path;
        size_t saddrname_len = strlen(saddrname);
        uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + saddrname_len + 1;
        
        struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
        if (name == nullptr) {
            log(loglevel_t::ERROR, "Opening control socket: out of memory");
            return false;
        }

        name->sun_family = AF_UNIX;
        memcpy(name->sun_path, saddrname, saddrname_len + 1);

        int sockfd = dinit_socket(AF_UNIX, SOCK_STREAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
        if (sockfd == -1) {
            log(loglevel_t::ERROR, "Error creating control socket: ", strerror(errno));
            free(name);
            return false;
        }

        // Check if there is already an active control socket (from another instance).
        // Unfortunately, there's no way to check atomically if a socket file is stale. Still, we
        // will try to check, since the consequences of running a system dinit instance twice are
        // potentially severe.
        int connr = connect(sockfd, (struct sockaddr *) name, sockaddr_size);
        if (connr != -1 || errno == EAGAIN) {
            log(loglevel_t::ERROR, "Control socket is already active"
                    " (another instance already running?)");

            close(connr);
            close(sockfd);
            free(name);

            return false;
        }

        // Unlink any stale control socket file.
        //
        // In the worst case, this potentially removes a socket which was not active at the time
        // we checked (just above) but has since become active; there's just no good API to avoid
        // this (we'd have to use a file lock, on yet another file). Since that's unlikely to
        // occur in practice, and because a stale socket will prevent communication with dinit (or
        // prevent it starting), then we'll take the chance on unlinking here.
        unlink(saddrname);

        if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
            bool have_error = (errno != EROFS || report_ro_failure);
            if (have_error) {
                log(loglevel_t::ERROR, "Error binding control socket: ", strerror(errno));
            }
            close(sockfd);
            free(name);
            return !have_error;
        }
        
        free(name);

        // No connections can be made until we listen, so it is fine to change the permissions now
        // (and anyway there is no way to atomically create the socket and set permissions):
        if (chmod(saddrname, S_IRUSR | S_IWUSR) == -1) {
            log(loglevel_t::ERROR, "Error setting control socket permissions: ", strerror(errno));
            close(sockfd);
            return false;
        }

        if (listen(sockfd, 10) == -1) {
            log(loglevel_t::ERROR, "Error listening on control socket: ", strerror(errno));
            close(sockfd);
            return false;
        }

        try {
            control_socket_io.add_watch(event_loop, sockfd, dasynq::IN_EVENTS);
            control_socket_open = true;
        }
        catch (std::exception &e)
        {
            log(loglevel_t::ERROR, "Could not setup I/O on control socket: ", e.what());
            close(sockfd);
        }
    }

    return control_socket_open;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movl %edi, %ebp
cmpb $0x1, 0x3b9c2(%rip)     # 0x45d23
jne 0xa3b9
movq 0x3b27e(%rip), %rdi     # 0x455e8
leaq 0x8(%rsp), %rsi
callq 0x8540
testl %eax, %eax
je 0xa3a9
callq 0x8040
cmpl $0x2, (%rax)
jne 0xa3a9
leaq 0x3b8df(%rip), %rdi     # 0x45c68
leaq 0x3b6a0(%rip), %rsi     # 0x45a30
callq 0xd002
movl 0x3b8e9(%rip), %edi     # 0x45c84
callq 0x8b50
movb $0x0, 0x3b97c(%rip)     # 0x45d23
jmp 0xa3b9
cmpb $0x0, 0x3b973(%rip)     # 0x45d23
movb $0x1, %r15b
jne 0xa490
movq 0x3b228(%rip), %r15     # 0x455e8
movq %r15, %rdi
callq 0x8220
movq %rax, %rbx
leal 0x3(%rax), %r12d
movq %r12, %rdi
callq 0x8820
testq %rax, %rax
je 0xa44e
movq %rax, %r14
movw $0x1, (%rax)
movq %rax, %rdi
addq $0x2, %rdi
incq %rbx
movq %r15, %rsi
movq %rbx, %rdx
callq 0x84d0
pushq $0x1
popq %rdi
movl $0x80801, %esi          # imm = 0x80801
xorl %edx, %edx
callq 0x8100
cmpl $-0x1, %eax
je 0xa45f
movl %eax, %ebx
movl %eax, %edi
movq %r14, %rsi
movl %r12d, %edx
callq 0x84f0
movl %eax, %r13d
cmpl $-0x1, %eax
jne 0xa42e
callq 0x8040
cmpl $0xb, (%rax)
jne 0xa4a9
leaq 0x238e4(%rip), %rsi     # 0x2dd19
pushq $0x3
popq %rdi
callq 0x28d42
movl %r13d, %edi
callq 0x8b50
movl %ebx, %edi
callq 0x8b50
jmp 0xa485
leaq 0x2387e(%rip), %rsi     # 0x2dcd3
pushq $0x3
popq %rdi
callq 0x28d42
jmp 0xa48d
callq 0x8040
movl (%rax), %edi
callq 0x81c0
movq %rax, %rbx
leaq 0x23884(%rip), %rsi     # 0x2dcf9
pushq $0x3
popq %rdi
callq 0x28e0a
movq %rbx, %rdi
callq 0x28f31
movq %r14, %rdi
callq 0x8710
xorl %r15d, %r15d
andb $0x1, %r15b
movl %r15d, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r13
movq %r15, %rdi
callq 0x8250
movl %ebx, %edi
movq %r14, %rsi
movl %r12d, %edx
callq 0x8090
cmpl $-0x1, %eax
je 0xa525
movq %r14, %rdi
callq 0x8710
movq %r15, %rdi
movl $0x180, %esi            # imm = 0x180
callq 0x8580
cmpl $-0x1, %eax
je 0xa570
pushq $0xa
popq %rsi
movl %ebx, %edi
callq 0x86a0
cmpl $-0x1, %eax
je 0xa579
leaq 0x3b76a(%rip), %rdi     # 0x45c68
leaq 0x3b52b(%rip), %rsi     # 0x45a30
pushq $0x1
popq %rcx
pushq $0x32
popq %r9
movl %ebx, %edx
movl %ecx, %r8d
callq 0xad4e
movb $0x1, 0x3b806(%rip)     # 0x45d23
movb $0x1, %r15b
jmp 0xa490
movl (%r13), %edi
cmpl $0x1e, %edi
setne %r15b
orb %bpl, %r15b
cmpb $0x1, %r15b
jne 0xa558
callq 0x81c0
movq %rax, %r12
leaq 0x23816(%rip), %rsi     # 0x2dd5e
pushq $0x3
popq %rdi
callq 0x28e0a
movq %r12, %rdi
callq 0x28f31
movl %ebx, %edi
callq 0x8b50
movq %r14, %rdi
callq 0x8710
xorb $0x1, %r15b
jmp 0xa490
leaq 0x23806(%rip), %r14     # 0x2dd7d
jmp 0xa580
leaq 0x23828(%rip), %r14     # 0x2dda8
movl (%r13), %edi
callq 0x81c0
movq %rax, %r15
pushq $0x3
popq %rdi
movq %r14, %rsi
callq 0x28e0a
movq %r15, %rdi
callq 0x28f31
movl %ebx, %edi
callq 0x8b50
jmp 0xa48d
cmpl $0x2, %edx
jne 0xa5f3
movq %rax, %rdi
callq 0x8200
movq (%rax), %rcx
movq %rax, %rdi
callq *0x10(%rcx)
movq %rax, %r14
leaq 0x23801(%rip), %rsi     # 0x2ddcc
pushq $0x3
popq %rdi
callq 0x28e0a
movq %r14, %rdi
callq 0x28f31
movl %ebx, %edi
callq 0x8b50
callq 0x8a40
movb 0x3b735(%rip), %r15b    # 0x45d23
jmp 0xa490
movq %rax, %rdi
callq 0xaebb