#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct winsize {
  int dummy;
};
struct termios {
  int dummy;
};
typedef scalar_t__ ssize_t;
typedef int pid_t;
typedef int /*<<< orphan*/ fd_set;

/* Variables and functions */
#define EINTR 128
scalar_t__ FD_ISSET(int, int /*<<< orphan*/ *);
int /*<<< orphan*/ FD_SET(int, int /*<<< orphan*/ *);
int /*<<< orphan*/ FD_ZERO(int /*<<< orphan*/ *);
int O_NOCTTY;
int O_RDWR;
int STDERR_FILENO;
int STDIN_FILENO;
int STDOUT_FILENO;
int /*<<< orphan*/ TCSADRAIN;
int /*<<< orphan*/ TCSANOW;
int /*<<< orphan*/ TIOCGWINSZ;
int /*<<< orphan*/ TIOCSWINSZ;
int WEXITSTATUS(int);
int /*<<< orphan*/ WNOHANG;
int /*<<< orphan*/ close(int);
int /*<<< orphan*/ die(char *);
int dup2(int, int);
int errno;
int /*<<< orphan*/ execvp(char *, char **);
int fork();
int /*<<< orphan*/ grantpt(int);
scalar_t__ init_tty_raw(int, struct termios *);
int ioctl(int, int /*<<< orphan*/, struct winsize *);
int open(char *, int);
char *ptsname(int);
scalar_t__ read(int, char *, int);
int select(int, int /*<<< orphan*/ *, int /*<<< orphan*/ *,
           int /*<<< orphan*/ *, int /*<<< orphan*/ *);
int /*<<< orphan*/ setsid();
scalar_t__ strlen(char *);
int tcgetattr(int, struct termios *);
int tcsetattr(int, int /*<<< orphan*/, struct termios *);
int /*<<< orphan*/ unlockpt(int);
scalar_t__ waitpid(int, int *, int /*<<< orphan*/);
scalar_t__ write(int, char *, scalar_t__);
int run_pty(char **cmd, char *input) {
  struct termios tty_attrs;
  struct winsize ws;
  pid_t child_pid;
  int master;
  int status;
  master = open("/dev/ptmx", O_RDWR | O_NOCTTY);
  if (master == -1)
    die("Unable to open pty master");
  if (tcgetattr(STDIN_FILENO, &tty_attrs) == -1)
    die(NULL);
  if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
    die(NULL);
  child_pid = fork();
  if (child_pid == -1)
    die(NULL);
  if (child_pid == 0) {
    int slave;
    setsid();
    grantpt(master);
    unlockpt(master);
    slave = open(ptsname(master), O_RDWR);
    if (slave == -1)
      die(NULL);
    if (tcsetattr(slave, TCSANOW, &tty_attrs) == -1)
      die(NULL);
    if (ioctl(slave, TIOCSWINSZ, &ws) == -1)
      die(NULL);
    if (dup2(slave, STDOUT_FILENO) == -1 || dup2(slave, STDIN_FILENO) == -1 ||
        dup2(slave, STDERR_FILENO) == -1)
      die(NULL);
    close(slave);
    execvp(cmd[0], cmd);
    die(NULL);
  } else {
    char buf[256];
    char buf2[256];
    ssize_t bytes_read;
    fd_set input_fd_set;
    if (init_tty_raw(STDIN_FILENO, &tty_attrs) != 0)
      die(NULL);
    if (input != NULL)
      if (write(master, input, strlen(input)) != strlen(input))
        die(NULL);
    while (1) {
      FD_ZERO(&input_fd_set);
      FD_SET(STDIN_FILENO, &input_fd_set);
      FD_SET(master, &input_fd_set);
      if (select(master + 1, &input_fd_set, NULL, NULL, NULL) == -1) {
        switch (errno) {
        case EINTR:
          break;
        default:
          die(NULL);
          break;
        }
      }
      if (FD_ISSET(STDIN_FILENO, &input_fd_set)) {
        bytes_read = read(STDIN_FILENO, buf2, 256);
        if (bytes_read > 0) {
          if (write(master, buf2, bytes_read) != bytes_read)
            die(NULL);
        }
      }
      if (FD_ISSET(master, &input_fd_set)) {
        bytes_read = read(master, buf, 256);
        if (bytes_read > 0) {
          if (write(STDOUT_FILENO, buf, bytes_read) != bytes_read)
            die(NULL);
        }
      }
      if (waitpid(child_pid, &status, WNOHANG) > 0)
        break;
    }
    close(master);
    if (tcsetattr(STDIN_FILENO, TCSADRAIN, &tty_attrs) == -1)
      die(NULL);
  }
  return WEXITSTATUS(status);
}


