// File: /workspace/github_c_makefile_star2_O3/sasairc[P]clangsay/src/libbenly/src/cmd.c
// Function: exec_cmd
int exec_cmd(cmd_t* cmd, int ret, int in_fd)
{
    int         status  = 0,
                fd[2]   = {0};

    pid_t       pid     = 0;

    /*
     * pipe (last)
     */
    if (cmd->prev != NULL) {
        if (cmd->prev->type == TPIPE && cmd->type != TPIPE) {
            redirect(in_fd, STDIN_FILENO);
            if (cmd->io != NULL) {
                if (file_redirect(cmd) < 0)
                    exit(1);
            }
            if (cmd->args[0][0] == '.'  &&
                        (cmd->args[0][1] == '/' || cmd->args[0][1] == '.')) {
                if (check_file_stat(cmd, 0, S_IEXEC) < 0)
                    exit(1);
            }
            execvp(cmd->args[0], cmd->args);
            fprintf(stderr, "command not found: %s\n",
                    cmd->args[0]);

            exit(errno);
        }
    }

    /*
     * command
     */
    if (cmd->type != TPIPE) {
        switch (pid = fork()) {
            case    -1:
                fprintf(stderr, "fork() failure");

                return errno;
            case    0:
                if (cmd->io != NULL) {
                    if (file_redirect(cmd) < 0)
                        exit(1);
                }
                if (cmd->args[0][0] == '.'  &&
                            (cmd->args[0][1] == '/' || cmd->args[0][1] == '.')) {
                    if (check_file_stat(cmd, 0, S_IEXEC) < 0)
                        exit(1);
                }
                execvp(cmd->args[0], cmd->args);
                fprintf(stderr, "command not found: %s\n",
                        cmd->args[0]);

                exit(errno);
            default:
                if (waitpid(pid, &status, 0) < 0)
                    perror("waitpid");

                ret += WEXITSTATUS(status);
                if (cmd->next != NULL) {
                    /*
                     * 1. &&
                     * 2. ||
                     * 3. ;
                     */
                    if (ret == 0 && cmd->type == TAND)
                        exec_cmd(cmd->next, ret, STDIN_FILENO);
                    else if (ret != 0 && cmd->type == TOR)
                        exec_cmd(cmd->next, ret, STDIN_FILENO);
                    else if (cmd->type == TPAREN || cmd->type == TCOM)
                        exec_cmd(cmd->next, 0, STDIN_FILENO);

                    /*
                     * 1. a && b && c
                     * 2. a || b || c
                     */
                    if ((cmd->type == TAND && ret != 0) || (cmd->type == TOR && ret == 0)) {
                        cmd = cmd->next;
                        switch (cmd->prev->type) {
                            case    TAND:
                                while (cmd->next != NULL &&
                                        (cmd->type == TPIPE || cmd->type == TAND))
                                    cmd = cmd->next;
                                break;
                            case    TOR:
                                while (cmd->next != NULL &&
                                        (cmd->type == TPIPE || cmd->type == TOR))
                                    cmd = cmd->next;
                                break;
                        }
                        if (cmd->next != NULL)
                            exec_cmd(cmd->next, 0, STDIN_FILENO);
                    }
                }

                return ret;
        }
    }

    /*
     * pipe
     */
    if (cmd->prev != NULL) {
        if (cmd->prev->type != TPIPE)
            pid = getpid();
    } else {
        pid= getpid();
    }
    switch (fork()) {
        case    -1:
            fprintf(stderr, "fork() failure");

            return errno;
        case    0:
            if (pipe(fd) < 0) {
                fprintf(stderr, "pipe() failure\n");

                exit(errno);
            }
            switch (fork()) {
                case    -1:
                    fprintf(stderr, "fork() failure\n");

                    exit(1);
                case    0:
                    if (cmd->io != NULL) {
                        if (file_redirect(cmd) < 0)
                            exit(1);
                    } else {
                        close(fd[0]);
                        redirect(in_fd, STDIN_FILENO);
                    }
                    redirect(fd[1], STDOUT_FILENO);
                    if (cmd->args[0][0] == '.'  &&
                                (cmd->args[0][1] == '/' || cmd->args[0][1] == '.')) {
                        if (check_file_stat(cmd, 0, S_IEXEC) < 0)
                            exit(1);
                    }
                    execvp(cmd->args[0], cmd->args);
                    fprintf(stderr, "command not found: %s\n",
                            cmd->args[0]);

                    exit(errno);
                default:
                    close(fd[1]);
                    close(in_fd);
                    if (cmd->next != NULL)
                        exec_cmd(cmd->next, ret, fd[0]);

                    exit(1);
            }
        default:
            status = mwait();
            if (pid == getpid()) {
                while (cmd->next != NULL && cmd->type == TPIPE)
                    cmd = cmd->next;

                ret += WEXITSTATUS(status);
                if (cmd->next != NULL) {
                    /*
                     * 1. &&
                     * 2. ||
                     * 3. ;
                     */
                    if (ret == 0 && cmd->type == TAND)
                        exec_cmd(cmd->next, ret, STDIN_FILENO);
                    else if (ret != 0 && cmd->type == TOR)
                        exec_cmd(cmd->next, ret, STDIN_FILENO);
                    else if (cmd->type == TPAREN || cmd->type == TCOM)
                        exec_cmd(cmd->next, 0, STDIN_FILENO);

                    /*
                     * 1. a | b && c && d
                     * 2. a | b || c || d
                     */
                    if ((cmd->type == TAND && ret != 0) || (cmd->type == TOR && ret == 0)) {
                        cmd = cmd->next;
                        switch (cmd->prev->type) {
                            case    TAND:
                                while (cmd->next != NULL &&
                                        (cmd->type == TPIPE || cmd->type == TAND))
                                    cmd = cmd->next;
                                break;
                            case    TOR:
                                while (cmd->next != NULL &&
                                        (cmd->type == TPIPE || cmd->type == TOR))
                                    cmd = cmd->next;
                                break;
                        }
                        if (cmd->next != NULL)
                            exec_cmd(cmd->next, 0, STDIN_FILENO);
                    }
                }
            } else {
                exit(0);
            }
    }

    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x18, %rsp
movl %edx, %ebp
movl %esi, %r14d
movq %rdi, %rbx
movl $0x0, 0x4(%rsp)
movq $0x0, 0x8(%rsp)
movq 0x20(%rdi), %rax
testq %rax, %rax
je 0x3599
cmpl $0x3, (%rax)
movl (%rbx), %eax
jne 0x3623
xorl %r15d, %r15d
cmpl $0x3, %eax
je 0x35aa
movl %ebp, %edi
xorl %esi, %esi
callq 0x3926
jmp 0x3814
cmpl $0x3, (%rbx)
jne 0x362c
callq 0x2130
movl %eax, %r15d
callq 0x2400
cmpl $-0x1, %eax
je 0x3798
testl %eax, %eax
je 0x3834
callq 0x3941
movl %eax, %ebp
movl %eax, 0x4(%rsp)
callq 0x2130
cmpl %eax, %r15d
jne 0x3847
movq %rbx, %r15
movq 0x18(%rbx), %rbx
testq %rbx, %rbx
je 0x3616
movl (%r15), %eax
cmpl $0x3, %eax
je 0x35d9
movl %ebp, %ecx
movzbl %ch, %ebp
addl %r14d, %ebp
je 0x3692
movl %ebp, %esi
cmpl $0x5, %eax
je 0x36a3
decl %eax
cmpl $0x1, %eax
jbe 0x36a1
jmp 0x36ad
movl %ebp, %eax
movzbl %ah, %ebp
addl %r14d, %ebp
jmp 0x37f6
cmpl $0x3, %eax
je 0x35a2
callq 0x2400
cmpl $-0x1, %eax
je 0x37e7
testl %eax, %eax
je 0x3814
leaq 0x4(%rsp), %rsi
movl %eax, %edi
xorl %edx, %edx
callq 0x2360
testl %eax, %eax
js 0x3803
movzbl 0x5(%rsp), %ebp
addl %r14d, %ebp
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x37f6
movl (%rbx), %eax
testl %ebp, %ebp
je 0x370a
movl %ebp, %esi
cmpl $0x5, %eax
je 0x371b
decl %eax
cmpl $0x1, %eax
jbe 0x3719
jmp 0x3722
cmpl $0x4, %eax
ja 0x36ad
movl $0x16, %ecx
btl %eax, %ecx
jae 0x36ad
xorl %esi, %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x354c
movl (%r15), %eax
cmpl $0x4, %eax
sete %cl
testl %ebp, %ebp
setne %dl
xorl $0x5, %eax
orl %ebp, %eax
sete %al
testb %cl, %dl
jne 0x36cf
testb %al, %al
je 0x37f6
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rax
movl (%rax), %eax
cmpl $0x5, %eax
je 0x376f
cmpl $0x4, %eax
jne 0x37d0
movq %rcx, %rax
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
je 0x37d3
movl (%rax), %edx
addl $-0x3, %edx
cmpl $0x2, %edx
jb 0x36eb
jmp 0x37d3
cmpl $0x4, %eax
ja 0x3722
movl $0x16, %ecx
btl %eax, %ecx
jae 0x3722
xorl %esi, %esi
xorl %edx, %edx
callq 0x354c
movl (%rbx), %eax
cmpl $0x4, %eax
sete %cl
testl %ebp, %ebp
setne %dl
xorl $0x5, %eax
orl %ebp, %eax
sete %al
testb %dl, %cl
jne 0x3743
testb %al, %al
je 0x37f6
movq 0x18(%rbx), %rcx
movq 0x20(%rcx), %rax
movl (%rax), %eax
cmpl $0x5, %eax
je 0x37a7
cmpl $0x4, %eax
jne 0x37d0
movq %rcx, %rax
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
je 0x37d3
movl (%rax), %edx
addl $-0x3, %edx
cmpl $0x2, %edx
jb 0x3757
jmp 0x37d3
movq 0x18(%rcx), %rdx
testq %rdx, %rdx
je 0x37d0
movq %rcx, %rax
movq %rdx, %rcx
movl (%rax), %edx
cmpl $0x5, %edx
je 0x378a
cmpl $0x3, %edx
jne 0x37d3
movq 0x18(%rcx), %rdx
movq %rcx, %rax
testq %rdx, %rdx
jne 0x377b
jmp 0x37d3
leaq 0x14(%rsp), %rbx
movq %rbx, %rdi
callq 0x2545
jmp 0x37f4
movq 0x18(%rcx), %rdx
testq %rdx, %rdx
je 0x37d0
movq %rcx, %rax
movq %rdx, %rcx
movl (%rax), %edx
cmpl $0x5, %edx
je 0x37c2
cmpl $0x3, %edx
jne 0x37d3
movq 0x18(%rcx), %rdx
movq %rcx, %rax
testq %rdx, %rdx
jne 0x37b3
jmp 0x37d3
movq %rcx, %rax
movq 0x18(%rax), %rdi
testq %rdi, %rdi
je 0x37f6
xorl %esi, %esi
xorl %edx, %edx
callq 0x354c
jmp 0x37f6
leaq 0x14(%rsp), %rbx
movq %rbx, %rdi
callq 0x24cc
movl (%rbx), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x888f(%rip), %rdi      # 0xc099
callq 0x2440
jmp 0x3658
cmpq $0x0, 0x10(%rbx)
je 0x38bd
movq %rbx, %rdi
callq 0x3383
testl %eax, %eax
jns 0x38bd
jmp 0x38e5
leaq 0x8(%rsp), %rdi
callq 0x2240
testl %eax, %eax
jns 0x384e
callq 0x251c
xorl %edi, %edi
callq 0x20c0
callq 0x2400
testl %eax, %eax
je 0x3861
cmpl $-0x1, %eax
jne 0x387c
callq 0x24f7
cmpq $0x0, 0x10(%rbx)
jne 0x38a3
movl 0x8(%rsp), %edi
callq 0x2060
movl %ebp, %edi
xorl %esi, %esi
callq 0x3926
jmp 0x38af
movl 0xc(%rsp), %edi
callq 0x2060
movl %ebp, %edi
callq 0x2060
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x38e5
movl 0x8(%rsp), %edx
movl %r14d, %esi
callq 0x354c
jmp 0x38e5
movq %rbx, %rdi
callq 0x3383
testl %eax, %eax
js 0x38e5
movl 0xc(%rsp), %edi
movl $0x1, %esi
callq 0x3926
movq 0x8(%rbx), %rsi
movq (%rsi), %rdi
cmpb $0x2e, (%rdi)
jne 0x38f6
movb 0x1(%rdi), %al
andb $-0x2, %al
cmpb $0x2e, %al
jne 0x38f6
movq %rbx, %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x3493
testl %eax, %eax
jns 0x38ef
movl $0x1, %edi
callq 0x20c0
movq 0x8(%rbx), %rsi
movq (%rsi), %rdi
callq 0x20b0
movq 0xd6de(%rip), %rax      # 0x10fe0
movq (%rax), %rdi
movq 0x8(%rbx), %rax
movq (%rax), %rdx
leaq 0x8760(%rip), %rsi      # 0xc073
xorl %eax, %eax
callq 0x2450
callq 0x2390
movl (%rax), %edi
callq 0x20c0