1. Your shell forks multiple child processes when executing piped commands. How does your implementation ensure that all child processes complete before the shell continues accepting user input? What would happen if you forgot to call waitpid() on all child processes?
1. Your shell forks multiple child processes when executing piped commands. How does your implementation ensure that all child processes complete before the shell continues accepting user input? What would happen if you forgot to call waitpid() on all child processes?
_answer here_
_The shell makes sure that it's all complete by calling waitpid() for each child process. It could cause a incorrect output, mess with the pointers, cause a zombie process to occur, and messy things to happen._
2. The dup2() function is used to redirect input and output file descriptors. Explain why it is necessary to close unused pipe ends after calling dup2(). What could go wrong if you leave pipes open?
2. The dup2() function is used to redirect input and output file descriptors. Explain why it is necessary to close unused pipe ends after calling dup2(). What could go wrong if you leave pipes open?
_answer here_
_Closing pipes is very necessary, it will cause memory leaks, and make the pipes open causing it to read forever, and also make sure that the pipline close correctly._
3. Your shell recognizes built-in commands (cd, exit, dragon). Unlike external commands, built-in commands do not require execvp(). Why is cd implemented as a built-in rather than an external command? What challenges would arise if cd were implemented as an external process?
3. Your shell recognizes built-in commands (cd, exit, dragon). Unlike external commands, built-in commands do not require execvp(). Why is cd implemented as a _built-in rather than an external command? What challenges would arise if cd were implemented as an external process?_
_answer here_
I think cd makes it so that the shell directory itself is changed and not the original directory, it wouldn't change our shell, and would be inefficient.
4. Currently, your shell supports a fixed number of piped commands (CMD_MAX). How would you modify your implementation to allow an arbitrary number of piped commands while still handling memory allocation efficiently? What trade-offs would you need to consider?
4. Currently, your shell supports a fixed number of piped commands (CMD_MAX). How would you modify your implementation to allow an arbitrary number of piped commands while still handling memory allocation efficiently? What trade-offs would you need to consider?
_answer here_
_So we would use dynamic memory instead and create more loops. I think the memory would be really confusing, and could cause lots of performance errors with all of the memory management we would be doing. Lots of error handling to deal with memory allocations, and failed mallocs._