// File: /workspace/github_cpp_makefile_star2_O3/clementino1971[P]ICC065-protoTerminal/protoTerminal.cpp
// Function: recursive_run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, int*)
void recursive_run(vector<string> command, int stdout_pipe[2]=NULL) {
    for(int i = command.size()-1; i>=0; i--) {
        if(command[i]=="&") {
            //aqui é pra rodar o que tiver em args e retornar pro futuro, e chamar um fork pro que rolar antes do &
            int rc = fork();
            if(rc < 0){
                fprintf(stderr, "Erro no fork\n");
                exit(1);
            }else if(rc == 0){
                vector<string> child_command(command.begin(), command.begin()+i);
                recursive_run(child_command);
                kill(getpid(), SIGTERM);
            }else{
                signal(SIGCHLD, SIG_IGN);
                rc = fork();
                if(rc<0) {
                    fprintf(stderr,"Erro no fork\n");
                }
                else if(rc==0) {
                    int saved_stdout=-1;
                    if(stdout_pipe!=NULL) {
                        saved_stdout = dup(1);
                        dup2(stdout_pipe[1],1);
                    }
                    vector<string> args(command.begin()+i+1, command.end());
                    runCommand(args);
                    if(saved_stdout!=-1) dup2(saved_stdout,1);
                    kill(getpid(), SIGTERM);
                }
                else {
                    int wc = waitpid(rc,NULL,0);
                    if(stdout_pipe!=NULL) {
                        close(stdout_pipe[1]);
                    }

                }
            }
            return;
        }
        else if(command[i]=="|") {
            vector<string> child_command(command.begin(), command.begin()+i);
            int pipefd[2];

            pipe(pipefd);
            recursive_run(child_command,pipefd);

            int rc = fork();

            if(rc < 0){
                cout << "Fork Failed\n";
                exit(1);
            } else if(rc == 0){
                int saved_stdout=-1;
                int saved_stdin=-1;
                if(stdout_pipe!=NULL) {
                    saved_stdout = dup(1);
                    dup2(stdout_pipe[1],1);
                }
                saved_stdin=dup(0);
                dup2(pipefd[0],0);

                vector<string> args(command.begin()+i+1, command.end());
                
                runCommand(args);
                dup2(saved_stdin,0);
                close(pipefd[0]);

                if(saved_stdout!=-1) dup2(saved_stdout,1);
                kill(getpid(), SIGTERM);
            }
            else {
                int wc = wait(NULL);
                if(stdout_pipe!=NULL) {
                    close(stdout_pipe[1]);
                }
            }
            return;
        }
    }

    if(command.size()){
    
        if(command[0] == "cd"){
    	    runCommand(command);
	        return;
        }

        if(command[0] == "quit"){
    	    TERMINAL = false;
	        return;
        }
    }

    int rc = fork();
    if(rc < 0){
        cout << "Fork Failed\n";
        exit(1);
    } else if(rc == 0){
        int saved_stdout=-1;
        if(stdout_pipe!=NULL) {
            saved_stdout = dup(1);
            dup2(stdout_pipe[1],1);
        }
        runCommand(command);
        if(saved_stdout!=-1) dup2(saved_stdout,1);
        kill(getpid(), SIGTERM);
    }
    else {
        int wc = wait(NULL);
        if(stdout_pipe!=NULL) {
            close(stdout_pipe[1]);
        }
    }

    return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, -0x38(%rbp)
movq %rdi, %rbx
movq 0x8(%rdi), %rax
subq (%rdi), %rax
shrq $0x5, %rax
movl %eax, %r15d
decq %r15
leaq 0x2855(%rip), %r12      # 0x5024
leaq 0x285e(%rip), %r13      # 0x5034
movq (%rbx), %rdi
testl %r15d, %r15d
js 0x2896
movl %r15d, %r14d
andl $0x7fffffff, %r14d      # imm = 0x7FFFFFFF
shlq $0x5, %r14
addq %r14, %rdi
movq %r12, %rsi
callq 0x20a0
testl %eax, %eax
je 0x28f4
movq (%rbx), %rdi
addq %r14, %rdi
movq %r13, %rsi
callq 0x20a0
decq %r15
testl %eax, %eax
jne 0x27d6
movq (%rbx), %rsi
leaq (%rsi,%r14), %rdx
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x3626
leaq -0x58(%rbp), %rdi
callq 0x22a0
leaq -0xa0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3524
movq -0x38(%rbp), %r15
leaq -0xa0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x279c
leaq -0xa0(%rbp), %rdi
callq 0x35b8
callq 0x2080
testl %eax, %eax
js 0x2bd2
je 0x299c
xorl %edi, %edi
callq 0x2280
testq %r15, %r15
je 0x2bab
movl 0x4(%r15), %edi
callq 0x2400
jmp 0x2bab
cmpq %rdi, 0x8(%rbx)
movq -0x38(%rbp), %r14
je 0x28cb
leaq 0x279c(%rip), %rsi      # 0x5043
callq 0x20a0
testl %eax, %eax
je 0x29c5
movq (%rbx), %rdi
leaq 0x2788(%rip), %rsi      # 0x5046
callq 0x20a0
testl %eax, %eax
je 0x2a3d
callq 0x2080
testl %eax, %eax
js 0x2be7
je 0x29eb
xorl %edi, %edi
callq 0x2280
testq %r14, %r14
je 0x2bb4
movl 0x4(%r14), %edi
jmp 0x2941
callq 0x2080
testl %eax, %eax
movq -0x38(%rbp), %r15
js 0x2bcd
je 0x2957
movl $0x1, %esi
movl $0x11, %edi
callq 0x2250
callq 0x2080
testl %eax, %eax
js 0x2bc6
je 0x2a14
movl %eax, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2170
testq %r15, %r15
je 0x2bb4
movl 0x4(%r15), %edi
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2400
movq (%rbx), %rsi
addq %rsi, %r14
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
movq %r14, %rdx
callq 0x3626
leaq -0xd0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3524
leaq -0xd0(%rbp), %rdi
xorl %esi, %esi
callq 0x279c
leaq -0xd0(%rbp), %rdi
callq 0x35b8
jmp 0x2b9a
testq %r15, %r15
je 0x2a49
movl $0x1, %edi
callq 0x2330
movl %eax, %r12d
movl 0x4(%r15), %edi
movl $0x1, %esi
callq 0x21b0
jmp 0x2a4f
leaq -0x100(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3524
movq %r14, %rdi
callq 0x26dc
leaq -0x100(%rbp), %rdi
jmp 0x2baf
testq %r14, %r14
je 0x2aeb
movl $0x1, %edi
callq 0x2330
movl %eax, %r15d
movl 0x4(%r14), %edi
movl $0x1, %esi
callq 0x21b0
jmp 0x2af1
testq %r15, %r15
je 0x2b3d
movl $0x1, %edi
callq 0x2330
movl %eax, %r12d
movl 0x4(%r15), %edi
movl $0x1, %esi
callq 0x21b0
jmp 0x2b43
movb $0x0, 0x57d4(%rip)      # 0x8218
jmp 0x2bb4
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorl %edi, %edi
callq 0x2330
movl %eax, %r15d
movl -0x58(%rbp), %edi
xorl %esi, %esi
callq 0x21b0
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
leaq (%rax,%r14), %rsi
addq $0x20, %rsi
leaq -0x70(%rbp), %rdi
leaq -0x29(%rbp), %rcx
callq 0x3626
leaq -0x88(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x3524
leaq -0x88(%rbp), %rdi
callq 0x26dc
leaq -0x88(%rbp), %rdi
callq 0x35b8
movl %r15d, %edi
xorl %esi, %esi
callq 0x21b0
movl -0x58(%rbp), %edi
callq 0x2400
cmpl $-0x1, %r12d
je 0x2acc
movl %r12d, %edi
movl $0x1, %esi
callq 0x21b0
callq 0x22f0
movl %eax, %edi
movl $0xf, %esi
callq 0x22c0
leaq -0x70(%rbp), %rdi
callq 0x35b8
jmp 0x2bab
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
leaq -0xe8(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3524
movq %r14, %rdi
callq 0x26dc
leaq -0xe8(%rbp), %rdi
callq 0x35b8
cmpl $-0x1, %r15d
je 0x2b2a
movl %r15d, %edi
movl $0x1, %esi
callq 0x21b0
callq 0x22f0
movl %eax, %edi
movl $0xf, %esi
callq 0x22c0
jmp 0x2bb4
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
leaq (%rax,%r14), %rsi
addq $0x20, %rsi
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x3626
leaq -0xb8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3524
leaq -0xb8(%rbp), %rdi
callq 0x26dc
leaq -0xb8(%rbp), %rdi
callq 0x35b8
cmpl $-0x1, %r12d
je 0x2b9a
movl %r12d, %edi
movl $0x1, %esi
callq 0x21b0
callq 0x22f0
movl %eax, %edi
movl $0xf, %esi
callq 0x22c0
leaq -0x50(%rbp), %rdi
callq 0x35b8
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x2420
jmp 0x2bb4
callq 0x244f
movq 0x53ef(%rip), %rdi      # 0x7fc8
leaq 0x2456(%rip), %rsi      # 0x5036
callq 0x21e0
jmp 0x2bfa
movq 0x53da(%rip), %rdi      # 0x7fc8
leaq 0x2441(%rip), %rsi      # 0x5036
callq 0x21e0
movl $0x1, %edi
callq 0x2260
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
jmp 0x2c64
jmp 0x2c72
jmp 0x2c6d
movq %rax, %rbx
leaq -0xe8(%rbp), %rdi
jmp 0x2c79
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x2c79
movq %rax, %rbx
leaq -0x88(%rbp), %rdi
callq 0x35b8
jmp 0x2c54
jmp 0x2c72
movq %rax, %rbx
leaq -0xd0(%rbp), %rdi
jmp 0x2c64
jmp 0x2c72
jmp 0x2c6d
jmp 0x2c72
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
jmp 0x2c64
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x35b8
jmp 0x2c75
jmp 0x2c72
movq %rax, %rbx
jmp 0x2c7e
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x35b8
movq %rbx, %rdi
callq 0x23a0