# Minishell
A lot of amazing shell stuff
## Dependencies
- libreadline-dev
- libncurses-dev

## Comments on work
- Checked if path is a directory and send appropriate message
- `executor_absolute_path` => extracted some code into helpers to make it norminette compliant
- `executor_child` => refactored putstr_fd into error_msg | checked if file on path is exectuable to show permission denied where applicable
- `lexer_token_next` => extracted code for norminette
- `parser` => **A LOT** of work in all files for norminette compliancy
- `expander_parse_string` => Fixed so that $HOME/test.txt returns the correct path and file

## Edge Cases
- `cat $PWD/test` should expand,
- `cd -` : `bash: cd: OLDPWD not set`
- `cd ~` : does not expand ?

## Tester
- [minishell_tester](https://github.com/LucasKuhn/minishell_tester)
- [python tester](https://minishell-test.readthedocs.io/en/latest/index.html)


## TODO
- [ ] export without arguments
- [ ] ft_free_arr_safe in environment mess
- [ ] builtins not first in pipeline? wtf is happening HAHAHAHAHAH its not using builtin, but core-utils
- [ ] Remove -c option parsing as split can break
- [ ] Only `""` as input shows command not found, that invalid
- [ ] CTRL+\ during `sleep 5` should do nothing, but returns a new prompt
- [ ] echo "hello" > /root/protected.txt gives the error but still prints
- [ ] cat < filenoexit returns `minishell: minishell: unable to write to temp file: No such file or directory` but we're not writin
- __Bonus:__ Command tree for &&, ||, *

## Signals
### In interactive mode
- `ctrl - C` redisplay prompt status 130
- `ctrl - D` exit shell
- `ctrl - \`
-- Done

### During process
- `ctrl - C` SIGINT to processs status 130
- `ctrl - D`
- `ctrl - \` SIGQUIT to process core dumped status 131
-- Shows ^C

### During HEREDOC
- `ctrl - C` redisplay prompt status  130
- `ctrl - D` SEND EOF error displayed but still works status:0
- `ctrl - \` nothing

## Allowed Functions

### `<readline/readline.h>`
* `readline`
	* `char *readline(const char *prompt);`
	* Reads a line from the terminal with editing capabilities.
* `rl_clear_history`
	* `void rl_clear_history(void);`
	* Clears the history of lines read by readline.
* `rl_on_new_line`
	* `int rl_on_new_line(void);`
	* Resets the state to indicate that a new line of input is being read.
* `rl_replace_line`
	* `int rl_replace_line(const char *text, int clear_undo);`
	* Replaces the contents of the current line with text.
* `rl_redisplay`
	* `int rl_redisplay(void);`
	* Redisplays the current input line.
* `add_history`
	* `void add_history(const char *line);`
	* Adds the line to the history list.

### `<stdio.h>`
* `printf`
	* `int printf(const char *format, ...);`
	* Sends formatted output to stdout.

### `<stdlib.h>`
* `malloc`
	* `void *malloc(size_t size);`
	* Allocates size bytes of memory and returns a pointer to the allocated memory.
* `free`
	* `void free(void *ptr);`
	* Frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc.

### `<unistd.h>`
* `write`
	* `ssize_t write(int fd, const void *buf, size_t count);`
	* Writes up to count bytes from the buffer starting at buf to the file referred to by the file descriptor fd.
* `access`
	* `int access(const char *pathname, int mode);`
	* Checks the file named by pathname for accessibility according to the bit pattern contained in mode.
* `open`
	* `int open(const char *pathname, int flags, ...);`
	* Opens a file specified by pathname. The flags argument determines the file access mode and file status flags.
* `read`
	* `ssize_t read(int fd, void *buf, size_t count);`
	* Reads up to count bytes from file descriptor fd into the buffer starting at buf.
* `close`
	* `int close(int fd);`
	* Closes the file descriptor fd.
* `fork`
	* `pid_t fork(void);`
	* Creates a new process by duplicating the calling process.

### `<sys/wait.h>`
* `wait`
	* `pid_t wait(int *wstatus);`
	* Suspends execution of the calling process until one of its children terminates.
* `waitpid`
	* `pid_t waitpid(pid_t pid, int *wstatus, int options);`
	* Suspends execution of the calling process until the child specified by pid changes state.
* `wait3`
	* `pid_t wait3(int *wstatus, int options, struct rusage *rusage);`
	* Similar to wait, but also returns resource usage information.
* `wait4`
	* `pid_t wait4(pid_t pid, int *wstatus, int options, struct rusage *rusage);`
	* Similar to waitpid, but also returns resource usage information.

### `<signal.h>`
* `signal`
	* `void (*signal(int signum, void (*handler)(int)))(int);`
	* Sets a function to handle signal signum.
* `sigaction`
	* `int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);`
	* Examines and changes the action associated with a specific signal.
* `sigemptyset`
	* `int sigemptyset(sigset_t *set);`
	* Initializes the signal set pointed to by set to exclude all signals.
* `sigaddset`
	* `int sigaddset(sigset_t *set, int signum);`
	* Adds the individual signal specified by signum to the signal set pointed to by set.
* `kill`
	* `int kill(pid_t pid, int sig);`
	* Sends the signal sig to the process specified by pid.

### `<stdlib.h>`
* `exit`
	* `void exit(int status);`
	* Causes normal process termination and returns an exit status to the host environment.

### `<sys/stat.h>`
* `stat`
	* `int stat(const char *pathname, struct stat *statbuf);`
	* Retrieves information about the file pointed to by pathname and fills in the stat structure.
* `lstat`
	* `int lstat(const char *pathname, struct stat *statbuf);`
	* Similar to stat, but does not follow symbolic links.
* `fstat`
	* `int fstat(int fd, struct stat *statbuf);`
	* Retrieves information about the file referred to by the open file descriptor fd.

### `<unistd.h>`
* `unlink`
	* `int unlink(const char *pathname);`
	* Deletes a name from the filesystem.
* `pipe`
	* `int pipe(int pipefd[2]);`
	* Creates a pipe, a unidirectional data channel that can be used for interprocess communication.
* `dup`
	* `int dup(int oldfd);`
	* Duplicates the file descriptor oldfd.
* `dup2`
	* `int dup2(int oldfd, int newfd);`
	* Duplicates oldfd to newfd, closing newfd first if necessary.
* `execve`
	* `int execve(const char *pathname, char *const argv[], char *const envp[]);`
	* Executes the program referred to by pathname.
* `getcwd`
	* `char *getcwd(char *buf, size_t size);`
	* Gets the current working directory and stores it in the buffer pointed to by buf.
* `chdir`
	* `int chdir(const char *path);`
	* Changes the current working directory to the directory specified in path.

### `<dirent.h>`
* `opendir`
	* `DIR *opendir(const char *name);`
	* Opens a directory stream corresponding to the directory name, and returns a pointer to the directory stream.
* `readdir`
	* `struct dirent *readdir(DIR *dirp);`
	* Reads the next directory entry from the directory stream pointed to by dirp.
* `closedir`
	* `int closedir(DIR *dirp);`
	* Closes the directory stream associated with dirp.

### `<string.h>`
* `strerror`
	* `char *strerror(int errnum);`
	* Returns a pointer to the textual representation of the error number errnum.
* `perror`
	* `void perror(const char *s);`
	* Prints a descriptive error message to stderr.

### `<unistd.h>`
* `isatty`
	* `int isatty(int fd);`
	* Tests whether fd is an open file descriptor referring to a terminal.
* `ttyname`
	* `char *ttyname(int fd);`
	* Returns a pointer to the null-terminated pathname of the terminal associated with fd.
* `ttyslot`
	* `int ttyslot(void);`
	* Returns the index of the current user's terminal in the user accounting file.

### `<sys/ioctl.h>`
* `ioctl`
	* `int ioctl(int fd, unsigned long request, ...);`
	* Manipulates the underlying device parameters of special files.

### `<stdlib.h>`
* `getenv`
	* `char *getenv(const char *name);`
	* Searches the environment list for a string that matches the name.

### `<termios.h>`
* `tcsetattr`
	* `int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);`
	* Sets the parameters associated with the terminal referred to by fd.
* `tcgetattr`
	* `int tcgetattr(int fd, struct termios *termios_p);`
	* Gets the parameters associated with the terminal referred to by fd.

### `<term.h>`
* `tgetent`
	* `int tgetent(char *bp, const char *name);`
	* Loads the entry for name from the termcap database.
* `tgetflag`
	* `int tgetflag(const char *id);`
	* Gets the boolean entry for id from the termcap database.
* `tgetnum`
	* `int tgetnum(const char *id);`
	* Gets the numeric entry for id from the termcap database.
* `tgetstr`
	* `char *tgetstr(const char *id, char **area);`
	* Gets the string entry for id from the termcap database.
* `tgoto`
	* `char *tgoto(const char *cap, int col, int row);`
	* Returns a cursor addressing string for the given capability cap.
* `tputs`
	* `int tputs(const char *str, int affcnt, int (*putc)(int));`
	* Outputs the string str with padding.

