// File: davmac314[P]dinit/src/control.cc
// Function: control_conn_t::process_signal()
bool control_conn_t::process_signal()
{
    // packet contains signal number and process handle
    constexpr int pkt_size = 1 + sizeof(int) + sizeof(handle_t);
    if (rbuf.get_length() < pkt_size) {
        chklen = pkt_size;
        return true;
    }

    sig_num_t sig_num;
    rbuf.extract(&sig_num, 1, sizeof(sig_num));
    handle_t handle;
    rbuf.extract(&handle, 1 + sizeof(sig_num), sizeof(handle));
    rbuf.consume(pkt_size);
    chklen = 0;

    service_record *service = find_service_for_key(handle);
    if (service == nullptr) {
        char nak_rep[] = { (char)cp_rply::NAK };
        return queue_packet(nak_rep, 1);
    }

    // Reply:
    // 1 byte packet type = cp_rply::*

    pid_t spid = service->get_pid();
    // we probably don't want to kill/signal every process (in the current group),
    // but get_pid() sometimes returns -1 if e.g. service is not 'started'
    if (spid == -1 || spid == 0) {
        char nak_rep[] = { (char)cp_rply::SIGNAL_NOPID };
        return queue_packet(nak_rep, 1);
    }
    else {
        if (bp_sys::kill(spid, sig_num) != 0) {
            if (errno == EINVAL) {
                log(loglevel_t::ERROR, "Requested signal not in valid signal range.");
                char nak_rep[] = { (char)cp_rply::SIGNAL_BADSIG };
                return queue_packet(nak_rep, 1);
            }
            log(loglevel_t::ERROR, "Error sending signal to process: ", strerror(errno));
            char nak_rep[] = { (char)cp_rply::SIGNAL_KILLERR };
            return queue_packet(nak_rep, 1);
        }
    }
    char ack_rep[] = { (char)cp_rply::ACK };
    return queue_packet(ack_rep, 1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x50(%rbp)
movl $0x9, -0x14(%rbp)
addq $0x80, %rdi
callq 0x5e200
cmpl $0x9, %eax
jae 0x5b8c0
movq -0x50(%rbp), %rax
movl $0x9, 0x7c(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x5ba4c
movq -0x50(%rbp), %rdi
addq $0x80, %rdi
leaq -0x18(%rbp), %rsi
movl $0x1, %edx
movl $0x4, %ecx
callq 0x5e220
movq -0x50(%rbp), %rdi
addq $0x80, %rdi
leaq -0x1c(%rbp), %rsi
movl $0x5, %edx
movl $0x4, %ecx
callq 0x5e220
movq -0x50(%rbp), %rdi
addq $0x80, %rdi
movl $0x9, %esi
callq 0x5e1a0
movq -0x50(%rbp), %rdi
movl $0x0, 0x7c(%rdi)
movl -0x1c(%rbp), %esi
callq 0x5e970
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x5b954
movq -0x50(%rbp), %rdi
movb 0x1db25(%rip), %al      # 0x7945e
movb %al, -0x29(%rbp)
leaq -0x29(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x5ba4c
movq -0x28(%rbp), %rdi
movq (%rdi), %rax
callq *0x48(%rax)
movl %eax, -0x30(%rbp)
cmpl $-0x1, -0x30(%rbp)
je 0x5b96d
cmpl $0x0, -0x30(%rbp)
jne 0x5b992
movq -0x50(%rbp), %rdi
movb 0x1dae8(%rip), %al      # 0x7945f
movb %al, -0x31(%rbp)
leaq -0x31(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x5ba4c
movl -0x30(%rbp), %edi
movl -0x18(%rbp), %esi
callq 0xaa90
cmpl $0x0, %eax
je 0x5ba2a
callq 0xa060
cmpl $0x16, (%rax)
jne 0x5b9e3
movl $0x3, %edi
leaq 0x1dad7(%rip), %rsi     # 0x79493
callq 0x6b540
movq -0x50(%rbp), %rdi
movb 0x1da95(%rip), %al      # 0x79460
movb %al, -0x32(%rbp)
leaq -0x32(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x5ba4c
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq %rax, -0x40(%rbp)
movl $0x3, %edi
leaq 0x1dac0(%rip), %rsi     # 0x794bf
leaq -0x40(%rbp), %rdx
callq 0x5c6f0
movq -0x50(%rbp), %rdi
movb 0x1da4f(%rip), %al      # 0x79461
movb %al, -0x41(%rbp)
leaq -0x41(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x5ba4c
jmp 0x5ba2c
movq -0x50(%rbp), %rdi
movb 0x1da2c(%rip), %al      # 0x79462
movb %al, -0x42(%rbp)
leaq -0x42(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)