// File: /workspace/github_cpp_makefile_star2_O2/grogers0[P]dots_and_boxes/DotsDriver.cpp
// Function: spawn_child(char const*, _IO_FILE*&, _IO_FILE*&, _IO_FILE*&, int&)
void spawn_child(const char *cmd, FILE *&child_stdin,
        FILE *&child_stdout, FILE *&child_stderr, pid_t &child_pid)
{
    int fd_stdin[2];
    int fd_stdout[2];
    int fd_stderr[2];

    assert(pipe(fd_stdin) != -1);
    assert(pipe(fd_stdout) != -1);
    assert(pipe(fd_stderr) != -1);

    pid_t pid = fork();
    assert(pid != -1);

    if (pid > 0) {
        // parent
        close(fd_stdin[0]);
        close(fd_stdout[1]);
        close(fd_stderr[1]);

        child_pid = pid;
        assert(child_stdin = fdopen(fd_stdin[1], "w"));
        assert(child_stdout = fdopen(fd_stdout[0], "r"));
        assert(child_stderr = fdopen(fd_stderr[0], "r"));
    } else {
        // child
        close(fd_stdin[1]);
        close(fd_stdout[0]);
        close(fd_stderr[0]);

        move_fd(fd_stdin[0], STDIN_FILENO);
        move_fd(fd_stdout[1], STDOUT_FILENO);
        move_fd(fd_stderr[1], STDERR_FILENO);

        if (execlp(cmd, cmd, (char*)0) == -1) {
            printf("Failed to execute \"%s\": %s\n",
                    cmd, strerror(errno));
            exit(1);
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, %r13
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %rbx
leaq 0x10(%rsp), %rdi
callq 0x2270
cmpl $-0x1, %eax
je 0x4364
leaq 0x8(%rsp), %rdi
callq 0x2270
cmpl $-0x1, %eax
je 0x437d
movq %rsp, %rdi
callq 0x2270
cmpl $-0x1, %eax
je 0x4396
callq 0x2050
cmpl $-0x1, %eax
je 0x43af
movl %eax, %ebp
testl %eax, %eax
jle 0x4300
movl 0x10(%rsp), %edi
callq 0x23c0
movl 0xc(%rsp), %edi
callq 0x23c0
movl 0x4(%rsp), %edi
callq 0x23c0
movl %ebp, (%r13)
movl 0x14(%rsp), %edi
leaq 0x11d3(%rip), %rsi      # 0x5472
callq 0x2200
movq %rax, (%r12)
testq %rax, %rax
je 0x43c8
movl 0x8(%rsp), %edi
leaq 0x11df(%rip), %rsi      # 0x549b
callq 0x2200
movq %rax, (%r15)
testq %rax, %rax
je 0x43e1
movl (%rsp), %edi
leaq 0x11c4(%rip), %rsi      # 0x549b
callq 0x2200
movq %rax, (%r14)
testq %rax, %rax
jne 0x4355
leaq 0x11db(%rip), %rdi      # 0x54c6
leaq 0x10b9(%rip), %rsi      # 0x53ab
leaq 0x1100(%rip), %rcx      # 0x53f9
pushq $0x42
jmp 0x43f8
movl 0x14(%rsp), %edi
callq 0x23c0
movl 0x8(%rsp), %edi
callq 0x23c0
movl (%rsp), %edi
callq 0x23c0
movl 0x10(%rsp), %edi
xorl %esi, %esi
callq 0x41b8
movl 0xc(%rsp), %edi
pushq $0x1
popq %rsi
callq 0x41b8
movl 0x4(%rsp), %edi
pushq $0x2
popq %rsi
callq 0x41b8
movq %rbx, %rdi
movq %rbx, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x2080
cmpl $-0x1, %eax
je 0x43fe
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1079(%rip), %rdi      # 0x53e4
leaq 0x1039(%rip), %rsi      # 0x53ab
leaq 0x1080(%rip), %rcx      # 0x53f9
pushq $0x32
jmp 0x43f8
leaq 0x10b8(%rip), %rdi      # 0x543c
leaq 0x1020(%rip), %rsi      # 0x53ab
leaq 0x1067(%rip), %rcx      # 0x53f9
pushq $0x33
jmp 0x43f8
leaq 0x10b5(%rip), %rdi      # 0x5452
leaq 0x1007(%rip), %rsi      # 0x53ab
leaq 0x104e(%rip), %rcx      # 0x53f9
pushq $0x34
jmp 0x43f8
leaq 0x10b2(%rip), %rdi      # 0x5468
leaq 0xfee(%rip), %rsi       # 0x53ab
leaq 0x1035(%rip), %rcx      # 0x53f9
pushq $0x37
jmp 0x43f8
leaq 0x10a5(%rip), %rdi      # 0x5474
leaq 0xfd5(%rip), %rsi       # 0x53ab
leaq 0x101c(%rip), %rcx      # 0x53f9
pushq $0x40
jmp 0x43f8
leaq 0x10b5(%rip), %rdi      # 0x549d
leaq 0xfbc(%rip), %rsi       # 0x53ab
leaq 0x1003(%rip), %rcx      # 0x53f9
pushq $0x41
popq %rdx
callq 0x2130
callq 0x2030
movl (%rax), %edi
callq 0x2090
leaq 0x10de(%rip), %rdi      # 0x54ef
movq %rbx, %rsi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2040
pushq $0x1
popq %rdi
callq 0x2250