// File: /workspace/github_c_makefile_star2_O1/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 0x35e3
cmpl $0x3, (%rax)
jne 0x35e3
cmpl $0x3, (%rbx)
jne 0x38cd
cmpl $0x3, (%rbx)
jne 0x3678
testq %rax, %rax
je 0x35f9
xorl %r15d, %r15d
cmpl $0x3, (%rax)
je 0x3601
callq 0x2130
movl %eax, %r15d
callq 0x23f0
cmpl $-0x1, %eax
je 0x3824
testl %eax, %eax
je 0x3860
callq 0x39ed
movl %eax, 0x4(%rsp)
callq 0x2130
cmpl %eax, %r15d
jne 0x38c6
movq %rbx, %r15
movq 0x18(%rbx), %rbx
testq %rbx, %rbx
je 0x3640
cmpl $0x3, (%r15)
je 0x362e
movzbl 0x5(%rsp), %ebp
addl %r14d, %ebp
testq %rbx, %rbx
je 0x3842
testl %ebp, %ebp
je 0x373d
cmpl $0x5, (%r15)
movl %ebp, %esi
je 0x3745
movl (%r15), %eax
decl %eax
cmpl $0x1, %eax
jbe 0x3743
jmp 0x374f
callq 0x23f0
cmpl $-0x1, %eax
je 0x3833
testl %eax, %eax
je 0x3877
leaq 0x4(%rsp), %rsi
movl %eax, %edi
xorl %edx, %edx
callq 0x2360
testl %eax, %eax
js 0x384f
movzbl 0x5(%rsp), %ebp
addl %r14d, %ebp
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x3842
testl %ebp, %ebp
je 0x36cf
cmpl $0x5, (%rbx)
movl %ebp, %esi
je 0x36da
movl (%rbx), %eax
decl %eax
cmpl $0x1, %eax
jbe 0x36d8
jmp 0x36e1
cmpl $0x4, (%rbx)
jne 0x37a1
xorl %esi, %esi
xorl %edx, %edx
callq 0x35a9
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 0x3702
testb %al, %al
je 0x3842
movq 0x18(%rbx), %rcx
movq 0x20(%rcx), %rax
movl (%rax), %eax
cmpl $0x5, %eax
je 0x37bb
cmpl $0x4, %eax
jne 0x380d
movq %rcx, %rax
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
je 0x3810
movl (%rax), %edx
addl $-0x3, %edx
cmpl $0x2, %edx
jb 0x371e
jmp 0x3810
cmpl $0x4, (%r15)
jne 0x37ae
xorl %esi, %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x35a9
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 0x3771
testb %al, %al
je 0x3842
movq 0x18(%r15), %rcx
movq 0x20(%rcx), %rax
movl (%rax), %eax
cmpl $0x5, %eax
je 0x37e4
cmpl $0x4, %eax
jne 0x380d
movq %rcx, %rax
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
je 0x3810
movl (%rax), %edx
addl $-0x3, %edx
cmpl $0x2, %edx
jb 0x3789
jmp 0x3810
testl %ebp, %ebp
jne 0x36bd
jmp 0x36c4
testl %ebp, %ebp
jne 0x3659
jmp 0x3665
movq 0x18(%rcx), %rdx
testq %rdx, %rdx
je 0x380d
movq %rcx, %rax
movq %rdx, %rcx
movl (%rax), %edx
cmpl $0x5, %edx
je 0x37d6
cmpl $0x3, %edx
jne 0x3810
movq 0x18(%rcx), %rdx
movq %rcx, %rax
testq %rdx, %rdx
jne 0x37c7
jmp 0x3810
movq 0x18(%rcx), %rdx
testq %rdx, %rdx
je 0x380d
movq %rcx, %rax
movq %rdx, %rcx
movl (%rax), %edx
cmpl $0x5, %edx
je 0x37ff
cmpl $0x3, %edx
jne 0x3810
movq 0x18(%rcx), %rdx
movq %rcx, %rax
testq %rdx, %rdx
jne 0x37f0
jmp 0x3810
movq %rcx, %rax
movq 0x18(%rax), %rdi
testq %rdi, %rdi
je 0x3842
xorl %esi, %esi
xorl %edx, %edx
callq 0x35a9
jmp 0x3842
leaq 0x14(%rsp), %rbx
movq %rbx, %rdi
callq 0x25e0
jmp 0x3840
leaq 0x14(%rsp), %rbx
movq %rbx, %rdi
callq 0x252e
movl (%rbx), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x8843(%rip), %rdi      # 0xc099
callq 0x2430
jmp 0x36a4
leaq 0x8(%rsp), %rdi
callq 0x2240
testl %eax, %eax
jns 0x3925
callq 0x25b7
cmpq $0x0, 0x10(%rbx)
je 0x388e
movq %rbx, %rdi
callq 0x33e0
testl %eax, %eax
js 0x39bc
movq 0x8(%rbx), %rax
movq (%rax), %rax
cmpb $0x2e, (%rax)
jne 0x38ba
movb 0x1(%rax), %al
andb $-0x2, %al
cmpb $0x2e, %al
jne 0x38ba
movq %rbx, %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x34f0
testl %eax, %eax
js 0x39bc
addq $0x8, %rbx
movq %rbx, %rdi
callq 0x24f5
xorl %edi, %edi
callq 0x20c0
movl %ebp, %edi
xorl %esi, %esi
callq 0x39d2
cmpq $0x0, 0x10(%rbx)
je 0x38ed
movq %rbx, %rdi
callq 0x33e0
testl %eax, %eax
js 0x39bc
movq 0x8(%rbx), %rax
movq (%rax), %rax
cmpb $0x2e, (%rax)
jne 0x3919
movb 0x1(%rax), %al
andb $-0x2, %al
cmpb $0x2e, %al
jne 0x3919
movq %rbx, %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x34f0
testl %eax, %eax
js 0x39bc
addq $0x8, %rbx
movq %rbx, %rdi
callq 0x24bc
callq 0x23f0
testl %eax, %eax
je 0x3938
cmpl $-0x1, %eax
jne 0x3953
callq 0x2592
cmpq $0x0, 0x10(%rbx)
jne 0x397a
movl 0x8(%rsp), %edi
callq 0x2060
movl %ebp, %edi
xorl %esi, %esi
callq 0x39d2
jmp 0x3986
movl 0xc(%rsp), %edi
callq 0x2060
movl %ebp, %edi
callq 0x2060
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x39bc
movl 0x8(%rsp), %edx
movl %r14d, %esi
callq 0x35a9
jmp 0x39bc
movq %rbx, %rdi
callq 0x33e0
testl %eax, %eax
js 0x39bc
movl 0xc(%rsp), %edi
movl $0x1, %esi
callq 0x39d2
movq 0x8(%rbx), %rax
movq (%rax), %rax
cmpb $0x2e, (%rax)
jne 0x39c6
movb 0x1(%rax), %al
andb $-0x2, %al
cmpb $0x2e, %al
jne 0x39c6
movq %rbx, %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x34f0
testl %eax, %eax
jns 0x39c6
movl $0x1, %edi
callq 0x20c0
addq $0x8, %rbx
movq %rbx, %rdi
callq 0x2559