// File: davmac314[P]dinit/src/proc-service.cc
// Function: bgproc_service::read_pid_file(dasynq::dprivate::proc_status*)
bgproc_service::pid_result_t
bgproc_service::read_pid_file(proc_status_t *exit_status) noexcept
{
    const char *pid_file_c = pid_file.c_str();
    int fd = bp_sys::open(pid_file_c, O_CLOEXEC);
    if (fd == -1) {
        log(loglevel_t::ERROR, get_name(), ": read pid file: ", strerror(errno));
        return pid_result_t::FAILED;
    }

    char pidbuf[21]; // just enough to hold any 64-bit integer
    int r = complete_read(fd, pidbuf, 20);
    if (r < 0) {
        // Could not read from PID file
        log(loglevel_t::ERROR, get_name(), ": could not read from pidfile; ", strerror(errno));
        bp_sys::close(fd);
        return pid_result_t::FAILED;
    }

    bp_sys::close(fd);
    pidbuf[r] = 0; // store nul terminator

    bool valid_pid = false;
    errno = 0;
    char *eptr;
    unsigned long long v = std::strtoull(pidbuf, &eptr, 0);
    if (errno == 0 && eptr != pidbuf) {
        if (v <= make_unsigned_val(std::numeric_limits<pid_t>::max())) {
            pid = (pid_t) v;
            valid_pid = true;
        }
    }

    if (valid_pid) {
        siginfo_t child_info;
        child_info.si_pid = 0; // for portability
        int waitid_r = bp_sys::waitid(P_PID, pid, &child_info, WNOHANG | WEXITED);
        if (waitid_r == -1 && errno == ECHILD) {
            // We can't track this child - check process exists:
            if (bp_sys::kill(pid, 0) == 0 || errno != ESRCH) {
                log(loglevel_t::WARN, get_name(), ": unable to supervise process with pid ", pid);
                tracking_child = false;
                return pid_result_t::OK;
            }

            log(loglevel_t::ERROR, get_name(), ": pid read from pidfile (", pid, ") is not valid");
            pid = -1;
            return pid_result_t::FAILED;
        }
        else if (waitid_r == 0) {
            if (child_info.si_pid != 0) {
                pid = -1;
                *exit_status = proc_status_t(child_info.si_code, child_info.si_status);
                return pid_result_t::TERMINATED;
            }

            // Child hasn't terminated, but we can track it (no error)
            child_listener.add_reserved(event_loop, pid, dasynq::DEFAULT_PRIORITY - 10);
            tracking_child = true;
            reserved_child_watch = true;
            return pid_result_t::OK;
        }
    }

    log(loglevel_t::ERROR, get_name(), ": pid read from pidfile (", pid, ") is not valid");
    pid = -1;
    return pid_result_t::FAILED;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x110(%rbp)
addq $0x5f0, %rdi            # imm = 0x5F0
callq 0xa250
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
xorl %eax, %eax
movl $0x80000, %esi          # imm = 0x80000
callq 0xa520
movl %eax, -0x108(%rbp)
jmp 0x50a46
movl -0x108(%rbp), %eax
movl %eax, -0x24(%rbp)
cmpl $-0x1, -0x24(%rbp)
jne 0x50aa0
movq -0x110(%rbp), %rdi
callq 0x2d420
movq %rax, -0x118(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x118(%rbp), %rsi
movq %rax, -0x30(%rbp)
movl $0x3, %edi
leaq 0x2808a(%rip), %rdx     # 0x78b15
leaq -0x30(%rbp), %rcx
callq 0x514c0
movl $0x1, -0x4(%rbp)
jmp 0x50de9
movl -0x24(%rbp), %edi
leaq -0x50(%rbp), %rsi
movl $0x14, %edx
callq 0x52d40
movq %rax, -0x120(%rbp)
jmp 0x50aba
movq -0x120(%rbp), %rax
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
jge 0x50b1f
movq -0x110(%rbp), %rdi
callq 0x2d420
movq %rax, -0x128(%rbp)
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq -0x128(%rbp), %rsi
movq %rax, -0x60(%rbp)
leaq 0x2802c(%rip), %rdx     # 0x78b27
movl $0x3, %edi
leaq -0x60(%rbp), %rcx
callq 0x51500
movl -0x24(%rbp), %edi
callq 0xad80
jmp 0x50b13
movl $0x1, -0x4(%rbp)
jmp 0x50de9
movl -0x24(%rbp), %edi
callq 0xad80
jmp 0x50b29
movslq -0x54(%rbp), %rax
movb $0x0, -0x50(%rbp,%rax)
movb $0x0, -0x61(%rbp)
callq 0xa060
movl $0x0, (%rax)
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rsi
xorl %edx, %edx
callq 0xadf0
movq %rax, -0x78(%rbp)
callq 0xa060
cmpl $0x0, (%rax)
jne 0x50bb5
movq -0x70(%rbp), %rax
leaq -0x50(%rbp), %rcx
cmpq %rcx, %rax
je 0x50bb5
movq -0x78(%rbp), %rax
movq %rax, -0x138(%rbp)
callq 0x40810
movl %eax, %edi
callq 0x52df0
movl %eax, -0x12c(%rbp)
jmp 0x50b8a
movq -0x138(%rbp), %rax
movl -0x12c(%rbp), %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
ja 0x50bb3
movq -0x110(%rbp), %rax
movq -0x78(%rbp), %rcx
movl %ecx, 0x4d8(%rax)
movb $0x1, -0x61(%rbp)
jmp 0x50bb5
testb $0x1, -0x61(%rbp)
je 0x50d9c
movq -0x110(%rbp), %rax
movl $0x0, -0xe8(%rbp)
movl 0x4d8(%rax), %esi
movl $0x1, %edi
leaq -0xf8(%rbp), %rdx
movl $0x5, %ecx
callq 0xa1e0
movl %eax, -0x13c(%rbp)
jmp 0x50bf4
movl -0x13c(%rbp), %eax
movl %eax, -0xfc(%rbp)
cmpl $-0x1, -0xfc(%rbp)
jne 0x50ce3
callq 0xa060
cmpl $0xa, (%rax)
jne 0x50ce3
movq -0x110(%rbp), %rax
movl 0x4d8(%rax), %edi
xorl %esi, %esi
callq 0xaa90
cmpl $0x0, %eax
je 0x50c3e
callq 0xa060
cmpl $0x3, (%rax)
je 0x50c91
movq -0x110(%rbp), %rdi
callq 0x2d420
movq -0x110(%rbp), %rcx
movq %rax, %rsi
addq $0x4d8, %rcx            # imm = 0x4D8
movl $0x2, %edi
leaq 0x27ee0(%rip), %rdx     # 0x78b47
callq 0x51540
movq -0x110(%rbp), %rax
movb 0x4f4(%rax), %cl
andb $-0x9, %cl
orb $0x0, %cl
movb %cl, 0x4f4(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x50de9
movq -0x110(%rbp), %rdi
callq 0x2d420
movq -0x110(%rbp), %rcx
movq %rax, %rsi
addq $0x4d8, %rcx            # imm = 0x4D8
movl $0x3, %edi
leaq 0x27eb5(%rip), %rdx     # 0x78b6f
leaq 0x27ec8(%rip), %r8      # 0x78b89
callq 0x51580
movq -0x110(%rbp), %rax
movl $0xffffffff, 0x4d8(%rax) # imm = 0xFFFFFFFF
movl $0x1, -0x4(%rbp)
jmp 0x50de9
cmpl $0x0, -0xfc(%rbp)
jne 0x50d98
cmpl $0x0, -0xe8(%rbp)
je 0x50d3c
movq -0x110(%rbp), %rax
movl $0xffffffff, 0x4d8(%rax) # imm = 0xFFFFFFFF
movl -0xf0(%rbp), %esi
movl -0xe0(%rbp), %edx
leaq -0x104(%rbp), %rdi
callq 0x1cc80
movq -0x18(%rbp), %rax
movq -0x104(%rbp), %rcx
movq %rcx, (%rax)
movl $0x2, -0x4(%rbp)
jmp 0x50de9
movq -0x110(%rbp), %rax
movq %rax, %rdi
addq $0x338, %rdi            # imm = 0x338
movl 0x4d8(%rax), %edx
leaq 0x57e06(%rip), %rsi     # 0xa8b60
movl $0x28, %ecx
callq 0x52e00
movq -0x110(%rbp), %rax
movb 0x4f4(%rax), %cl
andb $-0x9, %cl
orb $0x8, %cl
movb %cl, 0x4f4(%rax)
movb 0x4f4(%rax), %cl
andb $-0x5, %cl
orb $0x4, %cl
movb %cl, 0x4f4(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x50de9
jmp 0x50d9a
jmp 0x50d9c
movq -0x110(%rbp), %rdi
callq 0x2d420
movq -0x110(%rbp), %rcx
movq %rax, %rsi
addq $0x4d8, %rcx            # imm = 0x4D8
movl $0x3, %edi
leaq 0x27daa(%rip), %rdx     # 0x78b6f
leaq 0x27dbd(%rip), %r8      # 0x78b89
callq 0x51580
movq -0x110(%rbp), %rax
movl $0xffffffff, 0x4d8(%rax) # imm = 0xFFFFFFFF
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq %rax, %rdi
callq 0xfa30
nopl (%rax)