x86 assembly (clang, -O0):
<run_pty>:
push   %rbp
mov    %rsp,%rbp
sub    $0x260,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    0x2d56(%rip),%rax
mov    (%rax),%esi
mov    0x2d25(%rip),%rax
or     (%rax),%esi
lea    0xd64(%rip),%rdi
call   1140 <open@plt>
mov    %eax,-0x28(%rbp)
cmpl   $0xffffffff,-0x28(%rbp)
jne    12ba <run_pty+0x4a>
lea    0xd55(%rip),%rdi
call   1150 <die@plt>
mov    0x2cd7(%rip),%rax
mov    (%rax),%edi
lea    -0x18(%rbp),%rsi
call   1120 <tcgetattr@plt>
cmp    $0xffffffff,%eax
jne    12de <run_pty+0x6e>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
mov    0x2cb3(%rip),%rax
mov    (%rax),%edi
mov    0x2c9a(%rip),%rax
mov    (%rax),%esi
lea    -0x20(%rbp),%rdx
call   1080 <ioctl@plt>
cmp    $0x0,%eax
jge    130b <run_pty+0x9b>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
mov    $0x0,%al
call   1190 <fork@plt>
mov    %eax,-0x24(%rbp)
cmpl   $0xffffffff,-0x24(%rbp)
jne    1328 <run_pty+0xb8>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
cmpl   $0x0,-0x24(%rbp)
jne    1443 <run_pty+0x1d3>
mov    $0x0,%al
call   10a0 <setsid@plt>
mov    -0x28(%rbp),%edi
call   1170 <grantpt@plt>
mov    -0x28(%rbp),%edi
call   10c0 <unlockpt@plt>
mov    -0x28(%rbp),%edi
call   1030 <ptsname@plt>
mov    %rax,%rdi
mov    0x2c85(%rip),%rax
mov    (%rax),%esi
call   1140 <open@plt>
mov    %eax,-0x30(%rbp)
cmpl   $0xffffffff,-0x30(%rbp)
jne    1378 <run_pty+0x108>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
mov    -0x30(%rbp),%edi
mov    0x2c56(%rip),%rax
mov    (%rax),%esi
lea    -0x18(%rbp),%rdx
call   1130 <tcsetattr@plt>
cmp    $0xffffffff,%eax
jne    139f <run_pty+0x12f>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
mov    -0x30(%rbp),%edi
mov    0x2c1f(%rip),%rax
mov    (%rax),%esi
lea    -0x20(%rbp),%rdx
call   1080 <ioctl@plt>
cmp    $0xffffffff,%eax
jne    13c6 <run_pty+0x156>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
mov    -0x30(%rbp),%edi
mov    0x2c20(%rip),%rax
mov    (%rax),%esi
call   1070 <dup2@plt>
cmp    $0xffffffff,%eax
je     1414 <run_pty+0x1a4>
mov    -0x30(%rbp),%edi
mov    0x2bae(%rip),%rax
mov    (%rax),%esi
call   1070 <dup2@plt>
cmp    $0xffffffff,%eax
je     1414 <run_pty+0x1a4>
mov    -0x30(%rbp),%edi
mov    0x2b9c(%rip),%rax
mov    (%rax),%esi
call   1070 <dup2@plt>
cmp    $0xffffffff,%eax
jne    141d <run_pty+0x1ad>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
mov    -0x30(%rbp),%edi
call   1090 <close@plt>
mov    -0x8(%rbp),%rax
mov    (%rax),%rdi
mov    -0x8(%rbp),%rsi
call   1160 <execvp@plt>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
jmp    16c2 <run_pty+0x452>
mov    0x2b4e(%rip),%rax
mov    (%rax),%edi
lea    -0x18(%rbp),%rsi
call   10f0 <init_tty_raw@plt>
cmp    $0x0,%rax
je     1468 <run_pty+0x1f8>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
cmpq   $0x0,-0x10(%rbp)
je     14d6 <run_pty+0x266>
mov    -0x28(%rbp),%eax
mov    %eax,-0x254(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x250(%rbp)
mov    -0x10(%rbp),%rdi
call   1060 <strlen@plt>
mov    -0x254(%rbp),%edi
mov    -0x250(%rbp),%rsi
mov    %rax,%rdx
call   1040 <write@plt>
mov    %rax,-0x248(%rbp)
mov    -0x10(%rbp),%rdi
call   1060 <strlen@plt>
mov    %rax,%rcx
mov    -0x248(%rbp),%rax
cmp    %rcx,%rax
je     14d1 <run_pty+0x261>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
jmp    14d6 <run_pty+0x266>
jmp    14db <run_pty+0x26b>
lea    -0x23c(%rbp),%rdi
call   10d0 <FD_ZERO@plt>
mov    0x2aaa(%rip),%rax
mov    (%rax),%edi
lea    -0x23c(%rbp),%rsi
call   1180 <FD_SET@plt>
mov    -0x28(%rbp),%edi
lea    -0x23c(%rbp),%rsi
call   1180 <FD_SET@plt>
mov    -0x28(%rbp),%edi
add    $0x1,%edi
lea    -0x23c(%rbp),%rsi
xor    %eax,%eax
mov    %eax,%r8d
mov    %r8,%rdx
mov    %r8,%rcx
call   10e0 <select@plt>
cmp    $0xffffffff,%eax
jne    155d <run_pty+0x2ed>
mov    0x2a70(%rip),%rax
mov    (%rax),%eax
sub    $0x80,%eax
jne    154f <run_pty+0x2df>
jmp    154a <run_pty+0x2da>
jmp    1558 <run_pty+0x2e8>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
jmp    155d <run_pty+0x2ed>
mov    0x2a34(%rip),%rax
mov    (%rax),%edi
lea    -0x23c(%rbp),%rsi
call   1050 <FD_ISSET@plt>
cmp    $0x0,%rax
je     15e1 <run_pty+0x371>
mov    0x2a15(%rip),%rax
mov    (%rax),%edi
lea    -0x230(%rbp),%rsi
mov    $0x100,%edx
call   10b0 <read@plt>
mov    %rax,-0x238(%rbp)
cmpq   $0x0,-0x238(%rbp)
jle    15dc <run_pty+0x36c>
mov    -0x28(%rbp),%edi
lea    -0x230(%rbp),%rsi
mov    -0x238(%rbp),%rdx
call   1040 <write@plt>
cmp    -0x238(%rbp),%rax
je     15d7 <run_pty+0x367>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
jmp    15dc <run_pty+0x36c>
jmp    15e1 <run_pty+0x371>
mov    -0x28(%rbp),%edi
lea    -0x23c(%rbp),%rsi
call   1050 <FD_ISSET@plt>
cmp    $0x0,%rax
je     165f <run_pty+0x3ef>
mov    -0x28(%rbp),%edi
lea    -0x130(%rbp),%rsi
mov    $0x100,%edx
call   10b0 <read@plt>
mov    %rax,-0x238(%rbp)
cmpq   $0x0,-0x238(%rbp)
jle    165a <run_pty+0x3ea>
mov    0x29c6(%rip),%rax
mov    (%rax),%edi
lea    -0x130(%rbp),%rsi
mov    -0x238(%rbp),%rdx
call   1040 <write@plt>
cmp    -0x238(%rbp),%rax
je     1655 <run_pty+0x3e5>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
jmp    165a <run_pty+0x3ea>
jmp    165f <run_pty+0x3ef>
mov    -0x24(%rbp),%edi
mov    0x2967(%rip),%rax
mov    (%rax),%edx
lea    -0x2c(%rbp),%rsi
call   1110 <waitpid@plt>
cmp    $0x0,%rax
jle    1683 <run_pty+0x413>
jmp    1688 <run_pty+0x418>
jmp    14db <run_pty+0x26b>
mov    -0x28(%rbp),%edi
call   1090 <close@plt>
mov    0x2901(%rip),%rax
mov    (%rax),%edi
mov    0x2910(%rip),%rax
mov    (%rax),%esi
lea    -0x18(%rbp),%rdx
call   1130 <tcsetattr@plt>
cmp    $0xffffffff,%eax
jne    16bd <run_pty+0x44d>
xor    %eax,%eax
mov    %eax,%edi
call   1150 <die@plt>
jmp    16c2 <run_pty+0x452>
mov    -0x2c(%rbp),%edi
call   1100 <WEXITSTATUS@plt>
add    $0x260,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<run_pty>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x228,%rsp
mov    %rsi,%r13
mov    %rdi,%r12
mov    0x2d52(%rip),%rbp
mov    0x2d23(%rip),%rax
mov    (%rax),%esi
or     0x0(%rbp),%esi
lea    0xd5f(%rip),%rdi
call   1140 <open@plt>
mov    %eax,%r14d
cmp    $0xffffffff,%eax
jne    12ba <run_pty+0x4a>
lea    0xd55(%rip),%rdi
call   1150 <die@plt>
mov    0x2cd7(%rip),%rbx
mov    (%rbx),%edi
lea    0x8(%rsp),%rsi
call   1120 <tcgetattr@plt>
cmp    $0xffffffff,%eax
jne    12d9 <run_pty+0x69>
xor    %edi,%edi
call   1150 <die@plt>
mov    (%rbx),%edi
mov    0x2ca6(%rip),%rax
mov    (%rax),%esi
lea    0x10(%rsp),%rdx
call   1080 <ioctl@plt>
test   %eax,%eax
jns    12f9 <run_pty+0x89>
xor    %edi,%edi
call   1150 <die@plt>
xor    %eax,%eax
call   1190 <fork@plt>
mov    %eax,%r15d
cmp    $0xffffffff,%eax
jne    1311 <run_pty+0xa1>
xor    %edi,%edi
call   1150 <die@plt>
jmp    131a <run_pty+0xaa>
test   %r15d,%r15d
je     14e7 <run_pty+0x277>
mov    (%rbx),%edi
lea    0x8(%rsp),%rsi
call   10f0 <init_tty_raw@plt>
test   %rax,%rax
je     1332 <run_pty+0xc2>
xor    %edi,%edi
call   1150 <die@plt>
test   %r13,%r13
je     1364 <run_pty+0xf4>
mov    %r13,%rdi
call   1060 <strlen@plt>
mov    %r14d,%edi
mov    %r13,%rsi
mov    %rax,%rdx
call   1040 <write@plt>
mov    %rax,%rbp
mov    %r13,%rdi
call   1060 <strlen@plt>
cmp    %rax,%rbp
je     1364 <run_pty+0xf4>
xor    %edi,%edi
call   1150 <die@plt>
mov    %r14d,%r12d
add    $0x1,%r12d
lea    0x1c(%rsp),%rbp
jmp    13a6 <run_pty+0x136>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    0x2c49(%rip),%rax
mov    (%rax),%edx
mov    %r15d,%edi
lea    0x18(%rsp),%rsi
call   1110 <waitpid@plt>
test   %rax,%rax
mov    0x2bf8(%rip),%rbx
jg     14a3 <run_pty+0x233>
mov    %rbp,%rdi
call   10d0 <FD_ZERO@plt>
mov    (%rbx),%edi
mov    %rbp,%rsi
call   1180 <FD_SET@plt>
mov    %r14d,%edi
mov    %rbp,%rsi
call   1180 <FD_SET@plt>
mov    %r12d,%edi
mov    %rbp,%rsi
xor    %edx,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
call   10e0 <select@plt>
cmp    $0xffffffff,%eax
jne    13f0 <run_pty+0x180>
mov    0x2bc7(%rip),%rax
cmpl   $0x80,(%rax)
je     13f0 <run_pty+0x180>
xor    %edi,%edi
call   1150 <die@plt>
mov    (%rbx),%edi
mov    %rbp,%rsi
call   1050 <FD_ISSET@plt>
test   %rax,%rax
je     1440 <run_pty+0x1d0>
mov    (%rbx),%edi
lea    0x20(%rsp),%rsi
mov    $0x100,%edx
call   10b0 <read@plt>
test   %rax,%rax
jle    1440 <run_pty+0x1d0>
mov    %rax,%rbx
mov    %r14d,%edi
lea    0x20(%rsp),%rsi
mov    %rax,%rdx
call   1040 <write@plt>
cmp    %rbx,%rax
je     1440 <run_pty+0x1d0>
xor    %edi,%edi
call   1150 <die@plt>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    %r14d,%edi
mov    %rbp,%rsi
call   1050 <FD_ISSET@plt>
test   %rax,%rax
je     1380 <run_pty+0x110>
mov    %r14d,%edi
lea    0x120(%rsp),%rsi
mov    $0x100,%edx
call   10b0 <read@plt>
test   %rax,%rax
jle    1380 <run_pty+0x110>
mov    %rax,%r13
mov    0x2b74(%rip),%rax
mov    (%rax),%edi
lea    0x120(%rsp),%rsi
mov    %r13,%rdx
call   1040 <write@plt>
cmp    %r13,%rax
je     1380 <run_pty+0x110>
xor    %edi,%edi
call   1150 <die@plt>
jmp    1380 <run_pty+0x110>
mov    %r14d,%edi
call   1090 <close@plt>
mov    (%rbx),%edi
mov    0x2afc(%rip),%rax
mov    (%rax),%esi
lea    0x8(%rsp),%rdx
call   1130 <tcsetattr@plt>
cmp    $0xffffffff,%eax
jne    14cc <run_pty+0x25c>
xor    %edi,%edi
call   1150 <die@plt>
mov    0x18(%rsp),%edi
call   1100 <WEXITSTATUS@plt>
add    $0x228,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
xor    %eax,%eax
call   10a0 <setsid@plt>
mov    %r14d,%edi
call   1170 <grantpt@plt>
mov    %r14d,%edi
call   10c0 <unlockpt@plt>
mov    %r14d,%edi
call   1030 <ptsname@plt>
mov    0x0(%rbp),%esi
mov    %rax,%rdi
call   1140 <open@plt>
mov    %eax,%ebp
cmp    $0xffffffff,%eax
jne    151f <run_pty+0x2af>
xor    %edi,%edi
call   1150 <die@plt>
mov    0x2ab2(%rip),%rax
mov    (%rax),%esi
lea    0x8(%rsp),%rdx
mov    %ebp,%edi
call   1130 <tcsetattr@plt>
cmp    $0xffffffff,%eax
jne    1540 <run_pty+0x2d0>
xor    %edi,%edi
call   1150 <die@plt>
mov    0x2a81(%rip),%rax
mov    (%rax),%esi
lea    0x10(%rsp),%rdx
mov    %ebp,%edi
call   1080 <ioctl@plt>
cmp    $0xffffffff,%eax
jne    1561 <run_pty+0x2f1>
xor    %edi,%edi
call   1150 <die@plt>
mov    0x2a88(%rip),%rax
mov    (%rax),%esi
mov    %ebp,%edi
call   1070 <dup2@plt>
cmp    $0xffffffff,%eax
je     15a0 <run_pty+0x330>
mov    0x2a1b(%rip),%rax
mov    (%rax),%esi
mov    %ebp,%edi
call   1070 <dup2@plt>
cmp    $0xffffffff,%eax
je     15a0 <run_pty+0x330>
mov    0x2a0e(%rip),%rax
mov    (%rax),%esi
mov    %ebp,%edi
call   1070 <dup2@plt>
cmp    $0xffffffff,%eax
jne    15a7 <run_pty+0x337>
xor    %edi,%edi
call   1150 <die@plt>
mov    %ebp,%edi
call   1090 <close@plt>
mov    (%r12),%rdi
mov    %r12,%rsi
call   1160 <execvp@plt>
xor    %edi,%edi
call   1150 <die@plt>

LLVM IR (-O0):
%struct.termios = type { i32 }
%struct.winsize = type { i32 }
@.str = [10 x i8] c"/dev/ptmx\00"
@O_RDWR = global i32 0
@O_NOCTTY = global i32 0
@.str.1 = [26 x i8] c"Unable to open pty master\00"
@STDIN_FILENO = global i32 0
@TIOCGWINSZ = global i32 0
@TCSANOW = global i32 0
@TIOCSWINSZ = global i32 0
@STDOUT_FILENO = global i32 0
@STDERR_FILENO = global i32 0
@errno = global i32 0
@WNOHANG = global i32 0
@TCSADRAIN = global i32 0
define i32 @run_pty(i8** %0, i8* %1) {
%3 = alloca i8**
%4 = alloca i8*
%5 = alloca %struct.termios
%6 = alloca %struct.winsize
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca [256 x i8]
%12 = alloca [256 x i8]
%13 = alloca i64
%14 = alloca i32
store i8** %0, i8*** %3
store i8* %1, i8** %4
%15 = load i32, i32* @O_RDWR
%16 = load i32, i32* @O_NOCTTY
%17 = or i32 %15, %16
%18 = call i32 @open(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 %17)
store i32 %18, i32* %8
%19 = load i32, i32* %8
%20 = icmp eq i32 %19, -1
br i1 %20, label %21, label %23
21: ; preds = %2
%22 = call i32 @die(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0))
br label %23
23: ; preds = %21, %2
%24 = load i32, i32* @STDIN_FILENO
%25 = call i32 @tcgetattr(i32 %24, %struct.termios* %5)
%26 = icmp eq i32 %25, -1
br i1 %26, label %27, label %29
27: ; preds = %23
%28 = call i32 @die(i8* null)
br label %29
29: ; preds = %27, %23
%30 = load i32, i32* @STDIN_FILENO
%31 = load i32, i32* @TIOCGWINSZ
%32 = call i32 @ioctl(i32 %30, i32 %31, %struct.winsize* %6)
%33 = icmp slt i32 %32, 0
br i1 %33, label %34, label %36
34: ; preds = %29
%35 = call i32 @die(i8* null)
br label %36
36: ; preds = %34, %29
%37 = call i32 (...) @fork()
store i32 %37, i32* %7
%38 = load i32, i32* %7
%39 = icmp eq i32 %38, -1
br i1 %39, label %40, label %42
40: ; preds = %36
%41 = call i32 @die(i8* null)
br label %42
42: ; preds = %40, %36
%43 = load i32, i32* %7
%44 = icmp eq i32 %43, 0
br i1 %44, label %45, label %99
45: ; preds = %42
%46 = call i32 (...) @setsid()
%47 = load i32, i32* %8
%48 = call i32 @grantpt(i32 %47)
%49 = load i32, i32* %8
%50 = call i32 @unlockpt(i32 %49)
%51 = load i32, i32* %8
%52 = call i8* @ptsname(i32 %51)
%53 = load i32, i32* @O_RDWR
%54 = call i32 @open(i8* %52, i32 %53)
store i32 %54, i32* %10
%55 = load i32, i32* %10
%56 = icmp eq i32 %55, -1
br i1 %56, label %57, label %59
57: ; preds = %45
%58 = call i32 @die(i8* null)
br label %59
59: ; preds = %57, %45
%60 = load i32, i32* %10
%61 = load i32, i32* @TCSANOW
%62 = call i32 @tcsetattr(i32 %60, i32 %61, %struct.termios* %5)
%63 = icmp eq i32 %62, -1
br i1 %63, label %64, label %66
64: ; preds = %59
%65 = call i32 @die(i8* null)
br label %66
66: ; preds = %64, %59
%67 = load i32, i32* %10
%68 = load i32, i32* @TIOCSWINSZ
%69 = call i32 @ioctl(i32 %67, i32 %68, %struct.winsize* %6)
%70 = icmp eq i32 %69, -1
br i1 %70, label %71, label %73
71: ; preds = %66
%72 = call i32 @die(i8* null)
br label %73
73: ; preds = %71, %66
%74 = load i32, i32* %10
%75 = load i32, i32* @STDOUT_FILENO
%76 = call i32 @dup2(i32 %74, i32 %75)
%77 = icmp eq i32 %76, -1
br i1 %77, label %88, label %78
78: ; preds = %73
%79 = load i32, i32* %10
%80 = load i32, i32* @STDIN_FILENO
%81 = call i32 @dup2(i32 %79, i32 %80)
%82 = icmp eq i32 %81, -1
br i1 %82, label %88, label %83
83: ; preds = %78
%84 = load i32, i32* %10
%85 = load i32, i32* @STDERR_FILENO
%86 = call i32 @dup2(i32 %84, i32 %85)
%87 = icmp eq i32 %86, -1
br i1 %87, label %88, label %90
88: ; preds = %83, %78, %73
%89 = call i32 @die(i8* null)
br label %90
90: ; preds = %88, %83
%91 = load i32, i32* %10
%92 = call i32 @close(i32 %91)
%93 = load i8**, i8*** %3
%94 = getelementptr inbounds i8*, i8** %93, i64 0
%95 = load i8*, i8** %94
%96 = load i8**, i8*** %3
%97 = call i32 @execvp(i8* %95, i8** %96)
%98 = call i32 @die(i8* null)
br label %196
99: ; preds = %42
%100 = load i32, i32* @STDIN_FILENO
%101 = call i64 @init_tty_raw(i32 %100, %struct.termios* %5)
%102 = icmp ne i64 %101, 0
br i1 %102, label %103, label %105
103: ; preds = %99
%104 = call i32 @die(i8* null)
br label %105
105: ; preds = %103, %99
%106 = load i8*, i8** %4
%107 = icmp ne i8* %106, null
br i1 %107, label %108, label %120
108: ; preds = %105
%109 = load i32, i32* %8
%110 = load i8*, i8** %4
%111 = load i8*, i8** %4
%112 = call i64 @strlen(i8* %111)
%113 = call i64 @write(i32 %109, i8* %110, i64 %112)
%114 = load i8*, i8** %4
%115 = call i64 @strlen(i8* %114)
%116 = icmp ne i64 %113, %115
br i1 %116, label %117, label %119
117: ; preds = %108
%118 = call i32 @die(i8* null)
br label %119
119: ; preds = %117, %108
br label %120
120: ; preds = %119, %105
br label %121
121: ; preds = %120, %185
%122 = call i32 @FD_ZERO(i32* %14)
%123 = load i32, i32* @STDIN_FILENO
%124 = call i32 @FD_SET(i32 %123, i32* %14)
%125 = load i32, i32* %8
%126 = call i32 @FD_SET(i32 %125, i32* %14)
%127 = load i32, i32* %8
%128 = add nsw i32 %127, 1
%129 = call i32 @select(i32 %128, i32* %14, i32* null, i32* null, i32* null)
%130 = icmp eq i32 %129, -1
br i1 %130, label %131, label %137
131: ; preds = %121
%132 = load i32, i32* @errno
switch i32 %132, label %134 [
i32 128, label %133
]
133: ; preds = %131
br label %136
134: ; preds = %131
%135 = call i32 @die(i8* null)
br label %136
136: ; preds = %134, %133
br label %137
137: ; preds = %136, %121
%138 = load i32, i32* @STDIN_FILENO
%139 = call i64 @FD_ISSET(i32 %138, i32* %14)
%140 = icmp ne i64 %139, 0
br i1 %140, label %141, label %158
141: ; preds = %137
%142 = load i32, i32* @STDIN_FILENO
%143 = getelementptr inbounds [256 x i8], [256 x i8]* %12, i64 0, i64 0
%144 = call i64 @read(i32 %142, i8* %143, i32 256)
store i64 %144, i64* %13
%145 = load i64, i64* %13
%146 = icmp sgt i64 %145, 0
br i1 %146, label %147, label %157
147: ; preds = %141
%148 = load i32, i32* %8
%149 = getelementptr inbounds [256 x i8], [256 x i8]* %12, i64 0, i64 0
%150 = load i64, i64* %13
%151 = call i64 @write(i32 %148, i8* %149, i64 %150)
%152 = load i64, i64* %13
%153 = icmp ne i64 %151, %152
br i1 %153, label %154, label %156
154: ; preds = %147
%155 = call i32 @die(i8* null)
br label %156
156: ; preds = %154, %147
br label %157
157: ; preds = %156, %141
br label %158
158: ; preds = %157, %137
%159 = load i32, i32* %8
%160 = call i64 @FD_ISSET(i32 %159, i32* %14)
%161 = icmp ne i64 %160, 0
br i1 %161, label %162, label %179
162: ; preds = %158
%163 = load i32, i32* %8
%164 = getelementptr inbounds [256 x i8], [256 x i8]* %11, i64 0, i64 0
%165 = call i64 @read(i32 %163, i8* %164, i32 256)
store i64 %165, i64* %13
%166 = load i64, i64* %13
%167 = icmp sgt i64 %166, 0
br i1 %167, label %168, label %178
168: ; preds = %162
%169 = load i32, i32* @STDOUT_FILENO
%170 = getelementptr inbounds [256 x i8], [256 x i8]* %11, i64 0, i64 0
%171 = load i64, i64* %13
%172 = call i64 @write(i32 %169, i8* %170, i64 %171)
%173 = load i64, i64* %13
%174 = icmp ne i64 %172, %173
br i1 %174, label %175, label %177
175: ; preds = %168
%176 = call i32 @die(i8* null)
br label %177
177: ; preds = %175, %168
br label %178
178: ; preds = %177, %162
br label %179
179: ; preds = %178, %158
%180 = load i32, i32* %7
%181 = load i32, i32* @WNOHANG
%182 = call i64 @waitpid(i32 %180, i32* %9, i32 %181)
%183 = icmp sgt i64 %182, 0
br i1 %183, label %184, label %185
184: ; preds = %179
br label %186
185: ; preds = %179
br label %121
186: ; preds = %184
%187 = load i32, i32* %8
%188 = call i32 @close(i32 %187)
%189 = load i32, i32* @STDIN_FILENO
%190 = load i32, i32* @TCSADRAIN
%191 = call i32 @tcsetattr(i32 %189, i32 %190, %struct.termios* %5)
%192 = icmp eq i32 %191, -1
br i1 %192, label %193, label %195
193: ; preds = %186
%194 = call i32 @die(i8* null)
br label %195
195: ; preds = %193, %186
br label %196
196: ; preds = %195, %90
%197 = load i32, i32* %9
%198 = call i32 @WEXITSTATUS(i32 %197)
ret i32 %198
}

