// File: /workspace/github_cpp_makefile_star2_O2/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 0x2905(%rip), %r12      # 0x5024
leaq 0x290e(%rip), %r13      # 0x5034
movq (%rbx), %rdi
testl %r15d, %r15d
js 0x27e5
movl %r15d, %r14d
andl $0x7fffffff, %r14d      # imm = 0x7FFFFFFF
shlq $0x5, %r14
addq %r14, %rdi
movq %r12, %rsi
callq 0x3196
testb %al, %al
jne 0x2829
movq (%rbx), %rdi
addq %r14, %rdi
movq %r13, %rsi
callq 0x3196
decq %r15
testb %al, %al
je 0x2726
movq (%rbx), %rsi
leaq (%rsi,%r14), %rdx
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x3290
leaq -0x58(%rbp), %rdi
callq 0x22b0
leaq -0xa0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3210
leaq -0xa0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x26ec
leaq -0xa0(%rbp), %rdi
callq 0x3264
callq 0x2090
testl %eax, %eax
js 0x2b4d
je 0x28bb
xorl %edi, %edi
callq 0x2280
movq -0x38(%rbp), %rax
testq %rax, %rax
je 0x2a9b
movl 0x4(%rax), %edi
callq 0x2400
jmp 0x2a9b
cmpq %rdi, 0x8(%rbx)
je 0x2907
leaq 0x284d(%rip), %rsi      # 0x5043
callq 0x3196
testb %al, %al
je 0x28e8
leaq -0x100(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3210
movq %r14, %rdi
callq 0x262c
leaq -0x100(%rbp), %rdi
jmp 0x2a9f
callq 0x2090
testl %eax, %eax
js 0x2b2f
je 0x2876
pushq $0x11
popq %rdi
pushq $0x1
popq %rsi
callq 0x2250
callq 0x2090
testl %eax, %eax
js 0x2b02
je 0x2944
movl %eax, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2180
movq -0x38(%rbp), %rax
testq %rax, %rax
je 0x2aa4
movl 0x4(%rax), %edi
jmp 0x292e
movq (%rbx), %rsi
addq %rsi, %r14
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
movq %r14, %rdx
callq 0x3290
leaq -0xd0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3210
leaq -0xd0(%rbp), %rdi
xorl %esi, %esi
callq 0x26ec
leaq -0xd0(%rbp), %rdi
callq 0x3264
jmp 0x2a8c
movq -0x38(%rbp), %r15
testq %r15, %r15
je 0x299a
pushq $0x1
popq %r13
movl %r13d, %edi
callq 0x2340
movl %eax, %r12d
movl 0x4(%r15), %edi
movl %r13d, %esi
callq 0x21c0
jmp 0x299e
movq (%rbx), %rdi
leaq 0x2754(%rip), %rsi      # 0x5046
callq 0x3196
testb %al, %al
je 0x2907
movb $0x0, 0x5916(%rip)      # 0x8218
jmp 0x2aa4
callq 0x2090
testl %eax, %eax
movq -0x38(%rbp), %r14
js 0x2b62
je 0x2971
xorl %edi, %edi
callq 0x2280
testq %r14, %r14
je 0x2aa4
movl 0x4(%r14), %edi
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2400
movq -0x38(%rbp), %r15
testq %r15, %r15
je 0x2a33
pushq $0x1
popq %r13
movl %r13d, %edi
callq 0x2340
movl %eax, %r12d
movl 0x4(%r15), %edi
movl %r13d, %esi
callq 0x21c0
jmp 0x2a37
testq %r14, %r14
je 0x2ab6
pushq $0x1
popq %r12
movl %r12d, %edi
callq 0x2340
movl %eax, %r15d
movl 0x4(%r14), %edi
movl %r12d, %esi
callq 0x21c0
jmp 0x2aba
pushq $-0x1
popq %r12
xorl %edi, %edi
callq 0x2340
movl %eax, %r15d
movl -0x58(%rbp), %edi
xorl %esi, %esi
callq 0x21c0
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
leaq (%rax,%r14), %rsi
addq $0x20, %rsi
leaq -0x70(%rbp), %rdi
leaq -0x29(%rbp), %rcx
callq 0x3290
leaq -0x88(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x3210
leaq -0x88(%rbp), %rdi
callq 0x262c
leaq -0x88(%rbp), %rdi
callq 0x3264
movl %r15d, %edi
xorl %esi, %esi
callq 0x21c0
movl -0x58(%rbp), %edi
callq 0x2400
cmpl $-0x1, %r12d
je 0x2a19
pushq $0x1
popq %rsi
movl %r12d, %edi
callq 0x21c0
callq 0x2300
pushq $0xf
popq %rsi
movl %eax, %edi
callq 0x22e0
leaq -0x70(%rbp), %rdi
callq 0x3264
jmp 0x2a9b
pushq $-0x1
popq %r12
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
leaq (%rax,%r14), %rsi
addq $0x20, %rsi
leaq -0x50(%rbp), %rdi
leaq -0x70(%rbp), %rcx
callq 0x3290
leaq -0xb8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3210
leaq -0xb8(%rbp), %rdi
callq 0x262c
leaq -0xb8(%rbp), %rdi
callq 0x3264
cmpl $-0x1, %r12d
je 0x2a8c
pushq $0x1
popq %rsi
movl %r12d, %edi
callq 0x21c0
callq 0x2300
pushq $0xf
popq %rsi
movl %eax, %edi
callq 0x22e0
leaq -0x50(%rbp), %rdi
callq 0x3264
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $-0x1
popq %r15
leaq -0xe8(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3210
movq %r14, %rdi
callq 0x262c
leaq -0xe8(%rbp), %rdi
callq 0x3264
cmpl $-0x1, %r15d
je 0x2af1
pushq $0x1
popq %rsi
movl %r15d, %edi
callq 0x21c0
callq 0x2300
pushq $0xf
popq %rsi
movl %eax, %edi
callq 0x22e0
jmp 0x2aa4
movq 0x54c7(%rip), %rax      # 0x7fd0
movq (%rax), %rcx
leaq 0x2513(%rip), %rdi      # 0x5026
pushq $0xd
popq %rsi
pushq $0x1
popq %rdx
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x23e0
movq 0x549a(%rip), %rax      # 0x7fd0
movq (%rax), %rcx
leaq 0x24e6(%rip), %rdi      # 0x5026
pushq $0xd
popq %rsi
pushq $0x1
popq %rdx
callq 0x23e0
jmp 0x2b75
movq 0x5474(%rip), %rdi      # 0x7fc8
leaq 0x24db(%rip), %rsi      # 0x5036
callq 0x21e0
jmp 0x2b75
movq 0x545f(%rip), %rdi      # 0x7fc8
leaq 0x24c6(%rip), %rsi      # 0x5036
callq 0x21e0
pushq $0x1
popq %rdi
callq 0x2260
movq %rax, %rbx
leaq -0xe8(%rbp), %rdi
jmp 0x2bf2
movq %rax, %rbx
leaq -0xb8(%rbp), %rdi
jmp 0x2bdd
jmp 0x2beb
jmp 0x2be6
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x2bf2
movq %rax, %rbx
leaq -0x88(%rbp), %rdi
callq 0x3264
jmp 0x2bcd
jmp 0x2beb
movq %rax, %rbx
leaq -0xd0(%rbp), %rdi
jmp 0x2bdd
jmp 0x2beb
jmp 0x2be6
jmp 0x2beb
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
jmp 0x2bdd
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x3264
jmp 0x2bee
jmp 0x2beb
movq %rax, %rbx
jmp 0x2bf7
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x3264
movq %rbx, %rdi
callq 0x23b0