MIT 6.828 HW2 shell
Notes of MIT 6.828 HW2
In this HW, we implement several features in a small shell.
Executing simple commands
Fill the ‘’ case in runcmd
.
1 2 3 4 5 6 7 8 9
| case ' ': ecmd = (struct execcmd*)cmd; if(ecmd->argv[0] == 0) _exit(0);
if ((execv(ecmd->argv[0], ecmd->argv) == -1)) fprintf(stderr, "execv failed\n");
break;
|
I/O redirection
Use the trick that open
will choose the smallest free file descriptor.
1 2 3 4 5 6 7 8 9 10 11
| case '>': case '<': rcmd = (struct redircmd*)cmd; close(rcmd->fd); if (open(rcmd->file, rcmd->flags, S_IRWXU) == -1) { fprintf(stderr, "open failed\n"); break; }
runcmd(rcmd->cmd); break;
|
Implement Pipes
Use pipe
and dup
. Mind to close pipefds correctly and wait for child processes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| case '|': pcmd = (struct pipecmd*)cmd; int pipefds[2]; if ((pipe(pipefds)) == -1) { fprintf(stderr, "create pipe failed\n"); }
int pid1, pid2; if ((pid1 = fork1()) == 0) { close(STDOUT_FILENO); dup(pipefds[1]); close(pipefds[0]); close(pipefds[1]); runcmd(pcmd->left); } else { if ((pid2 = fork1()) == 0) { close(STDIN_FILENO); dup(pipefds[0]); close(pipefds[0]); close(pipefds[1]); runcmd(pcmd->right); } else { close(pipefds[0]); close(pipefds[1]); wait(&r); wait(&r); } } break;
|