LLVM IR (-O2):
%struct.termios = type { i32 }
%struct.winsize = type { i32 }
@.str = [10 x i8] c"/dev/ptmx\00"
@O_RDWR = global i32 0
@O_NOCTTY = global i32 0
@.str.1 = [26 x i8] c"Unable to open pty master\00"
@STDIN_FILENO = global i32 0
@TIOCGWINSZ = global i32 0
@TCSANOW = global i32 0
@TIOCSWINSZ = global i32 0
@STDOUT_FILENO = global i32 0
@STDERR_FILENO = global i32 0
@errno = global i32 0
@WNOHANG = global i32 0
@TCSADRAIN = global i32 0
define i32 @run_pty(i8** %0, i8* %1) {
%3 = alloca %struct.termios
%4 = alloca %struct.winsize
%5 = alloca i32
%6 = alloca [256 x i8]
%7 = alloca [256 x i8]
%8 = alloca i32
%9 = bitcast %struct.termios* %3 to i8*
%10 = bitcast %struct.winsize* %4 to i8*
%11 = bitcast i32* %5 to i8*
%12 = load i32, i32* @O_RDWR
%13 = load i32, i32* @O_NOCTTY
%14 = or i32 %13, %12
%15 = tail call i32 @open(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 %14)
%16 = icmp eq i32 %15, -1
br i1 %16, label %17, label %19
17: ; preds = %2
%18 = tail call i32 @die(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0))
br label %19
19: ; preds = %17, %2
%20 = load i32, i32* @STDIN_FILENO
%21 = call i32 @tcgetattr(i32 %20, %struct.termios* %3)
%22 = icmp eq i32 %21, -1
br i1 %22, label %23, label %25
23: ; preds = %19
%24 = call i32 @die(i8* null)
br label %25
25: ; preds = %23, %19
%26 = load i32, i32* @STDIN_FILENO
%27 = load i32, i32* @TIOCGWINSZ
%28 = call i32 @ioctl(i32 %26, i32 %27, %struct.winsize* %4)
%29 = icmp slt i32 %28, 0
br i1 %29, label %30, label %32
30: ; preds = %25
%31 = call i32 @die(i8* null)
br label %32
32: ; preds = %30, %25
%33 = call i32 (...) @fork()
switch i32 %33, label %77 [
i32 -1, label %34
i32 0, label %36
]
34: ; preds = %32
%35 = call i32 @die(i8* null)
br label %77
36: ; preds = %32
%37 = call i32 (...) @setsid()
%38 = call i32 @grantpt(i32 %15)
%39 = call i32 @unlockpt(i32 %15)
%40 = call i8* @ptsname(i32 %15)
%41 = load i32, i32* @O_RDWR
%42 = call i32 @open(i8* %40, i32 %41)
%43 = icmp eq i32 %42, -1
br i1 %43, label %44, label %46
44: ; preds = %36
%45 = call i32 @die(i8* null)
br label %46
46: ; preds = %44, %36
%47 = load i32, i32* @TCSANOW
%48 = call i32 @tcsetattr(i32 %42, i32 %47, %struct.termios* %3)
%49 = icmp eq i32 %48, -1
br i1 %49, label %50, label %52
50: ; preds = %46
%51 = call i32 @die(i8* null)
br label %52
52: ; preds = %50, %46
%53 = load i32, i32* @TIOCSWINSZ
%54 = call i32 @ioctl(i32 %42, i32 %53, %struct.winsize* %4)
%55 = icmp eq i32 %54, -1
br i1 %55, label %56, label %58
56: ; preds = %52
%57 = call i32 @die(i8* null)
br label %58
58: ; preds = %56, %52
%59 = load i32, i32* @STDOUT_FILENO
%60 = call i32 @dup2(i32 %42, i32 %59)
%61 = icmp eq i32 %60, -1
br i1 %61, label %70, label %62
62: ; preds = %58
%63 = load i32, i32* @STDIN_FILENO
%64 = call i32 @dup2(i32 %42, i32 %63)
%65 = icmp eq i32 %64, -1
br i1 %65, label %70, label %66
66: ; preds = %62
%67 = load i32, i32* @STDERR_FILENO
%68 = call i32 @dup2(i32 %42, i32 %67)
%69 = icmp eq i32 %68, -1
br i1 %69, label %70, label %72
70: ; preds = %66, %62, %58
%71 = call i32 @die(i8* null)
br label %72
72: ; preds = %70, %66
%73 = call i32 @close(i32 %42)
%74 = load i8*, i8** %0
%75 = call i32 @execvp(i8* %74, i8** %0)
%76 = call i32 @die(i8* null)
unreachable
77: ; preds = %34, %32
%78 = getelementptr inbounds [256 x i8], [256 x i8]* %6, i64 0, i64 0
%79 = getelementptr inbounds [256 x i8], [256 x i8]* %7, i64 0, i64 0
%80 = bitcast i32* %8 to i8*
%81 = load i32, i32* @STDIN_FILENO
%82 = call i64 @init_tty_raw(i32 %81, %struct.termios* %3)
%83 = icmp eq i64 %82, 0
br i1 %83, label %86, label %84
84: ; preds = %77
%85 = call i32 @die(i8* null)
br label %86
86: ; preds = %84, %77
%87 = icmp eq i8* %1, null
br i1 %87, label %95, label %88
88: ; preds = %86
%89 = call i64 @strlen(i8* %1)
%90 = call i64 @write(i32 %15, i8* %1, i64 %89)
%91 = call i64 @strlen(i8* %1)
%92 = icmp eq i64 %90, %91
br i1 %92, label %95, label %93
93: ; preds = %88
%94 = call i32 @die(i8* null)
br label %95
95: ; preds = %88, %93, %86
%96 = add nsw i32 %15, 1
br label %97
97: ; preds = %134, %95
%98 = call i32 @FD_ZERO(i32* %8)
%99 = load i32, i32* @STDIN_FILENO
%100 = call i32 @FD_SET(i32 %99, i32* %8)
%101 = call i32 @FD_SET(i32 %15, i32* %8)
%102 = call i32 @select(i32 %96, i32* %8, i32* null, i32* null, i32* null)
%103 = icmp ne i32 %102, -1
%104 = load i32, i32* @errno
%105 = icmp eq i32 %104, 128
%106 = select i1 %103, i1 true, i1 %105
br i1 %106, label %109, label %107
107: ; preds = %97
%108 = call i32 @die(i8* null)
br label %109
109: ; preds = %107, %97
%110 = load i32, i32* @STDIN_FILENO
%111 = call i64 @FD_ISSET(i32 %110, i32* %8)
%112 = icmp eq i64 %111, 0
br i1 %112, label %122, label %113
113: ; preds = %109
%114 = load i32, i32* @STDIN_FILENO
%115 = call i64 @read(i32 %114, i8* %79, i32 256)
%116 = icmp sgt i64 %115, 0
br i1 %116, label %117, label %122
117: ; preds = %113
%118 = call i64 @write(i32 %15, i8* %79, i64 %115)
%119 = icmp eq i64 %118, %115
br i1 %119, label %122, label %120
120: ; preds = %117
%121 = call i32 @die(i8* null)
br label %122
122: ; preds = %113, %120, %117, %109
%123 = call i64 @FD_ISSET(i32 %15, i32* %8)
%124 = icmp eq i64 %123, 0
br i1 %124, label %134, label %125
125: ; preds = %122
%126 = call i64 @read(i32 %15, i8* %78, i32 256)
%127 = icmp sgt i64 %126, 0
br i1 %127, label %128, label %134
128: ; preds = %125
%129 = load i32, i32* @STDOUT_FILENO
%130 = call i64 @write(i32 %129, i8* %78, i64 %126)
%131 = icmp eq i64 %130, %126
br i1 %131, label %134, label %132
132: ; preds = %128
%133 = call i32 @die(i8* null)
br label %134
134: ; preds = %125, %132, %128, %122
%135 = load i32, i32* @WNOHANG
%136 = call i64 @waitpid(i32 %33, i32* %5, i32 %135)
%137 = icmp sgt i64 %136, 0
br i1 %137, label %138, label %97
138: ; preds = %134
%139 = call i32 @close(i32 %15)
%140 = load i32, i32* @STDIN_FILENO
%141 = load i32, i32* @TCSADRAIN
%142 = call i32 @tcsetattr(i32 %140, i32 %141, %struct.termios* %3)
%143 = icmp eq i32 %142, -1
br i1 %143, label %144, label %146
144: ; preds = %138
%145 = call i32 @die(i8* null)
br label %146
146: ; preds = %144, %138
%147 = load i32, i32* %5
%148 = call i32 @WEXITSTATUS(i32 %147)
ret i32 %148
}