// File: davmac314[P]dinit/src/control.cc
// Function: fill_status_buffer(char*, service_record*)
static void fill_status_buffer(char *buffer, service_record *service)
{
    buffer[0] = static_cast<char>(service->get_state());
    buffer[1] = static_cast<char>(service->get_target_state());

    pid_t proc_pid = service->get_pid();

    char b0 = service->is_waiting_for_console() ? 1 : 0;
    b0 |= service->has_console() ? 2 : 0;
    b0 |= service->was_start_skipped() ? 4 : 0;
    b0 |= service->is_marked_active() ? 8 : 0;
    b0 |= (proc_pid != -1) ? 16 : 0;
    buffer[2] = b0;
    buffer[3] = static_cast<char>(service->get_stop_reason());

    buffer[4] = 0; // (if exec failed, these are replaced with stage)
    buffer[5] = 0;

    if (proc_pid != -1) {
        memcpy(buffer + 6, &proc_pid, sizeof(proc_pid));
    }
    else {
        // These values only make sense in STOPPING/STOPPED, but we'll fill them in regardless:
        if (buffer[3] == (char)stopped_reason_t::EXECFAILED) {
            base_process_service *bsp = (base_process_service *)service;
            run_proc_err exec_err = bsp->get_exec_err_info();
            uint16_t stage = (uint16_t)exec_err.stage;
            memcpy(buffer + 4, &stage, 2);
            memcpy(buffer + 6, &exec_err.st_errno, sizeof(int));
        }
        else {
            auto exit_status_ps = service->get_exit_status();
            // There is no portable way to derive the correct exit status value corresponding
            // to any condition except for a clean exit (0) which is the most important anyway.
            // We'll use -1 for any other status although this may not be valid.
            int exit_status = exit_status_ps.did_exit_clean() ? 0 : -1;
            memcpy(buffer + 6, &exit_status, sizeof(exit_status));
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2f0d0
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, (%rax)
movq -0x10(%rbp), %rdi
callq 0x52d20
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x1(%rax)
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
callq *0x48(%rax)
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rdi
callq 0x61060
movb %al, %dl
xorl %eax, %eax
movl $0x1, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movb %al, -0x15(%rbp)
movq -0x10(%rbp), %rdi
callq 0x61080
movb %al, %dl
xorl %ecx, %ecx
movl $0x2, %eax
testb $0x1, %dl
cmovnel %eax, %ecx
movsbl -0x15(%rbp), %eax
orl %ecx, %eax
movb %al, -0x15(%rbp)
movq -0x10(%rbp), %rdi
callq 0x610a0
movb %al, %dl
xorl %ecx, %ecx
movl $0x4, %eax
testb $0x1, %dl
cmovnel %eax, %ecx
movsbl -0x15(%rbp), %eax
orl %ecx, %eax
movb %al, -0x15(%rbp)
movq -0x10(%rbp), %rdi
callq 0x610c0
movb %al, %dl
xorl %ecx, %ecx
movl $0x8, %eax
testb $0x1, %dl
cmovnel %eax, %ecx
movsbl -0x15(%rbp), %eax
orl %ecx, %eax
movb %al, -0x15(%rbp)
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
movl $0x10, %eax
cmpl $-0x1, %edx
cmovnel %eax, %ecx
movsbl -0x15(%rbp), %eax
orl %ecx, %eax
movb %al, -0x15(%rbp)
movb -0x15(%rbp), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x2(%rax)
movq -0x10(%rbp), %rdi
callq 0x610e0
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x3(%rax)
movq -0x8(%rbp), %rax
movb $0x0, 0x4(%rax)
movq -0x8(%rbp), %rax
movb $0x0, 0x5(%rax)
cmpl $-0x1, -0x14(%rbp)
je 0x5c3c5
movq -0x8(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0x6(%rax)
jmp 0x5c43b
movq -0x8(%rbp), %rax
movsbl 0x3(%rax), %eax
cmpl $0x4, %eax
jne 0x5c406
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x61100
movq %rax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movw %ax, -0x2a(%rbp)
movq -0x8(%rbp), %rax
movw -0x2a(%rbp), %cx
movw %cx, 0x4(%rax)
movq -0x8(%rbp), %rax
movl -0x24(%rbp), %ecx
movl %ecx, 0x6(%rax)
jmp 0x5c439
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
movq %rax, -0x34(%rbp)
leaq -0x34(%rbp), %rdi
callq 0x4e260
movb %al, %dl
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movl -0x38(%rbp), %ecx
movl %ecx, 0x6(%rax)
jmp 0x5c43b
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)