// File: /workspace/github_cpp_makefile_star2_O3/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, 0x3c21f(%rip)     # 0x46d23
jne 0xab62
movq 0x3badb(%rip), %rdi     # 0x465e8
leaq 0x8(%rsp), %rsi
callq 0x8540
testl %eax, %eax
je 0xab52
callq 0x8050
cmpl $0x2, (%rax)
jne 0xab52
movl 0x3c159(%rip), %edx     # 0x46c84
leaq 0x3c136(%rip), %rsi     # 0x46c68
leaq 0x3bef7(%rip), %rdi     # 0x46a30
callq 0xd520
movl 0x3c140(%rip), %edi     # 0x46c84
callq 0x8b60
movb $0x0, 0x3c1d3(%rip)     # 0x46d23
jmp 0xab62
cmpb $0x0, 0x3c1ca(%rip)     # 0x46d23
movb $0x1, %r15b
jne 0xac45
movq 0x3ba7f(%rip), %r15     # 0x465e8
movq %r15, %rdi
callq 0x8230
movq %rax, %rbx
leal 0x3(%rax), %r12d
movq %r12, %rdi
callq 0x8820
testq %rax, %rax
je 0xabff
movq %rax, %r14
movw $0x1, (%rax)
movq %rax, %rdi
addq $0x2, %rdi
incq %rbx
movq %r15, %rsi
movq %rbx, %rdx
callq 0x84d0
movl $0x1, %edi
movl $0x80801, %esi          # imm = 0x80801
xorl %edx, %edx
callq 0x8110
cmpl $-0x1, %eax
je 0xac12
movl %eax, %ebx
movl %eax, %edi
movq %r14, %rsi
movl %r12d, %edx
callq 0x84f0
movl %eax, %r13d
cmpl $-0x1, %eax
jne 0xabdd
callq 0x8050
cmpl $0xb, (%rax)
jne 0xac5e
leaq 0x290ec(%rip), %rsi     # 0x33cd0
movl $0x3, %edi
callq 0x2e33a
movl %r13d, %edi
callq 0x8b60
movl %ebx, %edi
callq 0x8b60
jmp 0xac3a
leaq 0x29084(%rip), %rsi     # 0x33c8a
movl $0x3, %edi
callq 0x2e33a
jmp 0xac42
callq 0x8050
movl (%rax), %edi
callq 0x81d0
movq %rax, %rbx
leaq 0x29088(%rip), %rsi     # 0x33cb0
movl $0x3, %edi
callq 0x2e412
movq %rbx, %rdi
callq 0x2e53c
movq %r14, %rdi
callq 0x8720
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 0x80b0
cmpl $-0x1, %eax
je 0xad08
movq %r14, %rdi
callq 0x8720
movq %r15, %rdi
movl $0x180, %esi            # imm = 0x180
callq 0x8580
cmpl $-0x1, %eax
je 0xad55
movl %ebx, %edi
movl $0xa, %esi
callq 0x86a0
cmpl $-0x1, %eax
je 0xad5e
andb $-0x20, 0x3bfbb(%rip)   # 0x46c74
leaq 0x3bfa8(%rip), %rsi     # 0x46c68
movl $0x32, 0x3bfb6(%rip)    # 0x46c80
movl %ebx, 0x3bfb4(%rip)     # 0x46c84
movl $0x1, 0x3bfae(%rip)     # 0x46c88
leaq 0x3bd4f(%rip), %rdi     # 0x46a30
movl %ebx, %edx
movl $0x1, %ecx
movl $0x1, %r8d
movl $0x1, %r9d
callq 0xe198
movb $0x1, 0x3c023(%rip)     # 0x46d23
movb $0x1, %r15b
jmp 0xac45
movl (%r13), %edi
cmpl $0x1e, %edi
setne %r15b
orb %bpl, %r15b
cmpb $0x1, %r15b
jne 0xad3d
callq 0x81d0
movq %rax, %r12
leaq 0x28fea(%rip), %rsi     # 0x33d15
movl $0x3, %edi
callq 0x2e412
movq %r12, %rdi
callq 0x2e53c
movl %ebx, %edi
callq 0x8b60
movq %r14, %rdi
callq 0x8720
xorb $0x1, %r15b
jmp 0xac45
leaq 0x28fd8(%rip), %r14     # 0x33d34
jmp 0xad65
leaq 0x28ffa(%rip), %r14     # 0x33d5f
movl (%r13), %edi
callq 0x81d0
movq %rax, %r15
movl $0x3, %edi
movq %r14, %rsi
callq 0x2e412
movq %r15, %rdi
callq 0x2e53c
movl %ebx, %edi
callq 0x8b60
jmp 0xac42
cmpl $0x2, %edx
jne 0xaddc
movq %rax, %rdi
callq 0x8210
movq (%rax), %rcx
movq %rax, %rdi
callq *0x10(%rcx)
movq %rax, %r14
leaq 0x28fd1(%rip), %rsi     # 0x33d83
movl $0x3, %edi
callq 0x2e412
movq %r14, %rdi
callq 0x2e53c
movl %ebx, %edi
callq 0x8b60
callq 0x8a50
movb 0x3bf4c(%rip), %r15b    # 0x46d23
jmp 0xac45
movq %rax, %rdi
callq 0xb74e