// File: /workspace/github_cpp_makefile_star2_O3/davmac314[P]dinit/src/shutdown.cc
// Function: run_process(char const**, dasynq::v2::event_loop<dasynq::null_mutex, dasynq::v2::default_traits<dasynq::null_mutex>>&, subproc_buffer&)
static loop_t::child_proc_watcher::proc_status_t run_process(const char * prog_args[],
        loop_t &loop, subproc_buffer &sub_buf)
{
    class sp_watcher_t : public loop_t::child_proc_watcher_impl<sp_watcher_t>
    {
        public:
        bool terminated = false;
        proc_status_t exit_status;

        rearm status_change(loop_t &, pid_t child, proc_status_t status)
        {
            terminated = true;
            exit_status = status;
            return rearm::REMOVE;
        }
    };

    sp_watcher_t sp_watcher;

    // Create output pipe
    bool have_pipe = true;
    int pipefds[2];
    if (dasynq::pipe2(pipefds, O_NONBLOCK) == -1) {
        sub_buf.append("Warning: ");
        sub_buf.append(prog_args[0]);
        sub_buf.append(": could not create pipe for subprocess output\n");
        have_pipe = false;
        // Note, we proceed and let the sub-process run with our stdout/stderr.
    }

    subproc_out_watch owatch {sub_buf};

    if (have_pipe) {
        try {
            owatch.add_watch(loop, pipefds[0], dasynq::IN_EVENTS);
        }
        catch (...) {
            // failed to create the watcher for the subprocess output; again, let it run with
            // our stdout/stderr
            sub_buf.append("Warning: could not create output watch for subprocess\n");
            close(pipefds[0]);
            close(pipefds[1]);
            have_pipe = false;
        }
    }

    // If we've buffered any messages/output, give them a chance to go out now:
    loop.poll();

    pid_t ch_pid = sp_watcher.fork(loop);
    if (ch_pid == 0) {
        // child
        // Dup output pipe to stdout, stderr
        if (have_pipe) {
            dup2(pipefds[1], STDOUT_FILENO);
            dup2(pipefds[1], STDERR_FILENO);
            close(pipefds[0]);
            close(pipefds[1]);
        }
        execv(prog_args[0], const_cast<char **>(prog_args));
        puts("Failed to execute subprocess: ");
        perror(prog_args[0]);
        _exit(1);
    }
    if (have_pipe) {
        close(pipefds[1]);
    }

    do {
        loop.run();
    } while (!sp_watcher.terminated);

    if (have_pipe) {
        owatch.deregister(loop);
        close(pipefds[0]);
    }

    return sp_watcher.exit_status;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x88, %rsp
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
movl $0x2, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x30(%rsp)
movq %rax, 0x3c(%rsp)
leaq 0x790f(%rip), %rcx      # 0xbad0
movq %rcx, 0x8(%rsp)
movb $0x0, 0x44(%rsp)
movq %rax, 0x48(%rsp)
movq %rsp, %rdi
movl $0x800, %esi            # imm = 0x800
callq 0x3180
cmpl $-0x1, %eax
je 0x4233
movl $0x1, %eax
leaq 0x50(%rsp), %rsi
movl %eax, 0x8(%rsi)
leaq 0x7ae2(%rip), %rcx      # 0xbcd8
movq %rcx, (%rsi)
movq %r15, 0x28(%rsi)
xorl %ecx, %ecx
movb %cl, 0x30(%rsi)
movl (%rsp), %edx
movb %cl, 0xc(%rsi)
movl $0x32, 0x18(%rsi)
movl %edx, 0x1c(%rsi)
movl %eax, 0x20(%rsi)
movb $0x1, %bpl
movq %rbx, %rdi
movl $0x1, %ecx
movl $0x1, %r8d
movl $0x1, %r9d
callq 0x5022
jmp 0x427f
leaq 0x4692(%rip), %rsi      # 0x88cc
movq %r15, %rdi
callq 0x47f2
movq (%r14), %rsi
movq %r15, %rdi
callq 0x47f2
leaq 0x4682(%rip), %rsi      # 0x88d6
movq %r15, %rdi
callq 0x47f2
movl $0x1, 0x58(%rsp)
leaq 0x7a6d(%rip), %rax      # 0xbcd8
movq %rax, 0x50(%rsp)
movq %r15, 0x78(%rsp)
movb $0x0, 0x80(%rsp)
xorl %ebp, %ebp
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x4938
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
xorl %edx, %edx
movl $0x32, %ecx
callq 0x5dda
testl %eax, %eax
je 0x42f6
testb %bpl, %bpl
je 0x42b2
movl 0x4(%rsp), %edi
callq 0x3470
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x48b0
cmpb $0x1, 0x44(%rsp)
jne 0x42b2
testb %bpl, %bpl
je 0x42e3
leaq 0x50(%rsp), %rsi
movl 0x1c(%rsi), %edx
movq %rbx, %rdi
callq 0x56cc
movl (%rsp), %edi
callq 0x3470
movq 0x48(%rsp), %rax
addq $0x88, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movzbl %bpl, %edi
movq %rsp, %rsi
movq %r14, %rdx
callq 0x3490
movq %rax, %rdi
callq 0x30e0
leaq 0x45f1(%rip), %rsi      # 0x8905
movq %r15, %rdi
callq 0x47f2
movl (%rsp), %edi
callq 0x3470
movl 0x4(%rsp), %edi
callq 0x3470
callq 0x3400
jmp 0x427d
movq %rax, %rbx
callq 0x3400
movq %rbx, %rdi
callq 0x3440
movq %rax, %rdi
callq 0x47e6
nop