Operating System代写:CSE320 SFISH Shell Part2

代写一个类似Shell功能的命令行工具,第二部分主要是处理可执行部分,调用Linux现有的命令工具。

Part II: Executables

Now that sfish has builtin support, it’s time to give it the ability to run any executable like ls, grep, and wc. If you have implemented this part of your shell correctly, you should be able to run your HW1 and HW2 assignments within your shell.

Helpful and allowed interfaces

You will have to parse the command line using readline(3) and then use fork(2) and exec(3) (or flavors of exec , such as exece, execle, etc.) to launch programs. Programs you run should take input from stdin and output to stdout and stderr (errors). You will have to study the wait(2) (and flavors of wait such as waitpid ) system call in order for your shell to return the proper status codes. You may use any system call (section 2 of the man pages) or library call (section 3 of the man pages) for this assignment, EXCEPT for system(3) .

By convention, the name of the binary is the first argument provided to a program. Check the manual of the exec variant you are using to determine whether or not you should put the binary name in the argument list.

In general, your selection of libraries is unrestricted, with one important exception: you should NEVER use the function system or the library termios , which are really just wrappers for another shell. Speaking more broadly, it is not acceptable to simply write a wrapper for another shell-you should implement your own shell for this assignment. If we find that you used the system function the termios library, or any similar functioning library, you will receive a ZERO for the assignment.

Finding programs

Shells provide a nice command-line environment by automatically searching common locations for commands. For instance, when a user types ls , the shell will automatically figure out that the binary is actually located at /bin/ls . On Linux, the paths that a program has to search in order to find binaries/executables is stored in the environment variable PATH.

In your linux shell, you can inspect your environment variables using the printenv command:

$ printenv
TERM=xterm
SHELL=/bin/bash
PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/b
in:/sbin:/bin:/usr/games:/home/cse320/bin
...

When using PATH, check if the command includes a / character. If so, you may pass this command directly to the exec system call, as the command itself is specifying a relative or absolute path. If the command does not include a / character, then the shell should try each of the values in the PATH list, e.g,: ls should be checked as /usr/lib/lightdm/lightdm/ls, /usr/local/sbin/ls, /usr/sbin/ls, /usr/bin/ls, /sbin/ls, /bin/ls, /usr/games/ls, and /home/cse320/bin/ls.

You MUST use the stat system call to check whether a file exists, rather than relying on the more expensive exec system call to fail to find out.

You may use any exec variant you like for this assignment. Each exec variant has pros/cons that you should investigate before choosing.

In general, environment variables are passed from the parent through the envp argument to main. Be sure to parse these variables so that you can use them to find programs, as well as pass them to child processes.

The following features must be implemented:

  • Use the PATH environment variable to search for commands. If the entered command is found then it should be executed.

  • Handle the case where a command is not found.