mvaldes42 / minishell

42 project - Recreate a simple shell

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Minishell

Minishell is a simple shell project for 42 school

Minishell subdivision

  1. PARSING
  2. EXECUTOR
  3. SHELL SUBSYSTEMS
  4. CALL STACK MAP

I. PARSING :

  • Lexer :

    Lexing, tokenization, lexical analysis.
    Converts a sequence of WORD into a sequence of tokens.

  • Scanning :

    Segments the input string into syntactic units called lexemes, into token classes.

  • Evaluating :

    Converts lexemes into processed values.

  • Lexeme :

    A "word". Sequence of WORD that matches a pattern for a token.

  • Token :

    String with assigned meaning with a token name & token value.

  • Parser:

    Puts tokens into a data structure called Command Table that will store the commands to be executed.

> INPUTS EXAMPLES :

echo bonjour 				> bonjour
echo -n bonjour				> bonjour%
echo -n bonjour | echo cool		> cool
echo "-n bonjour"			> -n bonjour
echo 'bonjour				> cas non prit en compte
echo "bonjour"				> bonjour
echo bonjour > test\ 1			> echo "bonjour" inside file test 1
echo $HOME				> echo $HOME variable value
echo '$HOME'				> $HOME
echo "$HOME"				> echo $HOME variable value
export a=10				> export variable a with value 10
ls >> abcd
ls <> abcd				> error
ls | grep t
sort < abcd | grep t

other examples (not always up to date with the new subject)

SIGNALS:
ctrl + c
ctrl + d
ctrl + \

> INPUTS GRAMMAR :

[command](space)[arguments]
[command](space)[options][arguments]
[command](space)[options][arguments][operator][command](space)[options][arguments]
Operators
  • pipe operator = |
  • redirection operator = < << >> >
  • (logical operator = && || )
  • (list terminator = ; )

> PARSING EXAMPLE :

Take the following command :

echo -n bonjour | echo cool'$HOME top'"$HOME super" | echo $? > txt1

1. LEXER :

a. scanning :

Run through a scanning process that separates the words :

nb word
1 echo
2 -n
3 bonjour
4 |
5 echo
6 cool
7 '$HOME top'
8 "$HOME super"
9 |
10 echo
11 $?
12 >
13 txt1

b. evaluating :

Evaluate the resulted lexemes into tokens :

token token type
echo WORD
-n WORD
bonjour WORD
| PIPE
echo WORD
cool WORD
'$HOME top' STRONG_WORD
"$HOME super" WEAK WORD
| PIPE
echo WORD
$? EXIT_STATUS
> REDIR_OUT
txt1 WORD

2. SEARCHER :

  • compares the "ALIAS" tokens against known aliases.
  • compares the "WORD" tokens against known command names, builtins.
  • searched around the environment PATH directories to find a match for it.

The order of comparing: - 1) aliases, - 2) builtins, - 3) environment path.

1) Aliases

When an alias is found, its values are stored in a structure like so :

  typedef struct s_aliases
  {
  	char	*alias_name;
  	char	*real_name;
  } t_alias;

2) Builtins

When an builtin is found, its function pointer is stored in a structure like so :

  typedef struct s_builtins
  {
  	char	*name;
  	int		(*func)(void);
  } t_builtins;

2) Environment path

In bash, if you input ENV, you will get in stdout a list of all those variables.
In order to access the environment, an external variable must be declared in the header :

  extern char **environ;

Using loops, each directory is opened and stat() checks if the commandname is there. If positive, the directory is concatenated with a slash character and also with the user’s command, and the pointer is returned to be executed.

source : https://medium.com/swlh/tutorial-to-code-a-simple-shell-in-c-9405b2d3533e

3. PARSER :

Parse the tokens into a data structure called the command table : The Command Table is an array of SimpleCommand structs.

command option arguments
echo -n bonjour
echo cool$HOME top/Usr/user42 super
echo $?
  • execute "echo -n bonjour"
  • the output is connected to the input of following command (PIPE)
  • execute "echo cool$HOME top/Usr/user42 super"
  • the output is connected to the input of following command (PIPE)
  • execute "echo $?
  • redirects output to file txt1

source : https://www.cs.purdue.edu/homes/grr/SystemsProgrammingBook/Book/Chapter5-WritingYourOwnShell.pdf

II. EXECUTOR

With the command table, and for each simple command, creates a new process.

  • Interpret: The shell reads commands from the command table and executes them.

  • Terminate: After its commands are executed, the shell executes any shutdown commands, frees up any memory, and terminates.

  • if system command, a new child will be created and then by using the execvp, execute the command, and wait until it is finished.

  • if built-in execute normally

  • for pipes, call each command into separate children using execvp.

    1. Declare an integer array of size 2 for storing file descriptors. File descriptor 0 is for reading and 1 is for writing.
    2. Open a pipe using the pipe() function.
    3. Create two children with fork
    4. Child 1->
      • Here the output has to be taken into the pipe.
      • Copy file descriptor 1 to stdout.
      • Close file descriptor 0.
      • Execute the first command using execvp()
    5. Child 2->
      • Here the input has to be taken from the pipe.
      • Copy file descriptor 0 to stdin.
      • Close file descriptor 1.
      • Execute the second command using execvp()
    6. Wait for the two children to finish in the parent.

ressource here : https://www.geeksforgeeks.org/making-linux-shell-c/

III. SUBSYSTEMS

  • environment variables
  • subshells
  • history -> http://web.mit.edu/gnu/doc/html/rlman_2.html
  • show prompt
  • PATH variable, relative & absolute
  • built-ins
    • echo (-n)
    • cd (path only)
    • pwd
    • export
    • unset
    • env
    • exit
  • redirection
  • pipes
  • signals with = ctrl + C, ctrl + D, ctrl + \
  • $?
  • ` (inhibits all interpretation of a sequence of WORD)
  • `` (same, except for $)
  • redirect STDIN and STDOUT

IV. CALL STACK

// size = ft_strlen(getcwd(cwd, sizeof(cwd))) +
// ft_strlen("\033[32m\u27A1\033[0m ") +
// ft_strlen(" \033[38;5;69m\u2613\033[0m "); // data->prompt = (char *)malloc(sizeof(char) * (size + 1)); // strcat(data->prompt, "\033[32m\u27A1\033[0m "); // strcat(data->prompt, getcwd(cwd, sizeof(cwd))); // strcat(data->prompt, " \033[38;5;69m\u2613\033[0m ");

About

42 project - Recreate a simple shell


Languages

Language:C 96.2%Language:Makefile 3.8%