// File: 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
subq $0x230, %rsp            # imm = 0x230
movq %rdi, -0x1f0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x4f60
subq $0x1, %rax
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x4008
movq -0x1f0(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c80
movq %rax, %rdi
leaq 0x66de(%rip), %rsi      # 0xa008
callq 0x4c50
testb $0x1, %al
jne 0x3938
jmp 0x3c5b
callq 0x30a0
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jge 0x3968
movq 0xb683(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x66b3(%rip), %rsi      # 0xa00a
movb $0x0, %al
callq 0x33f0
movl $0x1, %edi
callq 0x3350
cmpl $0x0, -0x18(%rbp)
jne 0x3a67
movq -0x1f0(%rbp), %rdi
callq 0x4f80
movq -0x1f0(%rbp), %rdi
movq %rax, -0x38(%rbp)
callq 0x4f80
movq %rax, -0x48(%rbp)
movslq -0x14(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x4fb0
movq %rax, -0x40(%rbp)
leaq -0x49(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x4ff0
movq -0x1f8(%rbp), %rcx
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0x30(%rbp), %rdi
callq 0x5010
jmp 0x39cd
leaq -0x49(%rbp), %rdi
callq 0x5090
leaq -0x78(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4e10
jmp 0x39e5
xorl %eax, %eax
movl %eax, %esi
leaq -0x78(%rbp), %rdi
callq 0x38e0
jmp 0x39f4
leaq -0x78(%rbp), %rdi
callq 0x4f00
callq 0x3410
movl %eax, %edi
movl $0xf, %esi
callq 0x33e0
leaq -0x30(%rbp), %rdi
callq 0x4f00
jmp 0x3c54
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x49(%rbp), %rdi
callq 0x5090
jmp 0x41e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3a59
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x4f00
leaq -0x30(%rbp), %rdi
callq 0x4f00
jmp 0x41e9
movl $0x11, %edi
movl $0x1, %esi
callq 0x3340
callq 0x30a0
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jge 0x3aa1
movq 0xb545(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x6575(%rip), %rsi      # 0xa00a
movb $0x0, %al
callq 0x33f0
jmp 0x3c52
cmpl $0x0, -0x18(%rbp)
jne 0x3c27
movl $0xffffffff, -0x7c(%rbp) # imm = 0xFFFFFFFF
cmpq $0x0, -0x10(%rbp)
je 0x3ad7
movl $0x1, %edi
callq 0x3450
movl %eax, -0x7c(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
movl $0x1, %esi
callq 0x3260
movq -0x1f0(%rbp), %rdi
callq 0x4f80
movq %rax, -0xb0(%rbp)
movslq -0x14(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x4fb0
movq %rax, -0xa8(%rbp)
leaq -0xa8(%rbp), %rdi
movl $0x1, %esi
callq 0x4fb0
movq -0x1f0(%rbp), %rdi
movq %rax, -0xa0(%rbp)
callq 0x50b0
movq %rax, -0xb8(%rbp)
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0x4ff0
movq -0x200(%rbp), %rcx
movq -0xa0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
leaq -0x98(%rbp), %rdi
callq 0x5010
jmp 0x3b62
leaq -0xb9(%rbp), %rdi
callq 0x5090
leaq -0xd8(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4e10
jmp 0x3b83
leaq -0xd8(%rbp), %rdi
callq 0x3790
jmp 0x3b91
leaq -0xd8(%rbp), %rdi
callq 0x4f00
cmpl $-0x1, -0x7c(%rbp)
je 0x3bf7
movl -0x7c(%rbp), %edi
movl $0x1, %esi
callq 0x3260
jmp 0x3bf7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xb9(%rbp), %rdi
callq 0x5090
jmp 0x41e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3c16
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x4f00
jmp 0x3c16
callq 0x3410
movl %eax, %edi
movl $0xf, %esi
callq 0x33e0
leaq -0x98(%rbp), %rdi
callq 0x4f00
jmp 0x3c50
leaq -0x98(%rbp), %rdi
callq 0x4f00
jmp 0x41e9
movl -0x18(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x3210
movl %eax, -0xdc(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x3c4e
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x3540
jmp 0x3c50
jmp 0x3c52
jmp 0x3c54
jmp 0x3c56
jmp 0x41e0
movq -0x1f0(%rbp), %rdi
movslq -0x14(%rbp), %rsi
callq 0x4c80
movq %rax, %rdi
leaq 0x63a3(%rip), %rsi      # 0xa018
callq 0x4c50
testb $0x1, %al
jne 0x3c83
jmp 0x3ff6
movq -0x1f0(%rbp), %rdi
callq 0x4f80
movq -0x1f0(%rbp), %rdi
movq %rax, -0x100(%rbp)
callq 0x4f80
movq %rax, -0x110(%rbp)
movslq -0x14(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x4fb0
movq %rax, -0x108(%rbp)
leaq -0x111(%rbp), %rdi
movq %rdi, -0x208(%rbp)
callq 0x4ff0
movq -0x208(%rbp), %rcx
movq -0x100(%rbp), %rsi
movq -0x108(%rbp), %rdx
leaq -0xf8(%rbp), %rdi
callq 0x5010
jmp 0x3cf6
leaq -0x111(%rbp), %rdi
callq 0x5090
leaq -0x11c(%rbp), %rdi
callq 0x33b0
leaq -0x138(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x4e10
jmp 0x3d23
leaq -0x138(%rbp), %rdi
leaq -0x11c(%rbp), %rsi
callq 0x38e0
jmp 0x3d38
leaq -0x138(%rbp), %rdi
callq 0x4f00
callq 0x30a0
movl %eax, -0x13c(%rbp)
cmpl $0x0, -0x13c(%rbp)
jge 0x3dc2
movq 0xb269(%rip), %rdi      # 0xefc8
leaq 0x62b4(%rip), %rsi      # 0xa01a
callq 0x3280
jmp 0x3d6d
movl $0x1, %edi
callq 0x3350
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x111(%rbp), %rdi
callq 0x5090
jmp 0x41e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3fe5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x4f00
jmp 0x3fe5
cmpl $0x0, -0x13c(%rbp)
jne 0x3f9c
movl $0xffffffff, -0x140(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x144(%rbp) # imm = 0xFFFFFFFF
cmpq $0x0, -0x10(%rbp)
je 0x3e0b
movl $0x1, %edi
callq 0x3450
movl %eax, -0x140(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
movl $0x1, %esi
callq 0x3260
xorl %edi, %edi
movl %edi, -0x214(%rbp)
callq 0x3450
movl -0x214(%rbp), %esi
movl %eax, -0x144(%rbp)
movl -0x11c(%rbp), %edi
callq 0x3260
movq -0x1f0(%rbp), %rdi
callq 0x4f80
movq %rax, -0x178(%rbp)
movslq -0x14(%rbp), %rsi
leaq -0x178(%rbp), %rdi
callq 0x4fb0
movq %rax, -0x170(%rbp)
leaq -0x170(%rbp), %rdi
movl $0x1, %esi
callq 0x4fb0
movq -0x1f0(%rbp), %rdi
movq %rax, -0x168(%rbp)
callq 0x50b0
movq %rax, -0x180(%rbp)
leaq -0x181(%rbp), %rdi
movq %rdi, -0x210(%rbp)
callq 0x4ff0
movq -0x210(%rbp), %rcx
movq -0x168(%rbp), %rsi
movq -0x180(%rbp), %rdx
leaq -0x160(%rbp), %rdi
callq 0x5010
jmp 0x3eba
leaq -0x181(%rbp), %rdi
callq 0x5090
leaq -0x1a0(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x4e10
jmp 0x3edb
leaq -0x1a0(%rbp), %rdi
callq 0x3790
jmp 0x3ee9
leaq -0x1a0(%rbp), %rdi
callq 0x4f00
movl -0x144(%rbp), %edi
xorl %esi, %esi
callq 0x3260
movl -0x11c(%rbp), %edi
callq 0x3540
jmp 0x3f0f
cmpl $-0x1, -0x140(%rbp)
je 0x3f6f
movl -0x140(%rbp), %edi
movl $0x1, %esi
callq 0x3260
jmp 0x3f6f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x181(%rbp), %rdi
callq 0x5090
jmp 0x3fe5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3f8e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x4f00
jmp 0x3f8e
callq 0x3410
movl %eax, %edi
movl $0xf, %esi
callq 0x33e0
leaq -0x160(%rbp), %rdi
callq 0x4f00
jmp 0x3fd2
leaq -0x160(%rbp), %rdi
callq 0x4f00
jmp 0x3fe5
xorl %eax, %eax
movl %eax, %edi
callq 0x3380
movl %eax, -0x218(%rbp)
jmp 0x3fad
movl -0x218(%rbp), %eax
movl %eax, -0x1a4(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x3fd0
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x3540
jmp 0x3fce
jmp 0x3fd0
jmp 0x3fd2
jmp 0x3fd4
leaq -0xf8(%rbp), %rdi
callq 0x4f00
jmp 0x41e0
leaq -0xf8(%rbp), %rdi
callq 0x4f00
jmp 0x41e9
jmp 0x3ff8
jmp 0x3ffa
movl -0x14(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x3906
movq -0x1f0(%rbp), %rdi
callq 0x4f60
cmpq $0x0, %rax
je 0x40cc
movq -0x1f0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4c80
movq %rax, %rdi
leaq 0x5fef(%rip), %rsi      # 0xa027
callq 0x4c50
testb $0x1, %al
jne 0x4043
jmp 0x4099
movq -0x1f0(%rbp), %rsi
leaq -0x1c0(%rbp), %rdi
movq %rdi, -0x220(%rbp)
callq 0x4e10
movq -0x220(%rbp), %rdi
callq 0x3790
jmp 0x406b
leaq -0x1c0(%rbp), %rdi
callq 0x4f00
jmp 0x41e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x4f00
jmp 0x41e9
movq -0x1f0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4c80
movq %rax, %rdi
leaq 0x5f77(%rip), %rsi      # 0xa02a
callq 0x4c50
testb $0x1, %al
jne 0x40be
jmp 0x40ca
movb $0x0, 0xb203(%rip)      # 0xf2c8
jmp 0x41e0
jmp 0x40cc
callq 0x30a0
movl %eax, -0x1c4(%rbp)
cmpl $0x0, -0x1c4(%rbp)
jge 0x40fd
movq 0xaee1(%rip), %rdi      # 0xefc8
leaq 0x5f2c(%rip), %rsi      # 0xa01a
callq 0x3280
movl $0x1, %edi
callq 0x3350
cmpl $0x0, -0x1c4(%rbp)
jne 0x41b8
movl $0xffffffff, -0x1c8(%rbp) # imm = 0xFFFFFFFF
cmpq $0x0, -0x10(%rbp)
je 0x413c
movl $0x1, %edi
callq 0x3450
movl %eax, -0x1c8(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
movl $0x1, %esi
callq 0x3260
movq -0x1f0(%rbp), %rsi
leaq -0x1e0(%rbp), %rdi
movq %rdi, -0x228(%rbp)
callq 0x4e10
movq -0x228(%rbp), %rdi
callq 0x3790
jmp 0x4164
leaq -0x1e0(%rbp), %rdi
callq 0x4f00
cmpl $-0x1, -0x1c8(%rbp)
je 0x41a5
movl -0x1c8(%rbp), %edi
movl $0x1, %esi
callq 0x3260
jmp 0x41a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x4f00
jmp 0x41e9
callq 0x3410
movl %eax, %edi
movl $0xf, %esi
callq 0x33e0
jmp 0x41dc
xorl %eax, %eax
movl %eax, %edi
callq 0x3380
movl %eax, -0x1e4(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x41da
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x3540
jmp 0x41dc
jmp 0x41de
jmp 0x41e0
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x34e0
nopw %cs:(%rax,%rax)