Skip to content
Snippets Groups Projects
Commit 22be39ff authored by dt686's avatar dt686
Browse files

Question

parent be64df0f
No related branches found
No related tags found
No related merge requests found
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_
In my code, I have these lines:
// Wait for all children
for (int i = 0; i < clist->num; i++) {
waitpid(pids[i], NULL, 0);
}
These lines ensure that the shell has to wait until all child processes complete before accepting user input. If we forgot to call waitpid() on all child processes, we may miss some process - didn't update the current status - and lead to unexpected behaviors.
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_
After calling dup2(), we have done with redicecting input and output file descriptors. Therefore, we need to close the unused pipe ends to avoid unexpected behaviors in handling file descriptors. Specificially, it may lead to the infinite loop since it's waiting to the previous process to do something, but this process never been closed.
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_
The purpose of cd command is to change the working directory of the shell. It's built into the shell, so when it's called, the shell doesn't have to search for the PATH of the chdir command. Instead, it runs immediately.
In my code, I realized that the chdir() cannot change the directory if it's in a child process (for example: ls | cd bats, so it will not change to bats). I believe it's the purpose of cd command: maintaining the current working directory in the parent process. Therefore, if cd command is an external command, it could be run within the child process and change the current working directory in the parent process, which may lead to confusion for us when working with multiple commands. Moreover, the internal command is much faster.
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_
To allow an arbitrary number of piped commands, we can modify like this:
typedef struct command_list{
int num;
cmd_buff_t *commands;
}command_list_t;
command_list_t clist;
clist.commands = malloc(sizeof(cmd_buff_t)*CMD_MAX)
Trade-offs: By using this way, we can allow an arbitrary number of piped commands, instead of having a hard limit (like 8; I included a test case about max number of commands). It will be more efficient if we really want to do some complex pipelined executions. However, we need to update the memory allocation when reaching the initial limit. Moreover, we should be careful about memory leak. It's even more complex since we will have to deal with multiple child processes as well as the parent process, instead of a single one. Therefore, it will be harder to avoid some bugs like memory leak or double free.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment