user: Converte this assembly snippet into its equivalent C code:

```asm
<main>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %edi,-0x44(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movl   $0x0,-0x14(%rbp)
  movl   $0x0,-0x10(%rbp)
  movl   $0x0,-0xc(%rbp)
  lea    -0x2c(%rbp),%rax
  mov    %rax,%rdi
  call   <pipe@plt>
  lea    -0x24(%rbp),%rax
  mov    %rax,%rdi
  call   <pipe@plt>
  lea    -0x1c(%rbp),%rax
  mov    %rax,%rdi
  call   <pipe@plt>
  call   <fork@plt>
  mov    %eax,-0x38(%rbp)
  cmpl   $0x0,-0x38(%rbp)
  jne    L9
  mov    -0x28(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x2c(%rbp),%eax
  lea    -0x14(%rbp),%rcx
  mov    $0xc,%edx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <read@plt>
  mov    -0xc(%rbp),%ecx
  mov    -0x10(%rbp),%edx
  mov    -0x14(%rbp),%eax
  mov    %eax,%esi
  lea    D32(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x2c(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <child_send@plt>
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <child_wait@plt>
  jmp    L29
L9:
  call   <fork@plt>
  mov    %eax,-0x34(%rbp)
  cmpl   $0x0,-0x34(%rbp)
  jne    L23
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x24(%rbp),%eax
  lea    -0x14(%rbp),%rcx
  mov    $0xc,%edx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <read@plt>
  mov    -0xc(%rbp),%ecx
  mov    -0x10(%rbp),%edx
  mov    -0x14(%rbp),%eax
  mov    %eax,%esi
  lea    D31(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <child_send@plt>
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <child_wait@plt>
  jmp    L29
L23:
  call   <fork@plt>
  mov    %eax,-0x30(%rbp)
  cmpl   $0x0,-0x30(%rbp)
  jne    L6
  mov    -0x18(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x1c(%rbp),%eax
  lea    -0x14(%rbp),%rcx
  mov    $0xc,%edx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <read@plt>
  mov    -0xc(%rbp),%ecx
  mov    -0x10(%rbp),%edx
  mov    -0x14(%rbp),%eax
  mov    %eax,%esi
  lea    D33(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <child_send@plt>
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <child_wait@plt>
  jmp    L29
L6:
  mov    -0x2c(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x38(%rbp),%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x34(%rbp),%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x30(%rbp),%eax
  mov    %eax,-0xc(%rbp)
  mov    -0x28(%rbp),%eax
  lea    -0x14(%rbp),%rcx
  mov    $0xc,%edx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <write@plt>
  mov    -0x20(%rbp),%eax
  lea    -0x14(%rbp),%rcx
  mov    $0xc,%edx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <write@plt>
  mov    -0x18(%rbp),%eax
  lea    -0x14(%rbp),%rcx
  mov    $0xc,%edx
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <write@plt>
  lea    D11(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
L29:
  mov    $0x0,%eax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L32
  call   <__stack_chk_fail@plt>
L32:
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: data_tag: D32
type_guessed: string
name: retrieve_data
arguments: data_tag: D31
type_guessed: string
name: retrieve_data
arguments: data_tag: D33
type_guessed: string
name: retrieve_data
arguments: data_tag: D11
type_guessed: string

tool: D32: CHILD1: pids %d, %d, %d


tool: D31: CHILD2: pids %d, %d, %d


tool: D33: CHILD3: pids %d, %d, %d


tool: D11: PARENT: Wrote to children

assistant: ```c
int main(int argc, char *argv[]) {
  int pid[3] = {0, 0, 0};
  int child1, child2, child3;
  int fd1[2], fd2[2], fd3[2];
  pipe(fd1);
  pipe(fd2);
  pipe(fd3);
  child1 = fork();
  if (!child1) {
    close(fd1[1]);
    read(fd1[0], &pid, sizeof(int) * 3);
    printf("CHILD1: pids %d, %d, %d\n", pid[0], pid[1], pid[2]);
    close(fd1[0]);
    child_send(pid);
    child_wait(pid);
  } else {
    child2 = fork();
    if (!child2) {
      close(fd2[1]);
      read(fd2[0], &pid, sizeof(int) * 3);
      printf("CHILD2: pids %d, %d, %d\n", pid[0], pid[1], pid[2]);
      close(fd2[0]);
      child_send(pid);
      child_wait(pid);
    } else {
      child3 = fork();
      if (!child3) {
        close(fd3[1]);
        read(fd3[0], &pid, sizeof(int) * 3);
        printf("CHILD3: pids %d, %d, %d\n", pid[0], pid[1], pid[2]);
        close(fd3[0]);
        child_send(pid);
        child_wait(pid);
      } else {
        close(fd1[0]);
        close(fd2[0]);
        close(fd3[0]);
        pid[0] = child1;
        pid[1] = child2;
        pid[2] = child3;
        write(fd1[1], &pid, sizeof(int) * 3);
        write(fd2[1], &pid, sizeof(int) * 3);
        write(fd3[1], &pid, sizeof(int) * 3);
        printf("PARENT: Wrote to children\n");
      }
    }
  }
}
```