Help w/ writing a custom Linux shell using x86 assembly (NASM)
I thought this might be a great start to help me with an assignment I have that requires me to write an assembly program that mimics a 32 bit Linux command shell:
When launched, your program will perform the following steps in a loop:
1. Print a prompt, specifically “$ “ to the standard output file
2. Read a single line of input from the standard input file. A line is considered to end when a line feed character (‘\n’) is encountered.
3. If the input line is “exit\n” your program must terminate
4. Otherwise, the user's input is to be treated as a command to be executed along with any arguments to be passed to that command.
5. Your program must launch the program specified by the user and pass any provided arguments along to the newly launched program. The program that you launch must, with the exceptions specified below, inherit its environment and standard file handles from your shell program. A single space shall be used to separate individual arguments on the user’s supplied command line.
6. If the specified program fails to launch you must print the message: <prog>: command not found before returning to step 1 above. Here the user's desired program name is to be substituted for <prog>. For example
$ foofoo foofoo: command not found
7. Otherwise, your shell program must then wait for the program that you launch to complete before it prints its next prompt.
8. Upon completion of the program that was launched, return to step 1.
9. Properly recognize and handle output redirection specified by the user using the “>” (greater than) symbol in a provided command line. Everything to the left of the > is considered the command to execute along with its argument list. The one and only thing to the right of the > is the name of the file to which all of the command's standard output should be saved. The output file must be created with the permissions mask 0644 (that’s octal by the way). If your shell cannot successfully open the named output file, you should print an error message (“<file>: Permission denied”) and refuse to execve the named command. For example:
$ /bin/ls -l > /etc/passwd
/etc/passwd: Permission denied
10. Properly recognize and handle piping specified by the user using the “|” (vertical bar) symbol in a provided command line. Everything to the left of the | is considered to be the producer command to execute along with its argument list. Everything to the right of the | is considered to be the consumer command to execute along with its argument list. The standard output of the producer process must be connected to the standard input of the consumer process. Your program must wait for BOTH processes to complete before returning to step 1 and printing a prompt.
I understand that I will need to use the 'execve' instruction, fork the parent process (shell), and dup2 for redirection.
I'm kinda lost as to where to start. Conceptually I am having a hard time figuring out just how a shell is created out of another shell (if I am even thinking about that the right way).
How should I start this program off, let's say forking the parent shell?