Difference between revisions of "Shell"
(Completed "Adding a command" section) |
(→How it works: linked docs) |
||
Line 2: | Line 2: | ||
== How it works == | == How it works == | ||
− | The shell relies on the [[TTY_Driver | TTY driver]] to receive user input and provide output to the user. When XINU starts, a shell process is spawned | + | The shell relies on the [[TTY_Driver | TTY driver]] to receive user input and provide output to the user. When XINU starts, a shell process is spawned for each [[UART_Driver | serial port]] (or TTY). When a user enters a command the [http://xinu.mscs.mu.edu/docs/lexan_8c.html <code>lexan</code> function] divides the string of input into tokens. Command name, arguments, quoted strings, backgrounding, and redirection tokens are all recognized and divided by <code>lexan</code>. |
− | After the command is parsed, the shell uses the tokens to properly execute the given command. The shell first checks for the backgrounding ampersand ('&'), which should only appear as the last token. The shell is designed to handle redirection, but does not currently do so since XINU's file system is in development. Next, the command is looked up in the command table defined at the top of <code>shell/shell.c</code>. Each entry in the command table follows the format of command name, is the command built-in (ie can the command run in the background), and the function that executes the command: <code>{"command_name", TRUE / FALSE, xsh_function},</code>. Built-in commands are executed by calling the function that implements the command. All other commands are executed by creating a new process. If the user did not include the backgrounding flag in the input, the shell waits until the command process has completed before asking for more input. | + | After the command is parsed, the shell uses the tokens to properly execute the given command. The shell first checks for the backgrounding ampersand ('&'), which should only appear as the last token. The shell is designed to handle redirection, but does not currently do so since XINU's file system is in development. Next, the command is looked up in the command table defined at the top of <code>[http://xinu.mscs.mu.edu/docs/shell_8c.html shell/shell.c]</code>. Each entry in the command table follows the format of command name, is the command built-in (ie can the command run in the background), and the function that executes the command: <code>{"command_name", TRUE / FALSE, xsh_function},</code>. Built-in commands are executed by calling the function that implements the command. All other commands are executed by creating a new process. If the user did not include the backgrounding flag in the input, the shell waits until the command process has completed before asking for more input. |
== Running commands == | == Running commands == |
Revision as of 21:20, 20 September 2007
The XINU shell is a subsystem designed as an interface for interacting with the operating system.
Contents
How it works
The shell relies on the TTY driver to receive user input and provide output to the user. When XINU starts, a shell process is spawned for each serial port (or TTY). When a user enters a command the lexan
function divides the string of input into tokens. Command name, arguments, quoted strings, backgrounding, and redirection tokens are all recognized and divided by lexan
.
After the command is parsed, the shell uses the tokens to properly execute the given command. The shell first checks for the backgrounding ampersand ('&'), which should only appear as the last token. The shell is designed to handle redirection, but does not currently do so since XINU's file system is in development. Next, the command is looked up in the command table defined at the top of shell/shell.c
. Each entry in the command table follows the format of command name, is the command built-in (ie can the command run in the background), and the function that executes the command: {"command_name", TRUE / FALSE, xsh_function},
. Built-in commands are executed by calling the function that implements the command. All other commands are executed by creating a new process. If the user did not include the backgrounding flag in the input, the shell waits until the command process has completed before asking for more input.
Running commands
The current distribution of the XINU shell is equipped with some basic commands. The majority of the commands provide information about the current state of the system including its processes, memory, and hardware. A full list of commands can be obtained from the shell by using the help
command. Help on a specific command can be obtained using COMMAND --help
or help COMMAND
.
clear
: clears the shellexit
: quits the XINU shellgpiostat
: displays the current status of the GPIO pinshelp
: displays a list of commands in the XINU shellkill PID
: kills a process numberPID
led DESCRIPTOR STATUS
: turns an led on or offmemstat
: displays the current memory usage and prints the free listmemdump
: dumps a region of memoryps
: displays a table of running processesreset
: soft powercycles the backendsleep DELAY
: sleep forDELAY
secondstest
: can be used for building test programs, all builds should simply returnOK
testsuite
: run a series of tests to see if the system is functioning properlyuartstat UARTNUM
: displays statistics for uartUARTNUM
Adding commands
The shell is designed to be expandable, allowing users to add their own commands. The code that runs the shell (shell/shell.c
) and the command parser (shell/lexan.c
) do not need to change when a new command is added. The majority of the work goes into writing the actual command. After the command is written, it needs to be added to the header file (include/shell.h
), the command table (shell/shell.c
), and the make file (compile/Makefile
).
Writing the command
The command should be given its own C source file in the shell
directory, following the naming convention xsh_command.c
. All command files should include kernel.h
and shell.h
, along with any other headers necessary for the command. Function names for commands follow the same naming convention as the source file: xsh_command
. The method signature for a command is:
command xsh_command(ushort stdin, ushort stdout, ushort stderr, ushort nargs, char *args[])
Within the command, arguments are accessed via the args
array. The command name is located in arg[0]
. Subsequent arguments, up to nargs
are accessed via arg[n]
. Error checking of arguments is the responsibility of the command function. It is good practice to check for the correct number of arguments; remember the command name is counted in nargs
, so a command without any arguments should have nargs == 1
. Although not required, command functions should also allow for an argument of --help
as arg[1]
. This argument should cause the command to print out usage information. When a user types help COMMAND
in the shell, the COMMAND
is called with the --help
argument.
Additional code within the command function depends on what the command does. After the command is completed it should return OK
.
Add to command table
After the command function is written, the command needs to be added to the command table so the shell is aware of the command. The command table is an array of centry
(command entry) structures defined in shell/shell.c
. Each entry in the command table follows the format of command name, is the command built-in (ie can the command run in the background), and the function that executes the command: {"command_name", TRUE / FALSE, xsh_function},
.
Add to header and makefile
To complete the process, add the function prototype to the shell header file include/shell.h
:
command xsh_command( ushort, ushort, ushort, ushort, char *[]);
Lastly, add the command function source file to the makefile (compile/Makefile
) to ensure the command is compiled into the XINU boot image.