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

```asm
<launchProcess>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %rcx,-0x40(%rbp)
  mov    %r8,-0x48(%rbp)
  mov    %r9,-0x50(%rbp)
  cmpq   $0x0,0x10(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
  mov    $0x0,%eax
  call   <fork@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  jne    L74
  movl   $0x0,-0x14(%rbp)
  cmpq   $0x0,-0x40(%rbp)
  je     L64
  mov    -0x40(%rbp),%rax
  mov    %rax,%rdi
  call   <chdir@plt>
  test   %rax,%rax
  jns    L64
  mov    $0x7e,%edi
  call   <_exit@plt>
  jmp    L64
L108:
  addl   $0x1,-0x14(%rbp)
L64:
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rdx
  mov    0x18(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  test   %eax,%eax
  jg     L108
  cmpq   $0x0,0x10(%rbp)
  je     L4
  mov    0x10(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  jmp    L89
L4:
  mov    $0x0,%eax
L89:
  mov    -0x50(%rbp),%rdx
  add    $0x4,%rdx
  mov    (%rdx),%esi
  mov    -0x48(%rbp),%rdx
  mov    (%rdx),%edi
  mov    -0x14(%rbp),%ecx
  mov    0x18(%rbp),%rdx
  mov    %ecx,%r8d
  mov    %rdx,%rcx
  mov    %eax,%edx
  call   <closeOtherFds@plt>
  mov    -0x48(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <close@plt>
  mov    -0x50(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <close@plt>
  cmpl   $0x0,-0xc(%rbp)
  jne    L14
  mov    0x10(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <close@plt>
L14:
  mov    $0x0,%edi
  call   <close@plt>
  mov    -0x48(%rbp),%rax
  mov    (%rax),%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  mov    $0x1,%edi
  call   <close@plt>
  mov    -0x50(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  mov    $0x1,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  mov    $0x2,%edi
  call   <close@plt>
  cmpl   $0x0,-0xc(%rbp)
  je     L43
  mov    -0x50(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  jmp    L116
L43:
  mov    0x10(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
L116:
  mov    $0x2,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  movl   $0x0,-0x10(%rbp)
  jmp    L32
L107:
  mov    -0x10(%rbp),%eax
  lea    0x3(%rax),%edx
  mov    -0x10(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rcx
  mov    0x18(%rbp),%rax
  add    %rcx,%rax
  mov    (%rax),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <dup2@plt>
  addl   $0x1,-0x10(%rbp)
L32:
  mov    -0x10(%rbp),%eax
  cmp    -0x14(%rbp),%eax
  jl     L107
  mov    -0x38(%rbp),%rdx
  mov    -0x30(%rbp),%rcx
  mov    -0x28(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <execve@plt>
  mov    $0x1,%edi
  call   <_exit@plt>
L74:
  mov    -0x8(%rbp),%rax
  leave
  ret
```

assistant: ```c
pid_t launchProcess(const char *path, char *const argv[], char *const envp[], const char *workdir, const int fd_in[2], const int fd_out[2], const int fd_err[2], const int dupFds[]) {
  pid_t pid;
  int mergeStderr = (fd_err ? 0 : 1);
  pid = fork();
  if (pid == 0) {
    int countFd = 0;
    int i;
    if (workdir) {
      if (chdir(workdir) < 0) {
        _exit(126);
      }
    }
    while (dupFds[countFd] > 0) {
      ++countFd;
    }
    closeOtherFds(fd_in[0], fd_out[1], fd_err ? fd_err[1] : 0, dupFds, countFd);
    close(fd_in[1]);
    close(fd_out[0]);
    if (!mergeStderr)
      close(fd_err[0]);
    close(0);
    dup2(fd_in[0], 0);
    close(1);
    dup2(fd_out[1], 1);
    close(2);
    dup2(mergeStderr ? fd_out[1] : fd_err[1], 2);
    for (i = 0; i < countFd; i++) {
      dup2(dupFds[i], 3 + i);
    }
    execve(path, argv, envp);
    _exit(1);
  }
  return pid;
}
```