user: 请将以下的汇编代码转换成C语言代码:

```asm
<forkpty>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x14(%rbp)
  movl   $0x0,-0xc(%rbp)
  mov    -0x50(%rbp),%rdi
  mov    -0x48(%rbp),%rcx
  mov    -0x40(%rbp),%rdx
  lea    -0x24(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <openpty@plt>
  test   %rax,%rax
  jns    L144
  mov    $0xffffffff,%eax
  jmp    L159
L144:
  movl   $0x0,-0x20(%rbp)
  jmp    L73
L92:
  mov    D12(%rip),%rax
  mov    (%rax),%edx
  mov    -0x20(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  mov    $0x0,%eax
  call   <fcntl@plt>
  test   %eax,%eax
  jns    L180
  mov    D11(%rip),%rax
  mov    (%rax),%ecx
  mov    -0x24(%rbp),%eax
  mov    -0x20(%rbp),%edx
  mov    %ecx,%esi
  mov    %eax,%edi
  mov    $0x0,%eax
  call   <fcntl@plt>
  mov    %eax,-0x1c(%rbp)
  cmpl   $0x0,-0x1c(%rbp)
  js     L25
  mov    -0x1c(%rbp),%eax
  cmp    -0x20(%rbp),%eax
  je     L96
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  jmp    L180
L96:
  mov    -0x20(%rbp),%eax
  cltq
  movl   $0x1,-0x14(%rbp,%rax,4)
L180:
  addl   $0x1,-0x20(%rbp)
L73:
  cmpl   $0x2,-0x20(%rbp)
  jle    L92
  jmp    L32
L25:
  nop
L32:
  cmpl   $0x3,-0x20(%rbp)
  jne    L108
  call   <fork@plt>
  jmp    L24
L108:
  mov    $0xffffffff,%eax
L24:
  mov    %eax,-0x18(%rbp)
  cmpl   $0x0,-0x18(%rbp)
  jne    L12
  mov    -0x38(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    $0x0,%eax
  call   <setsid@plt>
  mov    D24(%rip),%rax
  mov    (%rax),%ecx
  mov    -0x24(%rbp),%eax
  mov    $0x0,%edx
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <ioctl@plt>
  mov    -0x24(%rbp),%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  mov    -0x24(%rbp),%eax
  mov    $0x1,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  mov    -0x24(%rbp),%eax
  mov    $0x2,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  mov    -0x24(%rbp),%eax
  cmp    $0x2,%eax
  jle    L46
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
L46:
  mov    $0x0,%eax
  jmp    L159
L12:
  movl   $0x0,-0x20(%rbp)
  jmp    L61
L118:
  mov    -0x20(%rbp),%eax
  cltq
  mov    -0x14(%rbp,%rax,4),%eax
  test   %eax,%eax
  je     L114
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
L114:
  addl   $0x1,-0x20(%rbp)
L61:
  cmpl   $0x2,-0x20(%rbp)
  jle    L118
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <close@plt>
  cmpl   $0x0,-0x18(%rbp)
  jns    L177
  mov    -0x38(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <close@plt>
L177:
  mov    -0x18(%rbp),%eax
L159:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L120
  call   <__stack_chk_fail@plt>
L120:
  leave
  ret
```

assistant: ```c
int forkpty(int *m, char *name, const struct termios *tio, const struct winsize *ws) {
  int s, t, i, istmp[3] = {0};
  pid_t pid;
  if (openpty(m, &s, name, tio, ws) < 0)
    return -1;
  for (i = 0; i < 3; i++) {
    if (fcntl(i, F_GETFL) < 0) {
      t = fcntl(s, F_DUPFD, i);
      if (t < 0)
        break;
      else if (t != i)
        close(t);
      else
        istmp[i] = 1;
    }
  }
  pid = i == 3 ? fork() : -1;
  if (!pid) {
    close(*m);
    setsid();
    ioctl(s, TIOCSCTTY, (char *)0);
    dup2(s, 0);
    dup2(s, 1);
    dup2(s, 2);
    if (s > 2)
      close(s);
    return 0;
  }
  for (i = 0; i < 3; i++)
    if (istmp[i])
      close(i);
  close(s);
  if (pid < 0)
    close(*m);
  return pid;
}
```