// File: /workspace/github_c_makefile_star2_O0/motet-a[P]libforks/libforks.c
// Function: libforks_fork
libforks_Result libforks_fork(
    libforks_ServerConn conn_p,
    pid_t *pid_ptr, // out
    int *socket_fd_ptr, // out
    int *exit_fd_ptr, // out
    void (*entrypoint)(libforks_ServerConn conn, int socket_fd)
  ) {

  ServerConn *conn = conn_p.private;

  ClientMessage req = {
    .type = ClientMessageType_FORK_REQUEST,
    .u = {
      .fork_request = {
        .create_user_socket = socket_fd_ptr != NULL,
        .create_exit_pipe = exit_fd_ptr != NULL,
        .entrypoint = entrypoint,
      },
    },
  };

  if (write_exact(conn->socket, &req, sizeof req) == -1) {
    return libforks_WRITE_ERROR;
  }

  ServerMessage res;
  int received_fds[2] = {-1, -1};
  int read_res = libforks_read_socket_fds(
    conn->socket,
    &res, sizeof res,
    received_fds, 2
  );
  if (read_res == -1) {
    return libforks_READ_ERROR;
  }

  if (res.type == ServerMessageType_FORK_FAILURE) {
    assert(res.u.fork_failure.error_code != libforks_OK);
    errno = res.u.fork_failure.saved_errno;
    return res.u.fork_failure.error_code;
  }

  assert(res.type == ServerMessageType_FORK_SUCCESS);

  if (pid_ptr) {
    *pid_ptr = res.u.fork_success.pid;
  }

  unsigned i = 0;
  if (socket_fd_ptr) {
    *socket_fd_ptr = received_fds[i++];
  }
  if (exit_fd_ptr) {
    *exit_fd_ptr = received_fds[i++];
  }

  return libforks_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x20(%rbp)
setne %al
andb $0x1, %al
movb %al, -0x50(%rbp)
cmpq $0x0, -0x28(%rbp)
setne %al
andb $0x1, %al
movb %al, -0x4f(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x40(%rbp)
movq -0x38(%rbp), %rax
movl 0x4(%rax), %edi
leaq -0x50(%rbp), %rsi
movl $0x18, %edx
callq 0x1aa0
cmpl $-0x1, %eax
jne 0x2353
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
jmp 0x245b
movq 0x249a(%rip), %rax      # 0x47f4
movq %rax, -0x64(%rbp)
movq -0x38(%rbp), %rax
movl 0x4(%rax), %edi
leaq -0x64(%rbp), %rcx
leaq -0x5c(%rbp), %rsi
movl $0xc, %edx
movl $0x2, %r8d
callq 0x1510
movl %eax, -0x68(%rbp)
cmpl $-0x1, -0x68(%rbp)
jne 0x2392
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x245b
cmpl $0x1, -0x54(%rbp)
jne 0x23da
cmpl $0x0, -0x5c(%rbp)
je 0x23a0
jmp 0x23bf
leaq 0x1eac(%rip), %rdi      # 0x4253
leaq 0x1e05(%rip), %rsi      # 0x41b3
movl $0x43a, %edx            # imm = 0x43A
leaq 0x1ec6(%rip), %rcx      # 0x4280
callq 0x10b0
movl -0x58(%rbp), %eax
movl %eax, -0x70(%rbp)
callq 0x1050
movl -0x70(%rbp), %ecx
movl %ecx, (%rax)
movl -0x5c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x245b
cmpl $0x0, -0x54(%rbp)
jne 0x23e2
jmp 0x2401
leaq 0x1f05(%rip), %rdi      # 0x42ee
leaq 0x1dc3(%rip), %rsi      # 0x41b3
movl $0x43f, %edx            # imm = 0x43F
leaq 0x1e84(%rip), %rcx      # 0x4280
callq 0x10b0
cmpq $0x0, -0x18(%rbp)
je 0x2411
movl -0x5c(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movl $0x0, -0x6c(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x2436
movl -0x6c(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x6c(%rbp)
movl %eax, %eax
movl -0x64(%rbp,%rax,4), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
cmpq $0x0, -0x28(%rbp)
je 0x2454
movl -0x6c(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x6c(%rbp)
movl %eax, %eax
movl -0x64(%rbp,%rax,4), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)