// File: /workspace/github_c_makefile_star2_O2/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
andl $0x0, 0x14(%rsp)
movl %edx, %ebp
andq $0x0, 0x8(%rsp)
movl %esi, %r14d
movq %rdi, %rbx
movq 0x20(%rdi), %rax
testq %rax, %rax
je 0x2f3f
cmpl $0x3, (%rax)
movl (%rbx), %eax
jne 0x2fc6
xorl %r15d, %r15d
cmpl $0x3, %eax
je 0x2f50
movl %ebp, %edi
xorl %esi, %esi
callq 0x32e4
jmp 0x31a0
cmpl $0x3, (%rbx)
jne 0x2fcf
callq 0x2130
movl %eax, %r15d
callq 0x2400
cmpl $-0x1, %eax
je 0x315f
testl %eax, %eax
je 0x31c0
callq 0x32ff
movl %eax, %ebp
callq 0x2130
cmpl %eax, %r15d
jne 0x31ef
movq %rbx, %r15
movq 0x18(%rbx), %rbx
testq %rbx, %rbx
je 0x2fb9
cmpl $0x3, (%r15)
je 0x2f7b
movl %ebp, %eax
movzbl %ah, %ebp
movl (%r15), %eax
addl %r14d, %ebp
je 0x3035
movl %ebp, %esi
cmpl $0x5, %eax
je 0x3044
decl %eax
cmpl $0x1, %eax
jbe 0x3042
jmp 0x304e
movl %ebp, %eax
movzbl %ah, %ebp
addl %r14d, %ebp
jmp 0x3182
cmpl $0x3, %eax
je 0x2f48
callq 0x2400
cmpl $-0x1, %eax
je 0x315f
testl %eax, %eax
je 0x31a0
leaq 0x14(%rsp), %rsi
movl %eax, %edi
xorl %edx, %edx
callq 0x2360
testl %eax, %eax
js 0x318f
movzbl 0x15(%rsp), %ebp
addl %r14d, %ebp
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x3182
movl (%rbx), %eax
testl %ebp, %ebp
je 0x30cb
movl %ebp, %esi
cmpl $0x5, %eax
je 0x30da
decl %eax
cmpl $0x1, %eax
jbe 0x30d8
jmp 0x30e1
cmpl $0x4, %eax
ja 0x304e
pushq $0x16
popq %rcx
btl %eax, %ecx
jae 0x304e
xorl %esi, %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x2ef8
movl (%r15), %eax
cmpl $0x4, %eax
sete %cl
testl %ebp, %ebp
setne %dl
xorl $0x5, %eax
orl %ebp, %eax
sete %al
testb %dl, %cl
jne 0x3070
testb %al, %al
je 0x3182
movq 0x18(%r15), %rax
movq 0x20(%rax), %rcx
movl (%rcx), %ecx
cmpl $0x4, %ecx
je 0x30bd
cmpl $0x5, %ecx
jne 0x314b
movq 0x18(%rax), %rdi
testq %rdi, %rdi
je 0x3182
movl (%rax), %ecx
movq %rdi, %rax
cmpl $0x3, %ecx
je 0x3088
movq %rdi, %rax
cmpl $0x5, %ecx
je 0x3088
jmp 0x3154
movl (%rax), %ecx
addl $-0x3, %ecx
movq %rdi, %rax
cmpl $0x2, %ecx
jae 0x3154
movq 0x18(%rax), %rdi
testq %rdi, %rdi
jne 0x30ac
jmp 0x3182
cmpl $0x4, %eax
ja 0x30e1
pushq $0x16
popq %rcx
btl %eax, %ecx
jae 0x30e1
xorl %esi, %esi
xorl %edx, %edx
callq 0x2ef8
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 0x3102
testb %al, %al
je 0x3182
movq 0x18(%rbx), %rax
movq 0x20(%rax), %rcx
movl (%rcx), %ecx
cmpl $0x4, %ecx
je 0x3140
cmpl $0x5, %ecx
jne 0x314b
movq 0x18(%rax), %rdi
testq %rdi, %rdi
je 0x3182
movl (%rax), %ecx
movq %rdi, %rax
cmpl $0x3, %ecx
je 0x3116
movq %rdi, %rax
cmpl $0x5, %ecx
je 0x3116
jmp 0x3154
movl (%rax), %ecx
addl $-0x3, %ecx
movq %rdi, %rax
cmpl $0x2, %ecx
jae 0x3154
movq 0x18(%rax), %rdi
testq %rdi, %rdi
jne 0x3133
jmp 0x3182
movq 0x18(%rax), %rdi
testq %rdi, %rdi
je 0x3182
xorl %esi, %esi
xorl %edx, %edx
callq 0x2ef8
jmp 0x3182
movq 0xde7a(%rip), %rax      # 0x10fe0
movq (%rax), %rcx
leaq 0x7efe(%rip), %rdi      # 0xb06e
pushq $0xe
popq %rsi
pushq $0x1
popq %rdx
callq 0x2410
callq 0x2390
movl (%rax), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7ee7(%rip), %rdi      # 0xb07d
callq 0x2440
jmp 0x2ffb
cmpq $0x0, 0x10(%rbx)
je 0x327f
movq %rbx, %rdi
callq 0x2d46
testl %eax, %eax
jns 0x327f
jmp 0x32a5
leaq 0x8(%rsp), %rdi
callq 0x2240
testl %eax, %eax
jns 0x31f6
movq 0xde0b(%rip), %rax      # 0x10fe0
movq (%rax), %rcx
leaq 0x7ea6(%rip), %rdi      # 0xb085
pushq $0xf
popq %rsi
pushq $0x1
popq %rdx
callq 0x2410
jmp 0x32d8
xorl %edi, %edi
callq 0x20c0
callq 0x2400
testl %eax, %eax
je 0x3225
cmpl $-0x1, %eax
jne 0x3240
movq 0xddd5(%rip), %rax      # 0x10fe0
movq (%rax), %rcx
leaq 0x7e80(%rip), %rdi      # 0xb095
pushq $0xf
popq %rsi
pushq $0x1
popq %rdx
callq 0x2410
jmp 0x32a5
cmpq $0x0, 0x10(%rbx)
jne 0x3267
movl 0x8(%rsp), %edi
callq 0x2060
movl %ebp, %edi
xorl %esi, %esi
callq 0x32e4
jmp 0x3273
movl 0xc(%rsp), %edi
callq 0x2060
movl %ebp, %edi
callq 0x2060
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x32a5
movl 0x8(%rsp), %edx
movl %r14d, %esi
callq 0x2ef8
jmp 0x32a5
movq %rbx, %rdi
callq 0x2d46
testl %eax, %eax
js 0x32a5
movl 0xc(%rsp), %edi
pushq $0x1
popq %rsi
callq 0x32e4
movq 0x8(%rbx), %rsi
movq (%rsi), %rdi
cmpb $0x2e, (%rdi)
jne 0x32b4
movb 0x1(%rdi), %al
andb $-0x2, %al
cmpb $0x2e, %al
jne 0x32b4
pushq $0x40
popq %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2e48
testl %eax, %eax
jns 0x32ad
pushq $0x1
popq %rdi
callq 0x20c0
movq 0x8(%rbx), %rsi
movq (%rsi), %rdi
callq 0x20b0
movq 0xdd20(%rip), %rax      # 0x10fe0
movq (%rax), %rdi
movq 0x8(%rbx), %rax
movq (%rax), %rdx
leaq 0x7d86(%rip), %rsi      # 0xb057
xorl %eax, %eax
callq 0x2450
callq 0x2390
movl (%rax), %edi
callq 0x20c0