// File: davmac314[P]dinit/src/baseproc-service.cc
// Function: base_process_service::open_socket()
bool base_process_service::open_socket() noexcept
{
    if (socket_path.empty() || socket_fd != -1) {
        // No socket, or already open
        return true;
    }

    const char * saddrname = socket_path.c_str();

    // Check the specified socket path
    struct stat stat_buf;
    if (stat(saddrname, &stat_buf) == 0) {
        if ((stat_buf.st_mode & S_IFSOCK) == 0) {
            // Not a socket
            log(loglevel_t::ERROR, get_name(), ": activation socket file exists (and is not a socket)");
            return false;
        }
    }
    else if (errno != ENOENT) {
        // Other error
        log(loglevel_t::ERROR, get_name(), ": error checking activation socket: ", strerror(errno));
        return false;
    }

    // Remove stale socket file (if it exists).
    // We won't test the return from unlink - if it fails other than due to ENOENT, we should get an
    // error when we try to create the socket anyway.
    unlink(saddrname);

    uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + socket_path.length() + 1;
    struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
    if (name == nullptr) {
        log(loglevel_t::ERROR, get_name(), ": opening activation socket: out of memory");
        return false;
    }

    name->sun_family = AF_UNIX;
    strcpy(name->sun_path, saddrname);

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

    if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
        log(loglevel_t::ERROR, get_name(), ": error binding activation socket: ", strerror(errno));
        close(sockfd);
        free(name);
        return false;
    }

    free(name);

    // POSIX (1003.1, 2013) says that fchown and fchmod don't necessarily work on sockets. We have to
    // use chown and chmod instead.
    if (chown(saddrname, socket_uid, socket_gid)) {
        log(loglevel_t::ERROR, get_name(), ": error setting activation socket owner/group: ",
                strerror(errno));
        close(sockfd);
        return false;
    }

    if (chmod(saddrname, socket_perms) == -1) {
        log(loglevel_t::ERROR, get_name(), ": Error setting activation socket permissions: ",
                strerror(errno));
        close(sockfd);
        return false;
    }

    if (listen(sockfd, 128) == -1) { // 128 "seems reasonable".
        log(loglevel_t::ERROR, ": error listening on activation socket: ", strerror(errno));
        close(sockfd);
        return false;
    }

    socket_fd = sockfd;
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
addq $0x198, %rdi            # imm = 0x198
callq 0xac70
testb $0x1, %al
jne 0x5501a
movq -0xf8(%rbp), %rax
cmpl $-0x1, 0x4e4(%rax)
je 0x55023
movb $0x1, -0x1(%rbp)
jmp 0x553e8
movq -0xf8(%rbp), %rdi
addq $0x198, %rdi            # imm = 0x198
callq 0xa250
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0xa640
cmpl $0x0, %eax
jne 0x5508a
movl -0x90(%rbp), %eax
andl $0xc000, %eax           # imm = 0xC000
cmpl $0x0, %eax
jne 0x55088
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, %rsi
movl $0x3, %edi
leaq 0x23f0a(%rip), %rdx     # 0x78f84
callq 0x56f30
movb $0x0, -0x1(%rbp)
jmp 0x553e8
jmp 0x550e4
callq 0xa060
cmpl $0x2, (%rax)
je 0x550e2
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, -0x100(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x100(%rbp), %rsi
movq %rax, -0xb0(%rbp)
movl $0x3, %edi
leaq 0x23eed(%rip), %rdx     # 0x78fba
leaq -0xb0(%rbp), %rcx
callq 0x56f60
movb $0x0, -0x1(%rbp)
jmp 0x553e8
jmp 0x550e4
movq -0x18(%rbp), %rdi
callq 0xa2c0
movq -0xf8(%rbp), %rdi
addq $0x198, %rdi            # imm = 0x198
callq 0xab20
addq $0x2, %rax
addq $0x1, %rax
movl %eax, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
movl %eax, %edi
callq 0xa9e0
movq %rax, -0xc0(%rbp)
cmpq $0x0, -0xc0(%rbp)
jne 0x55155
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, %rsi
movl $0x3, %edi
leaq 0x23e98(%rip), %rdx     # 0x78fdf
callq 0x56fa0
movb $0x0, -0x1(%rbp)
jmp 0x553e8
movq -0xc0(%rbp), %rax
movw $0x1, (%rax)
movq -0xc0(%rbp), %rdi
addq $0x2, %rdi
movq -0x18(%rbp), %rsi
callq 0xa6a0
movl $0x1, %esi
xorl %edx, %edx
movl $0x80800, %ecx          # imm = 0x80800
movl %esi, %edi
callq 0x56fd0
movl %eax, -0x104(%rbp)
jmp 0x55190
movl -0x104(%rbp), %eax
movl %eax, -0xc4(%rbp)
cmpl $-0x1, -0xc4(%rbp)
jne 0x551ff
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, -0x110(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x110(%rbp), %rsi
movq %rax, -0xd0(%rbp)
movl $0x3, %edi
leaq 0x23e2c(%rip), %rdx     # 0x7900a
leaq -0xd0(%rbp), %rcx
callq 0x56f60
movq -0xc0(%rbp), %rdi
callq 0xa890
movb $0x0, -0x1(%rbp)
jmp 0x553e8
movl -0xc4(%rbp), %edi
movq -0xc0(%rbp), %rsi
movl -0xb4(%rbp), %edx
callq 0xa0b0
cmpl $-0x1, %eax
jne 0x55283
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, -0x118(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x118(%rbp), %rsi
movq %rax, -0xd8(%rbp)
leaq 0x23ddf(%rip), %rdx     # 0x7902f
movl $0x3, %edi
leaq -0xd8(%rbp), %rcx
callq 0x57000
movl -0xc4(%rbp), %edi
callq 0xad80
jmp 0x5526e
movq -0xc0(%rbp), %rdi
callq 0xa890
movb $0x0, -0x1(%rbp)
jmp 0x553e8
movq -0xc0(%rbp), %rdi
callq 0xa890
movq -0xf8(%rbp), %rax
movq -0x18(%rbp), %rdi
movl 0x1bc(%rax), %esi
movl 0x1c0(%rax), %edx
callq 0xa480
cmpl $0x0, %eax
je 0x5530b
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, -0x120(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x120(%rbp), %rsi
movq %rax, -0xe0(%rbp)
leaq 0x23d6f(%rip), %rdx     # 0x79053
movl $0x3, %edi
leaq -0xe0(%rbp), %rcx
callq 0x57040
movl -0xc4(%rbp), %edi
callq 0xad80
jmp 0x55302
movb $0x0, -0x1(%rbp)
jmp 0x553e8
movq -0xf8(%rbp), %rax
movq -0x18(%rbp), %rdi
movl 0x1b8(%rax), %esi
callq 0xa680
cmpl $-0x1, %eax
jne 0x5537e
movq -0xf8(%rbp), %rdi
callq 0x2d420
movq %rax, -0x128(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x128(%rbp), %rsi
movq %rax, -0xe8(%rbp)
leaq 0x23d29(%rip), %rdx     # 0x79083
movl $0x3, %edi
leaq -0xe8(%rbp), %rcx
callq 0x57040
movl -0xc4(%rbp), %edi
callq 0xad80
jmp 0x55378
movb $0x0, -0x1(%rbp)
jmp 0x553e8
movl -0xc4(%rbp), %edi
movl $0x80, %esi
callq 0xa810
cmpl $-0x1, %eax
jne 0x553d1
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq %rax, -0xf0(%rbp)
leaq 0x23d06(%rip), %rsi     # 0x790b3
movl $0x3, %edi
leaq -0xf0(%rbp), %rdx
callq 0x57080
movl -0xc4(%rbp), %edi
callq 0xad80
jmp 0x553cb
movb $0x0, -0x1(%rbp)
jmp 0x553e8
movq -0xf8(%rbp), %rax
movl -0xc4(%rbp), %ecx
movl %ecx, 0x4e4(%rax)
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
movq %rax, %rdi
callq 0xfa30
nop