// File: /workspace/github_c_makefile_star2_O2/ebiggers[P]mysh/mysh_main.c
// Function: execute_pipeline
static int execute_pipeline(struct list_head command_tokens[],
			    unsigned ncommands)
{
	unsigned i;
	int ret;

	bool async;
	struct list_head redir_lists[ncommands];
	struct list_head cmd_arg_lists[ncommands];
	struct list_head var_assignment_lists[ncommands];
	unsigned cmd_nargs[ncommands];
	unsigned num_redirs[ncommands];

	int pipe_fds[2];
	int prev_read_end;
	pid_t child_pids[ncommands];

	mysh_assert(ncommands > 0);
	async = false;
	i = 0;
	do {
		INIT_LIST_HEAD(&cmd_arg_lists[i]);
		INIT_LIST_HEAD(&redir_lists[i]);
		INIT_LIST_HEAD(&var_assignment_lists[i]);
	} while (++i != ncommands);
	i = 0;
	do {
		ret = parse_tok_list(&command_tokens[i],
				     (i == ncommands - 1) ? &async : NULL,
				     &cmd_arg_lists[i],
				     &var_assignment_lists[i],
				     &redir_lists[i],
				     &cmd_nargs[i],
				     &num_redirs[i]);
		if (ret)
			goto out_free_lists;
	} while (++i != ncommands);

	if (mysh_noexecute)
		goto out_free_lists;

	/* If the pipeline only has one command and is not being executed
	 * asynchronously, try interpreting the command as a sequence of
	 * variable assignments or as a shell builtin.  Note: this means that
	 * with the current code, builtins cannot be used as parts of a
	 * multi-component pipeline. */
	if (ncommands == 1 && !async) {
		if (cmd_nargs[0] == 0) {
			/* No arguments: just process leading variable
			 * assignments. */
			ret = process_var_assignments(&var_assignment_lists[0]);
			goto out_free_lists;
		} else if (maybe_execute_builtin(&cmd_arg_lists[0],
						 &redir_lists[0],
						 cmd_nargs[0], &ret))
			goto out_free_lists;
		/* Not a builtin */
	}

	/* Verify that there is a command to execute for each component of the
	 * pipeline (e.g. there isn't a component that is only redirections) */
	i = 0;
	do {
		if (cmd_nargs[i] == 0) {
			mysh_error("Expected command name");
			ret = -1;
			goto out_free_lists;
		}
	} while (++i != ncommands);

	/* Execute the commands in the pipeline.  This essentially is done by
	 * fork() followed by execvp() for each command.  Redirections are
	 * handled by the forked child processes before calling execvp().  Pipes
	 * are created with pipe() before the fork.  Note that each component of
	 * the pipeline other than the first and last is involved with two
	 * different pipes: one to read from, and one to write to.  The
	 * @prev_read_end variable is used to save the read end of a pipe for
	 * the next pipeline component. */
	prev_read_end = pipe_fds[0] = pipe_fds[1] = -1;
	i = 0;
	do {
		/* Unless this is the last command, create a new pair of pipes */
		if (i != ncommands - 1) {
			if (pipe(pipe_fds)) {
				mysh_error_with_errno("can't create pipes");
				goto out_close_pipes;
			}
		}

		/* Fork the process */
		ret = fork();
		if (ret < 0) {
			/* fork() error */
			mysh_error_with_errno("can't fork child process");
			goto out_close_pipes;
		} else if (ret == 0) {
			if (async) {
				/* Background processes are executed with a new
				 * session ID and with standard input redirected
				 * from /dev/null. */
				int fd;

				errno = 0;
				setsid();
				fd = open("/dev/null", O_RDONLY);
				dup2(fd, STDIN_FILENO);
				close(fd);
				if (errno) {
					mysh_error_with_errno("problem daemonizing "
							      "background process");
				}
			}
			/* Child: set up redirections and execute new process */
			start_child(&cmd_arg_lists[i],
				    &redir_lists[i],
				    &var_assignment_lists[i],
				    cmd_nargs[i], i, ncommands,
				    pipe_fds, prev_read_end);
			/* Not reached */
			mysh_assert(0);
		}

		/* Parent: save child pid in an array */
		child_pids[i] = ret;

		/* Close any pipes we created that are no longer needed; also
		 * save the read end of the pipe (if any) in the prev_read_end
		 * variable.  */
		if (prev_read_end >= 0)
			close(prev_read_end);
		prev_read_end = pipe_fds[0];
		pipe_fds[0] = -1;
		if (pipe_fds[1] >= 0) {
			close(pipe_fds[1]);
			pipe_fds[1] = -1;
		}
	} while (++i != ncommands);
	ret = 0;
out_close_pipes:
	if (pipe_fds[0] >= 0)
		close(pipe_fds[0]);
	if (pipe_fds[1] >= 0)
		close(pipe_fds[1]);
	if (prev_read_end >= 0)
		close(prev_read_end);
	/* If no error has occurred and the pipeline is not being executed
	 * asynchronously, wait for the commands to terminate.  'ret' is set to
	 * the exit status of the last command in the pipeline.
	 *
	 * If the pipeline is to be asynchronous, don't wait for any children;
	 * just add an entry to the list of background pipelines. */
	if (ret == 0) {
		if (async)
			ret = add_background_pipeline(child_pids, ncommands);
		else
			ret = wait_for_children(child_pids, ncommands);
	}
out_free_lists:
	i = 0;
	do {
		free_string_list(&cmd_arg_lists[i]);
		free_string_list(&var_assignment_lists[i]);
		free_redir_list(&redir_lists[i]);
	} while (++i != ncommands);
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, -0x60(%rbp)
movq %rsp, %rcx
movl %esi, %eax
movq %rsp, %rdx
movq %rax, %r15
shlq $0x4, %r15
subq %r15, %rdx
movq %rdx, %rsp
movq %rsp, %rdi
subq %r15, %rdi
movq %rdi, %rsp
movq %rsp, %r8
subq %r15, %r8
movq %r8, %rsp
movq %rsp, %rbx
movq %rax, -0x58(%rbp)
leaq 0xf(,%rax,4), %rax
andq $-0x10, %rax
subq %rax, %rbx
movq %rbx, %rsp
movq %rsp, %r14
subq %rax, %r14
movq %r14, %rsp
movq %rsp, %r9
subq %rax, %r9
movq %r9, %rsp
testl %esi, %esi
je 0x3e96
movq %r9, -0x50(%rbp)
movq %rcx, -0x90(%rbp)
movb $0x0, -0x29(%rbp)
xorl %eax, %eax
leaq (%rdi,%rax), %rcx
movq %rcx, (%rdi,%rax)
movq %rcx, 0x8(%rdi,%rax)
leaq (%rdx,%rax), %rcx
movq %rcx, (%rdx,%rax)
movq %rcx, 0x8(%rdx,%rax)
leaq (%r8,%rax), %rcx
movq %rcx, (%r8,%rax)
movq %rcx, 0x8(%r8,%rax)
addq $0x10, %rax
cmpq %rax, %r15
jne 0x3a82
movq %r8, -0x68(%rbp)
movq %rdi, -0x70(%rbp)
movq %rdx, -0x78(%rbp)
movq %rsi, -0x48(%rbp)
leal -0x1(%rsi), %r12d
movq %r12, -0x88(%rbp)
shlq $0x4, %r12
xorl %r13d, %r13d
movq %rbx, -0x40(%rbp)
cmpq %r13, %r12
movl $0x0, %esi
leaq -0x29(%rbp), %rax
cmoveq %rax, %rsi
movq -0x60(%rbp), %rax
leaq (%rax,%r13), %rdi
movq -0x70(%rbp), %rax
leaq (%rax,%r13), %rdx
movq -0x68(%rbp), %rax
leaq (%rax,%r13), %rcx
movq -0x78(%rbp), %rax
leaq (%rax,%r13), %r8
subq $0x8, %rsp
movq %rbx, %r9
pushq %r14
callq 0x4e40
popq %rcx
popq %rdx
movl %eax, -0x30(%rbp)
testl %eax, %eax
jne 0x3e0d
addq $0x10, %r13
addq $0x4, %rbx
addq $0x4, %r14
cmpq %r13, %r15
jne 0x3ad8
cmpl $0x0, 0x76fd(%rip)      # 0xb238
jne 0x3e0d
cmpl $0x1, -0x48(%rbp)
jne 0x3b74
cmpb $0x0, -0x29(%rbp)
jne 0x3b74
movq -0x40(%rbp), %rax
movl (%rax), %edx
testl %edx, %edx
je 0x3c2c
leaq -0x30(%rbp), %rcx
movq -0x70(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x24cc
testb %al, %al
jne 0x3e0d
xorl %eax, %eax
movq -0x48(%rbp), %rdx
movq -0x40(%rbp), %rsi
movq -0x88(%rbp), %r12
movl %eax, %ecx
cmpl $0x0, (%rsi,%rcx,4)
je 0x3c0c
incl %eax
cmpl %eax, %edx
jne 0x3b85
leaq -0x38(%rbp), %rax
orq $-0x1, (%rax)
pushq $-0x1
popq %r14
xorl %ebx, %ebx
xorl %r13d, %r13d
movq -0x50(%rbp), %r15
cmpq %r13, %r12
je 0x3bbe
leaq -0x38(%rbp), %rdi
callq 0x21d0
testl %eax, %eax
jne 0x3c4a
callq 0x23b0
movl %eax, -0x30(%rbp)
testl %eax, %eax
js 0x3c23
je 0x3eb5
movl %eax, (%r15,%r13,4)
testl %r14d, %r14d
js 0x3be1
movl %r14d, %edi
callq 0x21c0
movl -0x38(%rbp), %r14d
movl -0x34(%rbp), %edi
orl $-0x1, -0x38(%rbp)
testl %edi, %edi
js 0x3bf9
callq 0x21c0
orl $-0x1, -0x34(%rbp)
incq %r13
addq $-0x10, %rbx
cmpl %r13d, -0x58(%rbp)
jne 0x3ba8
andl $0x0, -0x30(%rbp)
jmp 0x3c58
leaq 0x39b0(%rip), %rdi      # 0x75c3
xorl %eax, %eax
callq 0x5ef8
orl $-0x1, -0x30(%rbp)
jmp 0x3e0d
leaq 0x39c2(%rip), %rdi      # 0x75ec
jmp 0x3c51
movq -0x68(%rbp), %r14
movq %r14, %rbx
movq (%rbx), %rbx
cmpq %r14, %rbx
je 0x3e09
movq -0x18(%rbx), %rdi
callq 0x452d
jmp 0x3c33
leaq 0x3988(%rip), %rdi      # 0x75d9
xorl %eax, %eax
callq 0x5fb7
movl -0x38(%rbp), %edi
testl %edi, %edi
js 0x3c64
callq 0x21c0
movl -0x34(%rbp), %edi
testl %edi, %edi
js 0x3c70
callq 0x21c0
testl %r14d, %r14d
js 0x3c7d
movl %r14d, %edi
callq 0x21c0
cmpl $0x0, -0x30(%rbp)
jne 0x3e0d
cmpb $0x1, -0x29(%rbp)
jne 0x3cda
movq -0x58(%rbp), %rax
leaq 0x20(,%rax,4), %rdi
leaq (,%rax,4), %r14
callq 0x6099
movq %rax, %r13
pushq $0x1
popq %rbx
leaq 0x7545(%rip), %rax      # 0xb1f8
movq %rax, %rcx
movq -0x50(%rbp), %rsi
movq -0x88(%rbp), %r8
movq (%rcx), %rcx
cmpq %rax, %rcx
je 0x3dac
movl 0x10(%rcx), %edx
leal 0x1(%rdx), %edi
cmpl %edx, %ebx
cmovbel %edi, %ebx
jmp 0x3cc1
movb $0x0, 0x7547(%rip)      # 0xb228
leaq 0x3e4(%rip), %rdi       # 0x40cc
callq 0x4083
pushq $0x2
popq %r13
movq -0x50(%rbp), %r12
movq -0x58(%rbp), %r14
xorl %ecx, %ecx
movq -0x50(%rbp), %rax
movq %rcx, -0x40(%rbp)
movl (%rax,%rcx,4), %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %edi
leaq -0x7c(%rbp), %rsi
xorl %edx, %edx
callq 0x22b0
cmpl $-0x1, %eax
jne 0x3d75
callq 0x2060
cmpl $0x4, (%rax)
jne 0x3d5f
cmpb $0x1, 0x74fb(%rip)      # 0xb228
jne 0x3d5f
xorl %ebx, %ebx
movl (%r12,%rbx,4), %r15d
movl %r15d, %edi
movl %r13d, %esi
callq 0x2270
testl %eax, %eax
je 0x3d55
leaq 0x3a72(%rip), %rdi      # 0x77bd
movl %r15d, %esi
xorl %eax, %eax
callq 0x5fb7
incq %rbx
cmpl %ebx, %r14d
jne 0x3d31
jmp 0x3d09
leaq 0x3a1f(%rip), %rdi      # 0x7785
movl -0x60(%rbp), %esi
xorl %eax, %eax
callq 0x5fb7
pushq $-0x1
popq %rbx
jmp 0x3d82
movl -0x7c(%rbp), %eax
pushq $-0x1
popq %rbx
testb $0x7f, %al
jne 0x3d82
movzbl %ah, %ebx
movq -0x40(%rbp), %rcx
incq %rcx
decq %r14
addq $0x4, %r12
cmpl -0x58(%rbp), %ecx
jne 0x3cfb
cmpb $0x0, 0x7488(%rip)      # 0xb228
jne 0x3da7
callq 0x42a5
movl %ebx, -0x30(%rbp)
jmp 0x3e0d
movl %ebx, 0x10(%r13)
movq -0x48(%rbp), %rax
movl %eax, 0x14(%r13)
movl (%rsi,%r8,4), %r15d
movl %r15d, 0x7479(%rip)     # 0xb23c
movl %r15d, 0x18(%r13)
movq %r13, %rdi
addq $0x1c, %rdi
movq %r14, %rdx
callq 0x2260
movq 0x7423(%rip), %rax      # 0xb200
leaq 0x7414(%rip), %rcx      # 0xb1f8
movq %r13, 0x7415(%rip)      # 0xb200
movq %rcx, (%r13)
movq %rax, 0x8(%r13)
movq %r13, (%rax)
leaq 0x397f(%rip), %rdi      # 0x777c
movl %ebx, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x2140
andl $0x0, -0x30(%rbp)
xorl %r14d, %r14d
movq -0x48(%rbp), %r13
movq %r14, %rbx
shlq $0x4, %rbx
movq -0x70(%rbp), %rax
leaq (%rax,%rbx), %rdi
callq 0x61ae
movq -0x68(%rbp), %rax
leaq (%rax,%rbx), %rdi
callq 0x61ae
movq -0x78(%rbp), %rax
leaq (%rax,%rbx), %r15
movq (%rax,%rbx), %rbx
cmpq %r15, %rbx
je 0x3e75
movq (%rbx), %r12
movq 0x8(%rbx), %rax
movq %rax, 0x8(%r12)
movq %r12, (%rax)
cmpb $0x1, -0x20(%rbx)
jne 0x3e64
movq -0x18(%rbx), %rdi
callq 0x2050
addq $-0x20, %rbx
movq %rbx, %rdi
callq 0x2050
movq %r12, %rbx
jmp 0x3e41
incq %r14
cmpl %r13d, %r14d
jne 0x3e14
movl -0x30(%rbp), %eax
movq -0x90(%rbp), %rsp
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x36e1(%rip), %rdi      # 0x757e
leaq 0x368b(%rip), %rsi      # 0x752f
leaq 0x36e1(%rip), %rcx      # 0x758c
movl $0x14c, %edx            # imm = 0x14C
callq 0x2160
cmpb $0x1, -0x29(%rbp)
jne 0x3f03
callq 0x2060
movq %rax, %r15
andl $0x0, (%rax)
callq 0x21e0
leaq 0x3733(%rip), %rdi      # 0x7605
xorl %esi, %esi
xorl %eax, %eax
callq 0x22c0
movl %eax, %r12d
movl %eax, %edi
xorl %esi, %esi
callq 0x2120
movl %r12d, %edi
callq 0x21c0
cmpl $0x0, (%r15)
je 0x3f03
leaq 0x3713(%rip), %rdi      # 0x760f
xorl %eax, %eax
callq 0x5fb7
movq -0x70(%rbp), %rdi
subq %rbx, %rdi
movq -0x78(%rbp), %rsi
subq %rbx, %rsi
movq -0x68(%rbp), %rdx
subq %rbx, %rdx
movq -0x40(%rbp), %rax
movl (%rax,%r13,4), %ecx
movl %r13d, %r8d
movq -0x48(%rbp), %r9
pushq %r14
leaq -0x38(%rbp), %rax
pushq %rax
callq 0x3f33