This is the 6.828 first section of a small job, is to implement a shell, most of the source code is given, but compile a lot of bugs and warning found, so need to read the source and then change their own.
The focus of this assignment is to understand and realize how the shell is implemented and built, especially in UNIX systems where pipelines and redirects
For some basic principles of shell implementation, see Xv6-book chapter0a
The shell needs to ensure that at any time there are three open file descriptors, which are the default file descriptors for the console
The Convention is to read from file descriptor 0, output from File descriptor 1 (standard output), output error from file descriptor 2
The first is the Gecmd read command
There are 5 types of commands:
- Execute command symbol: ""
- REDIRECT Command > or <
- List commands, that is, multiple command symbols are semicolons;
- Pipeline command, you need to first create a pipe symbol is |
- Return command (This does not know what to do), the symbol is &
There are two core functions of the whole function, one is Parsecmd, the other is Runcmd
When the command is read, first parse
The core function of Parsecmd is ParseLine
This function is recursive and executes the process:
- First execute the parsepipe to detect if there is a pipeline command, and some words to establish a pipe connection
- Detects if there is a & in the command, that is, the return command, and some words use the Parsepipe return value to generate a new backcmd
- Detect if there is, that is, whether there are more than one command to execute, if so, recursive call ParseLine, all the commands are resolved after the connection.
Here is the code
The Listcmd function above is actually very simple, that is, to connect multiple commands into a linked list
The Backcmd function is simpler to generate a pointer to a new command
and the real core function is parsepipe.
Parsepipe's function is very brief, where the first parseexec function generates the corresponding struct based on the first executable command in the input command.
The Parsepipe function is then called recursively for the rest of the part, and the Recursive generation command
Actually, Pipecmd and listcmd structure are the same.
The difference is when it's actually executed.
If it is a listcmd, it is the execution of one piece, execution of the last one executes the next article
Here's the recursive notation.
Pipeline command
And Pipecmd cannot write this, because it is the input and output of the pipeline to be built and bound to some ports.
First build a pipeline
Then fork a sub-process out, after the original output file descriptor is closed, bind the output file descriptor to the output of the pipeline, and then execute the command on the left side
For the right side of the command is the same, so that the input and output can be combined together
It is important to note that there is a need to turn off the pipe descriptor within two sub-processes
The relocation command is more interesting.
Take a look at the execution process of the relocation command
- Call ExecCmd to generate a EXECCMD structure
- Then call the Parseredirs function to change the previous execcmd to Redircmd
- Execution, first detects that it is a redircmd, executes the redirect command
The procedure here is to first turn off a file descriptor, if the redirect is, and the output is turned off, otherwise it is input, releasing the file descriptor
Then open the specified file (code is wrong at first, no flag, no permissions to create or open), give the file descriptor just released
- Then the recursive call Runcmd executes the executable function, if it is, then the output of the executable function is redirected to the file, if it is <, then the input of the executable function is redirected to the contents of the file
- Improved
In the above code, MYEXECV is written by me, because for example, to execute the LS function, you must enter the/bin/ls, in order to add the default path, I will input the command is processed
If you have your own path, execute it directly, otherwise add the default path/bin/
List command
is actually entering multiple unrelated commands at once, executing
The way of processing is also relatively simple
- Call Pasrepipe first to process the pipeline command, which will parse all the pipeline commands before the first semicolon appears
- If a semicolon is found in the input, then call the Listcmd function, which puts the previously generated cmd struct pointer in a new struct, as left, and the parsed part as right, so that it is parsed like a list in sequence
Listcmd as follows
- The execution of the time, in turn from left to right.
Summarize
At the time of insignia, there were a few words
I didn't quite understand it at first, and now I realize that from the shell design of XV6, we can see that the internal only uses a small number of common interface, but through the combination, using pipelines, redirection, etc., can achieve very complex and powerful functions
In addition, the data structure is also very good, including the chain of command links, pipe tree-like execution, etc.
MIT 6.828-operating System Engineering Homework:shell