// File: /workspace/github_cpp_makefile_star2_O1/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, -0x30(%rbp)
movq %rdi, %rbx
movq 0x8(%rdi), %rax
subq (%rdi), %rax
shrq $0x5, %rax
movl %eax, %ecx
decq %rcx
leaq 0x2856(%rip), %r12      # 0x5024
leaq 0x285f(%rip), %r13      # 0x5034
movq %rcx, %r14
testl %r14d, %r14d
js 0x2aa9
movl %r14d, %r15d
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
shlq $0x5, %r15
movq (%rbx), %rdi
addq %r15, %rdi
movq %r12, %rsi
callq 0x20a0
testl %eax, %eax
je 0x289a
movq (%rbx), %rdi
addq %r15, %rdi
movq %r13, %rsi
callq 0x20a0
leaq -0x1(%r14), %rcx
testl %eax, %eax
jne 0x27d5
movq (%rbx), %rsi
leaq (%rsi,%r15), %rdx
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x3620
leaq -0x58(%rbp), %rdi
callq 0x22a0
leaq -0xa0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3522
leaq -0xa0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x279c
leaq -0xa0(%rbp), %rdi
callq 0x35b6
callq 0x2080
testl %eax, %eax
js 0x2be2
je 0x2937
xorl %edi, %edi
callq 0x2280
cmpq $0x0, -0x30(%rbp)
je 0x2a97
movq -0x30(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x2400
jmp 0x2a97
callq 0x2080
testl %eax, %eax
js 0x2bdd
je 0x28f2
movl $0x1, %esi
movl $0x11, %edi
callq 0x2250
callq 0x2080
testl %eax, %eax
js 0x2bbe
je 0x295d
movl %eax, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2170
cmpq $0x0, -0x30(%rbp)
je 0x2aa0
movq -0x30(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x2400
jmp 0x2aa0
movq (%rbx), %rsi
addq %rsi, %r15
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
movq %r15, %rdx
callq 0x3620
leaq -0xd0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3522
leaq -0xd0(%rbp), %rdi
xorl %esi, %esi
callq 0x279c
leaq -0xd0(%rbp), %rdi
callq 0x35b6
jmp 0x2a86
movq -0x30(%rbp), %r13
testq %r13, %r13
je 0x298a
movl $0x1, %edi
callq 0x2330
movl %eax, %r12d
movl 0x4(%r13), %edi
movl $0x1, %esi
callq 0x21b0
jmp 0x2990
movq -0x30(%rbp), %r13
testq %r13, %r13
je 0x2a29
movl $0x1, %edi
callq 0x2330
movl %eax, %r12d
movl 0x4(%r13), %edi
movl $0x1, %esi
callq 0x21b0
jmp 0x2a2f
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorl %edi, %edi
callq 0x2330
movl %eax, %r13d
movl -0x58(%rbp), %edi
xorl %esi, %esi
callq 0x21b0
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
leaq (%rax,%r15), %rsi
addq $0x20, %rsi
leaq -0x70(%rbp), %rdi
leaq -0x31(%rbp), %rcx
callq 0x3620
leaq -0x88(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x3522
leaq -0x88(%rbp), %rdi
callq 0x26dc
leaq -0x88(%rbp), %rdi
callq 0x35b6
movl %r13d, %edi
xorl %esi, %esi
callq 0x21b0
movl -0x58(%rbp), %edi
callq 0x2400
cmpl $-0x1, %r12d
je 0x2a0d
movl %r12d, %edi
movl $0x1, %esi
callq 0x21b0
callq 0x22f0
movl %eax, %edi
movl $0xf, %esi
callq 0x22c0
leaq -0x70(%rbp), %rdi
callq 0x35b6
jmp 0x2a97
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
leaq (%rax,%r15), %rsi
addq $0x20, %rsi
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x3620
leaq -0xb8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3522
leaq -0xb8(%rbp), %rdi
callq 0x26dc
leaq -0xb8(%rbp), %rdi
callq 0x35b6
cmpl $-0x1, %r12d
je 0x2a86
movl %r12d, %edi
movl $0x1, %esi
callq 0x21b0
callq 0x22f0
movl %eax, %edi
movl $0xf, %esi
callq 0x22c0
leaq -0x50(%rbp), %rdi
callq 0x35b6
testl %r14d, %r14d
jns 0x2bac
movq (%rbx), %rdi
cmpq %rdi, 0x8(%rbx)
je 0x2ad5
leaq 0x258a(%rip), %rsi      # 0x5043
callq 0x20a0
testl %eax, %eax
je 0x2b09
movq (%rbx), %rdi
leaq 0x257a(%rip), %rsi      # 0x5046
callq 0x20a0
testl %eax, %eax
je 0x2b53
callq 0x2080
testl %eax, %eax
js 0x2bc8
movq -0x30(%rbp), %r14
je 0x2b31
xorl %edi, %edi
callq 0x2280
testq %r14, %r14
je 0x2bac
movq -0x30(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x2400
jmp 0x2bac
leaq -0x100(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3522
movq %r14, %rdi
callq 0x26dc
leaq -0x100(%rbp), %rdi
callq 0x35b6
jmp 0x2bac
testq %r14, %r14
je 0x2b5c
movl $0x1, %edi
callq 0x2330
movl %eax, %r15d
movl 0x4(%r14), %edi
movl $0x1, %esi
callq 0x21b0
jmp 0x2b62
movb $0x0, 0x56be(%rip)      # 0x8218
jmp 0x2bac
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
leaq -0xe8(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3522
movq %r14, %rdi
callq 0x26dc
leaq -0xe8(%rbp), %rdi
callq 0x35b6
cmpl $-0x1, %r15d
je 0x2b9b
movl %r15d, %edi
movl $0x1, %esi
callq 0x21b0
callq 0x22f0
movl %eax, %edi
movl $0xf, %esi
callq 0x22c0
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x2420
jmp 0x2aa0
movq 0x53f9(%rip), %rdi      # 0x7fc8
leaq 0x2460(%rip), %rsi      # 0x5036
callq 0x21e0
jmp 0x2bf5
callq 0x244f
movq 0x53df(%rip), %rdi      # 0x7fc8
leaq 0x2446(%rip), %rsi      # 0x5036
callq 0x21e0
movl $0x1, %edi
callq 0x2260
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
jmp 0x2c5f
jmp 0x2c6d
jmp 0x2c68
movq %rax, %rbx
leaq -0x88(%rbp), %rdi
callq 0x35b6
jmp 0x2c4f
jmp 0x2c6d
movq %rax, %rbx
leaq -0xd0(%rbp), %rdi
jmp 0x2c5f
jmp 0x2c6d
jmp 0x2c68
movq %rax, %rbx
leaq -0xe8(%rbp), %rdi
jmp 0x2c74
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x2c74
jmp 0x2c6d
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
jmp 0x2c5f
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x35b6
jmp 0x2c70
jmp 0x2c6d
movq %rax, %rbx
jmp 0x2c79
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x35b6
movq %rbx, %rdi
callq 0x23a0