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

```asm
<main>:
  endbr64
  push   %rbp
  push   %rbx
  sub    $0x78,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x68(%rsp)
  xor    %eax,%eax
  lea    0x8(%rsp),%rdi
  lea    0x10(%rsp),%rbp
  call   <pipe@plt>
  mov    0xc(%rsp),%edx
  mov    0x8(%rsp),%esi
  xor    %eax,%eax
  lea    D17(%rip),%rdi
  call   <printf@plt>
  call   <fork@plt>
  test   %eax,%eax
  je     L46
L25:
  mov    0x8(%rsp),%edi
  call   <close@plt>
  lea    D34(%rip),%rdi
  call   <puts@plt>
  xor    %edi,%edi
  mov    $0x50,%edx
  mov    %rbp,%rsi
  call   <read@plt>
  mov    0xc(%rsp),%edi
  mov    %rbp,%rsi
  mov    %eax,%edx
  mov    %eax,%ebx
  call   <write@plt>
  mov    0xc(%rsp),%edi
  call   <close@plt>
  xor    %edi,%edi
  call   <wait@plt>
  xor    %edi,%edi
  mov    $0x19,%edx
  lea    D21(%rip),%rsi
  call   <write@plt>
  xor    %edi,%edi
  lea    -0x1(%rbx),%edx
  mov    %rbp,%rsi
  call   <write@plt>
  xor    %eax,%eax
  call   <getpid@plt>
  lea    D27(%rip),%rdi
  mov    %eax,%esi
  xor    %eax,%eax
  call   <printf@plt>
  xor    %edi,%edi
  call   <exit@plt>
  mov    0x68(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L29
  add    $0x78,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  ret
L46:
  mov    0xc(%rsp),%edi
  call   <close@plt>
  mov    0x8(%rsp),%edi
  mov    $0x50,%edx
  mov    %rbp,%rsi
  call   <read@plt>
  mov    $0x17,%edx
  mov    %eax,%ebx
  test   %eax,%eax
  jle    L16
  lea    D43(%rip),%rsi
  xor    %edi,%edi
  call   <write@plt>
  mov    %rbp,%rsi
  xor    %edi,%edi
  lea    -0x1(%rbx),%edx
  call   <write@plt>
  xor    %eax,%eax
  call   <getpid@plt>
  lea    D69(%rip),%rdi
  mov    %eax,%esi
  xor    %eax,%eax
  call   <printf@plt>
L36:
  xor    %edi,%edi
  call   <exit@plt>
  jmp    L25
L16:
  lea    D64(%rip),%rsi
  xor    %edi,%edi
  call   <write@plt>
  jmp    L36
L29:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: tag: D17
type_infered: string
name: unpack_data
arguments: tag: D34
type_infered: string
name: unpack_data
arguments: tag: D21
type_infered: string
name: unpack_data
arguments: tag: D27
type_infered: string
name: unpack_data
arguments: tag: D43
type_infered: string
name: unpack_data
arguments: tag: D69
type_infered: string
name: unpack_data
arguments: tag: D64
type_infered: string

tool: D17: ipc[0] = %d ipc[1] =%d 
 

tool: D34: 
Ingrese una cadena de caracteres por consola:

tool: D21: 
Escrito en la tuberia: 

tool: D27: , por el proceso padre, pid %d 


tool: D43: 
Leido de la tuberia: 

tool: D69: , por el proceso hijo, pid %d 


tool: D64: 
Error al leer tuberia

assistant: ```c
int main() {
  int ipc[2], proc;
  int leido;
  char buff[80];
  pipe(ipc);
  printf("ipc[0] = %d ipc[1] =%d \n ", ipc[0], ipc[1]);
  proc = fork();
  if (proc == 0) {
    close(ipc[1]);
    leido = read(ipc[0], buff, sizeof(buff));
    if (leido < 1) {
      write(0, "\nError al leer tuberia", sizeof("\nError al leer tuberia"));
    } else {
      write(0, "\nLeido de la tuberia: ", sizeof("\nLeido de la tuberia: "));
      write(0, buff, leido - 1);
      printf(", por el proceso hijo, pid %d \n", getpid());
    }
    exit(0);
  }
  close(ipc[0]);
  printf("\nIngrese una cadena de caracteres por consola:\n");
  leido = read(0, buff, sizeof(buff));
  write(ipc[1], buff, leido);
  close(ipc[1]);
  wait(NULL);
  write(0, "\nEscrito en la tuberia: ", sizeof("\nEscrito en la tuberia: "));
  write(0, buff, leido - 1);
  printf(", por el proceso padre, pid %d \n", getpid());
  exit(0);
}
```