// File: /workspace/github_cpp_makefile_star2_O3/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 0x2260
cmpl $-0x1, %eax
je 0x470b
leaq 0x8(%rsp), %rdi
callq 0x2260
cmpl $-0x1, %eax
je 0x472a
movq %rsp, %rdi
callq 0x2260
cmpl $-0x1, %eax
je 0x4749
callq 0x2050
cmpl $-0x1, %eax
je 0x4768
movl %eax, %ebp
testl %eax, %eax
jle 0x46a3
movl 0x10(%rsp), %edi
callq 0x23b0
movl 0xc(%rsp), %edi
callq 0x23b0
movl 0x4(%rsp), %edi
callq 0x23b0
movl %ebp, (%r13)
movl 0x14(%rsp), %edi
leaq 0xe33(%rip), %rsi       # 0x5472
callq 0x21f0
movq %rax, (%r12)
testq %rax, %rax
je 0x4787
movl 0x8(%rsp), %edi
leaq 0xe3f(%rip), %rsi       # 0x549b
callq 0x21f0
movq %rax, (%r15)
testq %rax, %rax
je 0x47a6
movl (%rsp), %edi
leaq 0xe24(%rip), %rsi       # 0x549b
callq 0x21f0
movq %rax, (%r14)
testq %rax, %rax
jne 0x46fc
leaq 0xe3b(%rip), %rdi       # 0x54c6
leaq 0xd19(%rip), %rsi       # 0x53ab
leaq 0xd60(%rip), %rcx       # 0x53f9
movl $0x42, %edx
callq 0x2120
movl 0x14(%rsp), %edi
callq 0x23b0
movl 0x8(%rsp), %edi
callq 0x23b0
movl (%rsp), %edi
callq 0x23b0
movl 0x10(%rsp), %edi
xorl %esi, %esi
callq 0x4550
movl 0xc(%rsp), %edi
movl $0x1, %esi
callq 0x4550
movl 0x4(%rsp), %edi
movl $0x2, %esi
callq 0x4550
movq %rbx, %rdi
movq %rbx, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x2080
cmpl $-0x1, %eax
je 0x47c5
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xcd2(%rip), %rdi       # 0x53e4
leaq 0xc92(%rip), %rsi       # 0x53ab
leaq 0xcd9(%rip), %rcx       # 0x53f9
movl $0x32, %edx
callq 0x2120
leaq 0xd0b(%rip), %rdi       # 0x543c
leaq 0xc73(%rip), %rsi       # 0x53ab
leaq 0xcba(%rip), %rcx       # 0x53f9
movl $0x33, %edx
callq 0x2120
leaq 0xd02(%rip), %rdi       # 0x5452
leaq 0xc54(%rip), %rsi       # 0x53ab
leaq 0xc9b(%rip), %rcx       # 0x53f9
movl $0x34, %edx
callq 0x2120
leaq 0xcf9(%rip), %rdi       # 0x5468
leaq 0xc35(%rip), %rsi       # 0x53ab
leaq 0xc7c(%rip), %rcx       # 0x53f9
movl $0x37, %edx
callq 0x2120
leaq 0xce6(%rip), %rdi       # 0x5474
leaq 0xc16(%rip), %rsi       # 0x53ab
leaq 0xc5d(%rip), %rcx       # 0x53f9
movl $0x40, %edx
callq 0x2120
leaq 0xcf0(%rip), %rdi       # 0x549d
leaq 0xbf7(%rip), %rsi       # 0x53ab
leaq 0xc3e(%rip), %rcx       # 0x53f9
movl $0x41, %edx
callq 0x2120
callq 0x2030
movl (%rax), %edi
callq 0x2090
leaq 0xd17(%rip), %rdi       # 0x54ef
movq %rbx, %rsi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2040
movl $0x1, %edi
callq 0x2240