Write a shell in C/C++ **Prefer this to be written in C++** You do NOT need to b
ID: 3782575 • Letter: W
Question
Write a shell in C/C++
**Prefer this to be written in C++**
You do NOT need to be concerned with piping the output of commands to other commands or background job control
Your shell should use the fork system call and the execv system call (or one of its variants) to execute commands. The shell needs to use either wait or waitpid system calls to wait for a program to complete execution. You should recognize the command exit to mean that your shell program should terminate by calling the exit() system call.
A very simple shell such as this needs at least the following components:
a command-line parser to figure out what the user is trying to do.
If a valid command has been entered, the shell should use fork to create a new child process, and the child process should exec the command.
Your shell will need to support file redirection. Use the same syntax as defined in the Bash shell: a single '>' implies that one needs to redirect the standard output of the program being started to the referenced file while a single '<' implies the same with standard input. The double '>>' implies that standard output will append to an existing file rather than create a new file (similar behavior is required for the '<<' operator and standard input). You do not need to implement support for the Bash pipeline operator '|'.
Before calling exec to begin execution, the child process may have to close stdin (file desriptor 0) and/or stdout (file descriptor 0), open the corresponding file and use the dup2 system call to make it the appropriate file descriptor. Don't forget to use the close system call to close the old file descriptor.
Explanation / Answer
First, let us try to understand the basic pseudocode for a shell using UNIX :
int
main (int argc, char **argv)
{
while (1){
int childPid;
char * cmdLine;
printPrompt();
cmdLine= readCommandLine(); //or GNU readline("");
cmd = parseCommand(cmdLine);
record command in history list (GNU readline history ?)
if ( isBuiltInCommand(cmd)){
executeBuiltInCommand(cmd);
} else {
childPid = fork();
if (childPid == 0){
executeCommand(cmd); //calls execvp
} else {
if (isBackgroundJob(cmd)){
record in list of background jobs
} else {
waitpid (childPid);
}
}
}
}
To be able to redirect STDIN and STDOUT for the new processes by using < and >. For example, foo < infile > outfile would create a new process to run foo and assign STDIN for the new process to infile and STDOUT for the new process to outfile
First open the file (use open or creat, open read only for infiles and creat writable for outfiles ) and then use dup2. 0 is the filedescriptor for STDIN and 1 is the file descriptor for STDOUT.
dup2 (fdFileYouOpened, fileno(stdin))
dup2 (fdFileYouOpened, fileno(stdout))
Hence, the code:
if ((pid = fork()) < 0)
...error...
else if (pid == 0)
{
if (in) //if '<' char was found in string inputted by user
{
int fd0 = open(input, O_RDONLY);
dup2(fd0, STDIN_FILENO);
close(fd0);
}
if (out) //if '>' char was found in string inputted by user
{
int fd1 = creat(output , 0644) ;
dup2(fd1, STDOUT_FILENO);
close(fd1);
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.