// File: /workspace/github_c_makefile_star2_O2/justy989[P]ce/ce_app.c
// Function: run_shell_command_and_output_to_buffer
static void* run_shell_command_and_output_to_buffer(void* data){
     ShellCommandData_t* shell_command_data = (ShellCommandData_t*)(data);

     CeSubprocess_t subprocess;
     bool use_shell = true;
     if(!ce_subprocess_open(&subprocess, shell_command_data->command, CE_PROC_COMM_STDOUT, use_shell)){
          ce_log("failed to run shell command '%s': '%s'", shell_command_data->command, strerror(errno));
          pthread_exit(NULL);
     }

     *shell_command_data->should_scroll = true;

     RunShellCommandCleanup_t cleanup = {shell_command_data, &subprocess};
     int rc = 0;

     char bytes[BUFSIZ];
     snprintf(bytes, BUFSIZ, "pid %d started: '%s'\n\n", subprocess.pid, shell_command_data->command);
     ce_buffer_insert_string(shell_command_data->buffer, bytes, ce_buffer_end_point(shell_command_data->buffer));

     int stdout_fd = fileno(subprocess.stdout_file);
     int flags = fcntl(stdout_fd, F_GETFL, 0);
     fcntl(stdout_fd, F_SETFL, flags | O_NONBLOCK);

     while(true){
          if(g_shell_command_should_die){
               run_shell_command_cleanup(&cleanup);
               return NULL;
          }

          int64_t bytes_read = ce_subprocess_read_stdout(&subprocess, bytes, BUFSIZ - 1);
          if(bytes_read > 0){
               bytes[bytes_read] = 0;

               // sanitize bytes for non-printable characters
               for(int i = 0; i < bytes_read; i++){
                   if(bytes[i] < 32 && bytes[i] != '\n') bytes[i] = '?';
               }

               CePoint_t end = ce_buffer_advance_point(shell_command_data->buffer, ce_buffer_end_point(shell_command_data->buffer), 1);
               ce_buffer_insert_string(shell_command_data->buffer, bytes, end);
#if defined(DISPLAY_TERMINAL)
               do{
                    bytes_read = write(g_shell_command_ready_fds[1], "1", 2);
               }while(bytes_read == -1 && errno == EINTR);
#endif

               if(bytes_read < 0){
                    ce_log("%s() write() to terminal ready fd failed: %s", __FUNCTION__, strerror(errno));
                    run_shell_command_cleanup(&cleanup);
                    return NULL;
               }
          }else if(bytes_read < 0){
               if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR){
                    usleep(1000);
               }else{
                    break;
               }
          }else{
               break;
          }
     }

     if(ferror(subprocess.stdout_file)){
          ce_log("shell command: fgets() from pid %d failed\n", subprocess.pid);
          run_shell_command_cleanup(&cleanup);
          return NULL;
     }

     int status = ce_subprocess_close(&subprocess);

     if(WIFEXITED(status)){
          snprintf(bytes, BUFSIZ, "\npid %d exited with code %d", subprocess.pid, WEXITSTATUS(status));
     }else if(WIFSIGNALED(status)){
          snprintf(bytes, BUFSIZ, "\npid %d killed by signal %d", subprocess.pid, WTERMSIG(status));
     }else if(WIFSTOPPED(status)){
          snprintf(bytes, BUFSIZ, "\npid %d stopped by signal %d", subprocess.pid, WSTOPSIG(status));
     }else{
          snprintf(bytes, BUFSIZ, "\npid %d stopped with unexpected status %d", subprocess.pid, status);
     }

     CePoint_t end = ce_buffer_advance_point(shell_command_data->buffer, ce_buffer_end_point(shell_command_data->buffer), 1);
     ce_buffer_insert_string(shell_command_data->buffer, bytes, end);
     shell_command_data->buffer->status = CE_BUFFER_STATUS_READONLY;
#if defined(DISPLAY_TERMINAL)
     do{
          rc = write(g_shell_command_ready_fds[1], "1", 2);
     }while(rc == -1 && errno == EINTR);
#endif

     if(rc < 0){
          ce_log("%s() write() to terminal ready fd failed: %s", __FUNCTION__, strerror(errno));
          run_shell_command_cleanup(&cleanup);
          return NULL;
     }

     run_shell_command_cleanup(&cleanup);
     return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2038, %rsp           # imm = 0x2038
movq %rdi, %rbx
movq 0x8(%rdi), %rsi
movq %rsp, %r14
pushq $0x2
popq %rdx
pushq $0x1
popq %rcx
movq %r14, %rdi
callq 0x1d791
testb %al, %al
je 0x13ff5
movq 0x10(%rbx), %rax
movb $0x1, (%rax)
movq %rbx, 0x20(%rsp)
movq %r14, 0x28(%rsp)
movl (%rsp), %ecx
movq 0x8(%rbx), %r8
leaq 0x18164(%rip), %rdx     # 0x2bedc
leaq 0x30(%rsp), %r15
movl $0x2000, %esi           # imm = 0x2000
movq %r15, %rdi
xorl %eax, %eax
callq 0xd260
movq (%rbx), %r12
movq %r12, %rdi
callq 0xd9cc
movq %rdx, %rcx
movq %r12, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0xd9ef
movq 0x8(%rsp), %rdi
callq 0xd460
movl %eax, %ebp
pushq $0x3
popq %rsi
movl %eax, %edi
xorl %edx, %edx
xorl %eax, %eax
callq 0xd1b0
orl $0x800, %eax            # imm = 0x800
pushq $0x4
popq %rsi
movl %ebp, %edi
movl %eax, %edx
xorl %eax, %eax
callq 0xd1b0
leaq 0x18117(%rip), %r13     # 0x2bef3
pushq $0x2
popq %rbp
cmpb $0x0, 0x27d1a(%rip)     # 0x3bb00
jne 0x13fce
movl $0x1fff, %edx           # imm = 0x1FFF
movq %r14, %rdi
movq %r15, %rsi
callq 0x1d9db
testq %rax, %rax
jle 0x13e7d
movb $0x0, 0x30(%rsp,%rax)
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x13e2d
movb 0x30(%rsp,%rcx), %dl
cmpb $0x20, %dl
setge %sil
cmpb $0xa, %dl
sete %dl
orb %sil, %dl
jne 0x13e28
movb $0x3f, 0x30(%rsp,%rcx)
incq %rcx
jmp 0x13e08
movq (%rbx), %r12
movq %r12, %rdi
callq 0xd9cc
movq %r12, %rdi
movq %rax, %rsi
pushq $0x1
popq %rcx
callq 0xec3a
movq %rdx, %rcx
movq (%rbx), %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0xd9ef
movl 0x27cab(%rip), %edi     # 0x3bb08
movq %r13, %rsi
movq %rbp, %rdx
callq 0xd1d0
cmpq $-0x1, %rax
jne 0x13e9f
callq 0xd0a0
cmpl $0x4, (%rax)
je 0x13e57
jmp 0x13faf
jns 0x13eb2
callq 0xd0a0
movl (%rax), %eax
cmpl $0xb, %eax
je 0x13e90
cmpl $0x4, %eax
jne 0x13eb2
movl $0x3e8, %edi            # imm = 0x3E8
callq 0xd740
jmp 0x13ddf
testq %rax, %rax
jns 0x13ddf
callq 0xd0a0
jmp 0x13faf
movq 0x8(%rsp), %rdi
callq 0xd130
testl %eax, %eax
je 0x13ed6
movl (%rsp), %esi
leaq 0x1807f(%rip), %rdi     # 0x2bf49
xorl %eax, %eax
callq 0xd8e5
jmp 0x13fce
movq %rsp, %rdi
callq 0x1d934
movl %eax, %r8d
andl $0x7f, %r8d
je 0x13f11
movl %r8d, %ecx
shll $0x18, %ecx
addl $0x1000000, %ecx        # imm = 0x1000000
cmpl $0x2000000, %ecx        # imm = 0x2000000
jl 0x13f20
movl (%rsp), %ecx
leaq 0x1808b(%rip), %rdx     # 0x2bf90
leaq 0x30(%rsp), %rdi
movl $0x2000, %esi           # imm = 0x2000
jmp 0x13f47
movl (%rsp), %ecx
movzbl %ah, %eax
leaq 0x18056(%rip), %rdx     # 0x2bf74
jmp 0x13f3a
movl (%rsp), %ecx
cmpb $0x7f, %al
jne 0x13f33
movzbl %ah, %eax
leaq 0x1807b(%rip), %rdx     # 0x2bfac
jmp 0x13f3a
leaq 0x1808f(%rip), %rdx     # 0x2bfc9
leaq 0x30(%rsp), %rdi
movl $0x2000, %esi           # imm = 0x2000
movl %eax, %r8d
xorl %eax, %eax
callq 0xd260
movq (%rbx), %r14
movq %r14, %rdi
callq 0xd9cc
pushq $0x1
popq %rcx
movq %r14, %rdi
movq %rax, %rsi
callq 0xec3a
movq %rdx, %rcx
movq (%rbx), %rdi
leaq 0x30(%rsp), %rsi
movq %rax, %rdx
callq 0xd9ef
movq (%rbx), %rax
movl $0x2, 0x18(%rax)
leaq 0x17f68(%rip), %rbx     # 0x2bef3
pushq $0x2
popq %r14
movl 0x27b73(%rip), %edi     # 0x3bb08
movq %rbx, %rsi
movq %r14, %rdx
callq 0xd1d0
cmpl $-0x1, %eax
jne 0x13fec
callq 0xd0a0
cmpl $0x4, (%rax)
je 0x13f8f
movl (%rax), %edi
callq 0xd650
leaq 0x17f38(%rip), %rdi     # 0x2bef5
leaq 0x17f5e(%rip), %rsi     # 0x2bf22
movq %rax, %rdx
xorl %eax, %eax
callq 0xd8e5
leaq 0x20(%rsp), %rdi
callq 0x13bb3
xorl %eax, %eax
addq $0x2038, %rsp           # imm = 0x2038
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testl %eax, %eax
jns 0x13fce
jmp 0x13ea8
movq 0x8(%rbx), %rbx
callq 0xd0a0
movl (%rax), %edi
callq 0xd650
leaq 0x17ea9(%rip), %rdi     # 0x2beb5
movq %rbx, %rsi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd8e5
xorl %edi, %edi
callq 0xd4b0