# Minishell A lot of amazing shell stuff ## Dependencies - libreadline-dev - libncurses-dev ##EVALS - [ ] exit code niet perse de laatste command race condition? - [ ] heredoc quote + variable expansion ## 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 ? - ~ does expand in bash but not in any quotes - `echo a '' b` = "a b" ipv "a b" ## Tester - [minishell_tester](https://github.com/LucasKuhn/minishell_tester) - [python tester](https://minishell-test.readthedocs.io/en/latest/index.html) ## TODO - CTRL+C on input line results in exit code 130 in bash. -> this is signal global - `cat | cat | ls` isn't blocking. (processes appear to be active while parent moves on) - `echo $USER" $PWD` -> match quotes and throw error. - CB command to change banner - __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` * `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. ### `` * `printf` * `int printf(const char *format, ...);` * Sends formatted output to stdout. ### `` * `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. ### `` * `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. ### `` * `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` * `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. ### `` * `exit` * `void exit(int status);` * Causes normal process termination and returns an exit status to the host environment. ### `` * `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. ### `` * `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. ### `` * `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. ### `` * `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. ### `` * `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. ### `` * `ioctl` * `int ioctl(int fd, unsigned long request, ...);` * Manipulates the underlying device parameters of special files. ### `` * `getenv` * `char *getenv(const char *name);` * Searches the environment list for a string that matches the name. ### `` * `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. ### `` * `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.