user: 下面的汇编指令对应的C源代码是什么：

```asm
<popen2>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  lea    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <pipe@plt>
  test   %rax,%rax
  jne    L38
  lea    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <pipe@plt>
  test   %rax,%rax
  je     L44
L38:
  mov    $0xffffffff,%eax
  jmp    L4
L44:
  call   <fork@plt>
  mov    %eax,-0x1c(%rbp)
  cmpl   $0x0,-0x1c(%rbp)
  jns    L132
  mov    -0x1c(%rbp),%eax
  jmp    L4
L132:
  cmpl   $0x0,-0x1c(%rbp)
  jne    L14
  mov    -0x14(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  cmpq   $0x0,-0x30(%rbp)
  jne    L39
  mov    -0x18(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  jmp    L24
L39:
  mov    -0x18(%rbp),%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <dup2@plt>
L24:
  mov    -0x10(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  cmpq   $0x0,-0x38(%rbp)
  jne    L10
  mov    -0xc(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  jmp    L34
L10:
  mov    -0xc(%rbp),%eax
  mov    $0x1,%esi
  mov    %eax,%edi
  call   <dup2@plt>
L34:
  mov    -0x28(%rbp),%rax
  mov    $0x0,%r8d
  mov    %rax,%rcx
  lea    D4(%rip),%rax
  mov    %rax,%rdx
  lea    D39(%rip),%rax
  mov    %rax,%rsi
  lea    D38(%rip),%rax
  mov    %rax,%rdi
  call   <execl@plt>
  lea    D31(%rip),%rax
  mov    %rax,%rdi
  call   <perror@plt>
  mov    $0x1,%edi
  call   <exit@plt>
L14:
  cmpq   $0x0,-0x30(%rbp)
  jne    L50
  mov    -0x14(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  jmp    L90
L50:
  mov    -0x14(%rbp),%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
L90:
  cmpq   $0x0,-0x38(%rbp)
  jne    L81
  mov    -0x10(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  jmp    L60
L81:
  mov    -0x10(%rbp),%edx
  mov    -0x38(%rbp),%rax
  mov    %edx,(%rax)
L60:
  mov    -0x18(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0xc(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x1c(%rbp),%eax
L4:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L9
  call   <__stack_chk_fail@plt>
L9:
  leave
  ret
```

tool_calls: name: extract_symbolic_data
arguments: data_label: D4
type_infered: string
name: extract_symbolic_data
arguments: data_label: D39
type_infered: string
name: extract_symbolic_data
arguments: data_label: D38
type_infered: string
name: extract_symbolic_data
arguments: data_label: D31
type_infered: string

tool: D4: -c

tool: D39: sh

tool: D38: /bin/sh

tool: D31: execl

assistant: ```c
pid_t popen2(const char *command, int *infp, int *outfp) {
  int p_stdin[2], p_stdout[2];
  pid_t pid;
  if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
    return -1;
  pid = fork();
  if (pid < 0)
    return pid;
  else if (pid == 0) {
    close(p_stdin[1]);
    if (infp == NULL)
      close(p_stdin[0]);
    else
      dup2(p_stdin[0], 0);
    close(p_stdout[0]);
    if (outfp == NULL)
      close(p_stdout[1]);
    else
      dup2(p_stdout[1], 1);
    execl("/bin/sh", "sh", "-c", command, NULL);
    perror("execl");
    exit(1);
  }
  if (infp == NULL)
    close(p_stdin[1]);
  else
    *infp = p_stdin[1];
  if (outfp == NULL)
    close(p_stdout[0]);
  else
    *outfp = p_stdout[0];
  close(p_stdin[0]);
  close(p_stdout[1]);
  return pid;
}
```