代做shell | oop | project – UMass Boston CS 444

UMass Boston CS 444

代做shell | oop | project – 这道题目是利用oop进行的编程代写任务, 涵盖了shell/oop等方面, 这是值得参考的project代写的题目

project代写 代写project

project 4

1 Introduction

In this project, we develop a shell program calledbsh b-shell, Boston shell. It works like the classicshandbash. It accepts commands in the following syntax:

command [arg1 … argn] [< filename] [> filename] //accepting command-line arguments and performing I/O redirection

command [arg1 … argn] | command [arg1 … argn] //creating a pipe between two commands

First, create a directory in the VM.

minix# mkdir /root/proj

Next, copy four files from the instructors directory to the VM.

mic$ scp -P 2213 /home/ming/444/proj4/* root@localhost:~/proj

The files are the following.

-rw-r–r–. 1 ming 2908 Mar 29 09:40 bsh.c -rw-r–r–. 1 ming 273 Mar 29 09:40 envDemo.c -rw-r–r–. 1 ming 67 Mar 29 09:40 Makefile -rw-r–r–. 1 ming 1580 Mar 29 09:40 pipeDemo.c

2 Built-In Commands

2.1 Six Commands

B-shell has six built-in commands. Write C code to implement them do not fork a new process and then invoke existing Minix commands to accomplish the tasks. The commands are:

  1. exitexitsbsh.
  2. envlists the environment variables and their values. The syntax is as follows (onevar=value per line):
HOME=/root
HOST=minix
PWD=/root/proj
SHELL=/bin/sh
USER=root
  1. setenvsets the value of an environment variable (new or existing). The syntax is: setenv variable value
  1. unsetenvremoves a variable from the environment. The syntax is: unsetenv variable
  2. cdchanges the current working directory and updates the environment variablePWD.
  3. historylists the last 500 commands the user has entered. As you can see in the filebsh.c, the commandexitis already implemented.

2.2 Environment Variables

Environment variables are typically inherited from the parent shell. When an executable such as bshstarts running, it receives three parameters seeenvDemo.c:

int main(int argc, char *argv[], char *envp[]){ }

The first two parameters should be familiar to you:argcis the number of command-line arguments, andargvis an array of string pointers to the arguments. The third parameter is probably new to you. Just likeargv, it is an array of string pointers where each string is formatted like this:

HOME=/root

The main difference betweenargvandenvpis:

  • You know there areargcarguments inargv[]. They are stored inargv[0],argv[1],.. ., argv[argc – 1].
  • You dont know the number of environment variables right away. If there areksuch variables, they are stored inenvp[0],envp[1],.. .,envp[k 1 ]. The only way for you to know that you have reachedkis by testing forenvp[k] == NULL.

2.2.1 strsep()

Throughout this project, you often need to separate a string into several tokens. The function strsep()is handy for this purpose. It separates a string by delimiters of your choice. For example,

char tmpStr[1024], *myPath, *justPATH;

strcpy(tmpStr, "PATH=/bin:/usr/bin:/usr/pkg/bin:/usr/local/bin"); myPath = tmpStr; justPATH = strsep(myPath, "=");

The following summarizes what happened above.

  • The variabletmpStris unchanged it still points at the same address.
  • justPATHhas the same value astmpStr it points at the same address.
  • strsep()replaced the equals sign attmpStr[4]with the end-of-string char\0 if you print the string atjustPATH, you get PATH, literally.
  • myPathpoints attmpStr[5], just beyond the original equals sign if you print the string at myPath, you get/bin:/usr/bin:/usr/pkg/bin:/usr/local/bin.
  • Last but not least,strsep()is destructive the copy intmpStris altered. This is why we usedstrcpy(). The copy is tokenized, but the original PATH value can be used again. P.S. In Section 3, you l oop through the paths bystrsep(myPath, ":").

2.2.2 Implement Environment Variables

To implementenv,setenv, andunsetenv, you need to do the following:

  • At the beginning ofbsh, loop throughenvpandmake a copyof the environment variables to the memory space of your code. If you dont make a copy and later try to change the values directly inenvp, disasters segmentation faults will strike. To store the environment variables, it is easier to use an array than a linked list. You can assume that there are no more than 64 variables bsh.chas#define MAXENV 64
  • When the users ofbsh you and the instructor try tosetenv, you search your copy of the variables. If it is an existing variable, you shouldmalloc()a new string, save the new value, andfree()the old string. If you dontmalloc()a new string, the existing space may not be long enough to hold the new value, and segfaults will strike. If the variable is new, you justmalloc()a new space to save it.
  • When the users try tounsetenv, you remove the variable from the list. Dont forget tofree() the memory, or else there will be memory leak.

2.3 Change Directory

You call the functionchdir()to change the working directory ofbsh. There are two cases. If the user enters justcd, youchdir()to the value of the environment variableHOME. If the user enters cd someDir, youchdir()tosomeDir. Dont forget the set the value of PWDaccordingly. When you save a new value toPWD, it is safer tomalloc()a new string with enough space. Otherwise, if the newPWDis longer than the previousPWD, segfaults may strike. Dont forget tofree()the previous memory, or else there will be memory leak.

2.4 History

The Linux commandhistorylists chronologically the last 500 commands that a user has entered. Implement this feature. Inbsh.c, there is#define MAXLINE 1024, which limits a command line to be no more than 1024 bytes. Given this, it is easier to use an array of 500 pointers, each pointing to a string of 1,024 bytes, so that you dont need tomalloc()andfree()all the time. However, before the user has entered 500 commands, you need a way to know which history slots are valid and which slots are yet to be filled.

3 Minix Commands

An environment variable calledPATHhas a list of directories that contain Minix executables. When a command entered by the user is not one of the built-in commands,bshshould check to see if the command exists in one of the directories inPATH. You need to do the following:

  • Iterate through the directories listed inPATH
    • Usestrsep()to separate the paths. However, you shouldmake a copyof PATH=… and applystrsep()to the copy, becausestrsep()is destructive. You must keep the original copy ofPATH=… intact so that you can use it again.
  • Append the user command to the end of a path to make an absolute path. For example, if the user command isls, and you have extracted a path/binfromPATH, then you concatenate them to create an absolute path/bin/ls.
  • Use the functionaccess()to see if the absolute path is a valid executable.
  • Ifaccess()says it is indeed an executable, you run it immediately as follows ignore the rest of directories inPATH – Usefork()to generate a child process – Make the parent process wait for the child – In the child process, callexecv()with the appropriate parameters to run the executable. Seebsh.cfor details.
  • If the command does not appear anywhere in the paths, an error message should be printed. To implement the full functionality ofbsh, you may need several system calls: fork(),wait(), waitpid(),execv(),chdir(),access(). You can find their manual pages by themancommand in Minix:minix# man fork, or you can googleman forkin a browser.

4 I/O Redirection

B-shell needs to be able to handle redirection ofstdinandstdout. The following commands are examples of I/O redirection.

bsh> ls > tmp.txt //Redirects stdout to the file tmp.txt bsh> wc < tmp.txt //Redirects stdin from the file tmp.txt bsh> wc < in.txt > out.txt //Redirects stdin from in.txt, stdout to out.txt

When a child process is created using the system callfork(), it gets a copy of its parents file descriptor table. Included in this table are the file descriptors forstdin(fd 0) andstdout(fd 1 ). Each of these can be redirected by closing them and then creating a new file descriptor in their place using the system callsopen(),close(), anddup(). For instance, to redirect output from stdoutto the filetmp.txt, you do the following:

fid = open("tmp.txt", O_WRONLY | O_CREAT); close(1); //closes stdout dup(fid); //fid is now associated with fd 1 close(fid); //fid is no longer needed; use fd 1 instead

The system calldup()duplicatesfidto the first available entry in the file descriptor table, in this case,fd 1, because it was just closed at the previous line.

5 Parsing User Commands

If the user enters commands in a clean way that all parts are separated by spaces, for example, cat in.txt | wc > out.txt, the functionstrsep()is all you need to tokenize the command line. Here, you implement a way to allow the instructor to enter a command like:

cat in.txt|wc>out.txt

You can write C code or use the Minix utilityflex.

6 Pipe

A pipe is a one-way communication channel between two processes. One processes writes to one end of the pipe, and the other process reads from the other end. The process that reads from the

pipe should know it is time to exit when it reads anEOFon its input. Pipes are created using the system callpipe(). Adapt the code inpipeDemo.ctobsh.c. You are required to implement only one pipe, which connects two commands dont worry about multiple pipes connecting more than two commands.

7 Grading Rubric

Put all files in/root/proj4.

  • (10 points) Write areadMe.txtand explain what you have done and what you havent done
  • (20 points)env,setenv,unsetenv
  • (10 points)cd
  • (10 points)history
  • (20 points) Minix commands
  • (10 points) I/O redirection
  • (10 points) parsing
  • (10 points) pipe