// File: /workspace/github_c_makefile_star2_O0/coyove[P]chann/./lib/mongoose/mongoose.c
// Function: open_cgi_endpoint
static void open_cgi_endpoint(struct connection *conn, const char *prog) {
  struct cgi_env_block blk;
  char dir[MAX_PATH_SIZE];
  const char *p;
  sock_t fds[2];

  prepare_cgi_environment(conn, prog, &blk);
  // CGI must be executed in its own directory. 'dir' must point to the
  // directory containing executable program, 'p' must point to the
  // executable program name relative to 'dir'.
  if ((p = strrchr(prog, '/')) == NULL) {
    mg_snprintf(dir, sizeof(dir), "%s", ".");
  } else {
    mg_snprintf(dir, sizeof(dir), "%.*s", (int) (p - prog), prog);
  }

  // Try to create socketpair in a loop until success. ns_socketpair()
  // can be interrupted by a signal and fail.
  // TODO(lsm): use sigaction to restart interrupted syscall
  {
    int attempts = 0, max_attempts = NS_MAX_SOCKETPAIR_ATTEMPTS;
    do {
      ns_socketpair(fds);
    } while (fds[0] == INVALID_SOCKET && ++attempts < max_attempts);

    if (fds[0] == INVALID_SOCKET) {
      closesocket(fds[0]);
      send_http_error(conn, 500, "ns_socketpair() failed");
    }
  }

  if (start_process(conn->server->config_options[CGI_INTERPRETER],
                    prog, blk.buf, blk.vars, dir, fds[1]) != 0) {
    conn->endpoint_type = EP_CGI;
    conn->endpoint.nc = ns_add_sock(&conn->server->ns_mgr, fds[0],
                                    mg_ev_handler, conn);
    conn->endpoint.nc->flags |= MG_CGI_CONN;
    ns_send(conn->ns_conn, cgi_status, sizeof(cgi_status) - 1);
    conn->mg_conn.status_code = 200;
    conn->ns_conn->flags |= NSF_BUFFER_BUT_DONT_SEND;
    // Pass POST data to the CGI process
    conn->endpoint.nc->send_iobuf = conn->ns_conn->recv_iobuf;
    iobuf_init(&conn->ns_conn->recv_iobuf, 0);
  } else {
    closesocket(fds[0]);
    send_http_error(conn, 500, "start_process(%s) failed", prog);
  }

#ifndef _WIN32
  closesocket(fds[1]);  // On Windows, CGI stdio thread closes that socket
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4240, %rsp           # imm = 0x4240
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x2220(%rbp), %rdx
callq 0xb79f0
movq -0x10(%rbp), %rdi
movl $0x2f, %esi
callq 0xdbe0
movq %rax, -0x4228(%rbp)
cmpq $0x0, %rax
jne 0xb4475
leaq -0x4220(%rbp), %rdi
movl $0x2000, %esi           # imm = 0x2000
leaq 0x103cb(%rip), %rdx     # 0xc4830
leaq 0xb82d(%rip), %rcx      # 0xbfc99
movb $0x0, %al
callq 0xb3c50
jmp 0xb44a3
leaq -0x4220(%rbp), %rdi
movq -0x4228(%rbp), %rax
movq -0x10(%rbp), %rcx
subq %rcx, %rax
movl %eax, %ecx
movq -0x10(%rbp), %r8
movl $0x2000, %esi           # imm = 0x2000
leaq 0xbd14(%rip), %rdx      # 0xc01b0
movb $0x0, %al
callq 0xb3c50
movl $0x0, -0x4234(%rbp)
movl $0xa, -0x4238(%rbp)
leaq -0x4230(%rbp), %rdi
callq 0xaf380
xorl %eax, %eax
cmpl $-0x1, -0x4230(%rbp)
movb %al, -0x4239(%rbp)
jne 0xb44f2
movl -0x4234(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4234(%rbp)
cmpl -0x4238(%rbp), %eax
setl %al
movb %al, -0x4239(%rbp)
movb -0x4239(%rbp), %al
testb $0x1, %al
jne 0xb44b7
cmpl $-0x1, -0x4230(%rbp)
jne 0xb4527
movl -0x4230(%rbp), %edi
callq 0xd350
movq -0x8(%rbp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
leaq 0x13226(%rip), %rdx     # 0xc7746
movb $0x0, %al
callq 0xb3db0
movq -0x8(%rbp), %rax
movq 0x2a8(%rax), %rax
movq 0x50(%rax), %rdi
movq -0x10(%rbp), %rsi
leaq -0x2220(%rbp), %rdx
addq $0x8, %rdx
leaq -0x2220(%rbp), %rcx
addq $0x2008, %rcx           # imm = 0x2008
leaq -0x4220(%rbp), %r8
movl -0x422c(%rbp), %r9d
callq 0xb8040
cmpl $0x0, %eax
je 0xb4645
movq -0x8(%rbp), %rax
movl $0x2, 0x2b8(%rax)
movq -0x8(%rbp), %rax
movq 0x2a8(%rax), %rdi
movl -0x4230(%rbp), %esi
movq -0x8(%rbp), %rcx
leaq -0x1189(%rip), %rdx     # 0xb3410
callq 0xaf920
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x2b0(%rax)
movq -0x8(%rbp), %rax
movq 0x2b0(%rax), %rax
movl 0xa0(%rax), %ecx
orl $0x400000, %ecx         # imm = 0x400000
movl %ecx, 0xa0(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
leaq 0x12449(%rip), %rsi     # 0xc6a20
movl $0x11, %edx
callq 0xafce0
movq -0x8(%rbp), %rax
movl $0xc8, 0x284(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl 0xa0(%rax), %ecx
orl $0x2, %ecx
movl %ecx, 0xa0(%rax)
movq -0x8(%rbp), %rax
movq 0x2b0(%rax), %rax
movq -0x8(%rbp), %rcx
movq (%rcx), %rcx
movq 0x40(%rcx), %rdx
movq %rdx, 0x58(%rax)
movq 0x48(%rcx), %rdx
movq %rdx, 0x60(%rax)
movq 0x50(%rcx), %rcx
movq %rcx, 0x68(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x40, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xaebc0
jmp 0xb466b
movl -0x4230(%rbp), %edi
callq 0xd350
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rcx
movl $0x1f4, %esi            # imm = 0x1F4
leaq 0x130f9(%rip), %rdx     # 0xc775d
movb $0x0, %al
callq 0xb3db0
movl -0x422c(%rbp), %edi
callq 0xd350
addq $0x4240, %rsp           # imm = 0x4240
popq %rbp
retq
nop