From 07f458c875de94eaf8af688118090ebe0210a02b Mon Sep 17 00:00:00 2001 From: hugogogo Date: Tue, 2 Nov 2021 14:39:38 +0100 Subject: [PATCH 01/13] mise a jour libft --- libft | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libft b/libft index 1401fdd..1e8aaa7 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit 1401fddfcd177d8794d41a8c7dd3b806bbb5057f +Subproject commit 1e8aaa7154cbae5f7a200ca20323ece66c99fdd3 From f93825ee59af29c03badf9f2b7b35a258d78667a Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 4 Nov 2021 14:57:34 +0100 Subject: [PATCH 02/13] descriptions functions externes dans readme --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/README.md b/README.md index 3612c40..4da7a9c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,66 @@ +## external functions : +--- +### readline : +- readline +- rl_clear_history +- rl_on_new_line +- rl_replace_line +- rl_redisplay +- add_history +### files : +- access +- open +- read +- close +- dup +- dup2 +- pipe +- stat : `int stat(const char *pathname, struct stat *statbuf);` returns information about a file, in the buffer pointed to by statbuf +- lstat : `int fstat(int fd, struct stat *statbuf);` lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to +- fstat : `int lstat(const char *pathname, struct stat *statbuf);` fstat() is identical to stat(), except that the file about which information is to be retrieved is specified by the file descriptor fd +- unlink : `int unlink(const char *pathname);` unlink() deletes a name from the filesystem +### process : +- fork +- wait +- waitpid +- wait3 +- wait4 +- exit +### signals : +- signal +- sigaction +- kill +### directories : +- getcwd : `char *getcwd(char *buf, size_t size);` returns a null-terminated string containing an absolute pathname that is the current working directory of the calling process +- chdir : `int chdir(const char *path);` changes the current working directory of the calling process to the directory specified in path +- execve : `int execve(const char *filename, char *const argv[], char *const envp[]);` executes the program pointed to by filename +- 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);` returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dirp +- closedir : `int closedir(DIR *dirp);` closes the directory stream associated with dirp +### errors : +- strerror : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum +- perror : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function +### other : +- printf +- malloc +- free +- write + +- isatty +- ttyname +- ttyslot +- ioctl +- getenv +- tcsetattr +- tcgetattr +- tgetent +- tgetflag +- tgetnum +- tgetstr +- tgoto +- tputs + + ## sommaire : --- - [1. todo list :](#markdown-header-1-todo-list) From bb44760e2b0aa44ea24d47e5a1fee50d92b1165b Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 4 Nov 2021 15:16:36 +0100 Subject: [PATCH 03/13] continue to fill readme with external functions --- README.md | 153 +++++++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 4da7a9c..0e22f61 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,82 @@ -## external functions : +## 2. external functions : --- ### readline : -- readline -- rl_clear_history -- rl_on_new_line -- rl_replace_line -- rl_redisplay -- add_history +- **readline** : `char *readline (const char *prompt);` will read a line from the terminal and return it, using prompt as a prompt +- **rl_clear_history** : ` ` +- **rl_on_new_line** : ` ` +- **rl_replace_line** : ` ` +- **rl_redisplay** : ` ` +- **add_history** : ` ` ### files : -- access -- open -- read -- close -- dup -- dup2 -- pipe -- stat : `int stat(const char *pathname, struct stat *statbuf);` returns information about a file, in the buffer pointed to by statbuf -- lstat : `int fstat(int fd, struct stat *statbuf);` lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to -- fstat : `int lstat(const char *pathname, struct stat *statbuf);` fstat() is identical to stat(), except that the file about which information is to be retrieved is specified by the file descriptor fd -- unlink : `int unlink(const char *pathname);` unlink() deletes a name from the filesystem +- **access** : `int access(const char *pathname, int mode);` checks whether the calling process can access the file pathname +- **open** : `int open(const char *pathname, int flags, [mode_t mode]);` system call opens the file specified by pathname +- **read** : `ssize_t read(int fd, void *buf, size_t count);` attempts to read up to count bytes from file descriptor fd into the buffer starting at buf +- **close** : `int close(int fd);` closes a file descriptor, so that it no longer refers to any file and may be reused +- **dup** : `int dup(int oldfd);` creates a copy of the file descriptor oldfd, using the lowest-numbered unused file descriptor for the new descriptor +- **dup2** : `int dup2(int oldfd, int newfd);` performs the same task as dup(), but instead of using the lowest-numbered unused file descriptor, it uses the file descriptor number specified in newfd +- **pipe** : `int pipe(int pipefd[2]);` creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe. pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe +- **stat** : `int stat(const char *pathname, struct stat *statbuf);` returns information about a file, in the buffer pointed to by statbuf +- **lstat** : `int fstat(int fd, struct stat *statbuf);` lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to +- **fstat** : `int lstat(const char *pathname, struct stat *statbuf);` fstat() is identical to stat(), except that the file about which information is to be retrieved is specified by the file descriptor fd +- **unlink** : `int unlink(const char *pathname);` unlink() deletes a name from the filesystem ### process : -- fork -- wait -- waitpid -- wait3 -- wait4 -- exit +- **fork** : ` ` +- **wait** : ` ` +- **waitpid** : ` ` +- **wait3** : ` ` +- **wait4** : ` ` +- **exit** : ` ` ### signals : -- signal -- sigaction -- kill +- **signal** : ` ` +- **sigaction** : ` ` +- **kill** : ` ` ### directories : -- getcwd : `char *getcwd(char *buf, size_t size);` returns a null-terminated string containing an absolute pathname that is the current working directory of the calling process -- chdir : `int chdir(const char *path);` changes the current working directory of the calling process to the directory specified in path -- execve : `int execve(const char *filename, char *const argv[], char *const envp[]);` executes the program pointed to by filename -- 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);` returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dirp -- closedir : `int closedir(DIR *dirp);` closes the directory stream associated with dirp +- **getcwd** : `char *getcwd(char *buf, size_t size);` returns a null-terminated string containing an absolute pathname that is the current working directory of the calling process +- **chdir** : `int chdir(const char *path);` changes the current working directory of the calling process to the directory specified in path +- **execve** : `int execve(const char *filename, char *const argv[], char *const envp[]);` executes the program pointed to by filename +- **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);` returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dirp +- **closedir** : `int closedir(DIR *dirp);` closes the directory stream associated with dirp ### errors : -- strerror : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum -- perror : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function +- **strerror** : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum +- **perror** : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function ### other : -- printf -- malloc -- free -- write +- **printf** : ` ` +- **malloc** : ` ` +- **free** : ` ` +- **write** : ` ` -- isatty -- ttyname -- ttyslot -- ioctl -- getenv -- tcsetattr -- tcgetattr -- tgetent -- tgetflag -- tgetnum -- tgetstr -- tgoto -- tputs +- **isatty** : ` ` +- **ttyname** : ` ` +- **ttyslot** : ` ` +- **ioctl** : ` ` +- **getenv** : ` ` +- **tcsetattr** : ` ` +- **tcgetattr** : ` ` +- **tgetent** : ` ` +- **tgetflag** : ` ` +- **tgetnum** : ` ` +- **tgetstr** : ` ` +- **tgoto** : ` ` +- **tputs** : ` ` ## sommaire : --- - [1. todo list :](#markdown-header-1-todo-list) -- [2. parsing :](#markdown-header-2-parsing) - - [2.1. methode arbre binaire :](#markdown-header-21-methode-arbre-binaire) -- [3. gerer les quotes et la separation des arguments :](#markdown-header-3-gerer-les-quotes-et-la-separation-des-arguments) - - [3.1. tentative methode 1 :](#markdown-header-31-tentative-methode-1) - - [3.1.1. pseudo code :](#markdown-header-311-pseudo-code) - - [3.1.2. application :](#markdown-header-312-application) - - [3.1.3. erreur :](#markdown-header-313-erreur) - - [3.2. tentative methode 2 :](#markdown-header-32-tentative-methode-2) - - [3.2.1. deroulement :](#markdown-header-321-deroulement) - - [3.2.2. application :](#markdown-header-322-application) - - [3.3. comportement reel chelou :](#markdown-header-33-comportement-reel-chelou) -- [4. notes :](#markdown-header-4-notes) +- [2. external functions :](#markdown-header-2-external-functions) +- [3. parsing :](#markdown-header-3-parsing) + - [3.1. methode arbre binaire :](#markdown-header-31-methode-arbre-binaire) +- [4. gerer les quotes et la separation des arguments :](#markdown-header-4-gerer-les-quotes-et-la-separation-des-arguments) + - [4.1. tentative methode 1 :](#markdown-header-41-tentative-methode-1) + - [4.1.1. pseudo code :](#markdown-header-411-pseudo-code) + - [4.1.2. application :](#markdown-header-412-application) + - [4.1.3. erreur :](#markdown-header-413-erreur) + - [4.2. tentative methode 2 :](#markdown-header-42-tentative-methode-2) + - [4.2.1. deroulement :](#markdown-header-421-deroulement) + - [4.2.2. application :](#markdown-header-422-application) + - [4.3. comportement reel chelou :](#markdown-header-43-comportement-reel-chelou) +- [5. notes :](#markdown-header-5-notes) ## 1. todo list : --- @@ -119,10 +120,10 @@ *[\go to sommaire](#markdown-header-sommaire)* -## 2. parsing : +## 3. parsing : --- -### 2.1 methode arbre binaire : +### 3.1 methode arbre binaire : [transformer arbre normal en arbre binaire](https://fr.wikipedia.org/wiki/Arbre_binaire#Transformation_d'un_arbre_quelconque_en_un_arbre_binaire) @@ -156,12 +157,12 @@ EXEMPLE : . . *[\go to sommaire](#markdown-header-sommaire)* -## 3. gerer les quotes et la separation des arguments : +## 4. gerer les quotes et la separation des arguments : --- -### 3.1 tentative methode 1 : +### 4.1 tentative methode 1 : -#### 3.1.1 pseudo code : +#### 4.1.1 pseudo code : ```text q = 0 // first quote c = 0 // count @@ -210,7 +211,7 @@ while (str[i]) *[\go to sommaire](#markdown-header-sommaire)* -#### 3.1.2 application : +#### 4.1.2 application : ```text ['][a][r][g][1][ ]['][a][r][g][2]["][ ][a][r][g][3]["] c = 0 . . . . . . . . . . . . . . . . . . @@ -253,7 +254,7 @@ c = . . . . . . . . . 0 str[i] != ' | " ; -> *[\go to sommaire](#markdown-header-sommaire)* -#### 3.1.3 erreur : +#### 4.1.3 erreur : -> comment le programme sait que cette fois il doit decrementer "c" ? en retenant dans l'ordre toutes les dernieres valeurs de "q" ! @@ -261,9 +262,9 @@ c = . . . . . . . . . 0 str[i] != ' | " ; -> *[\go to sommaire](#markdown-header-sommaire)* -### 3.2 tentative methode 2 : +### 4.2 tentative methode 2 : -#### 3.2.1 deroulement : +#### 4.2.1 deroulement : ```text .--------------------------------------------. : .--------------------------------------. : @@ -291,7 +292,7 @@ c = . . . . . . . . . 0 str[i] != ' | " ; -> *[\go to sommaire](#markdown-header-sommaire)* -#### 3.2.2 application : +#### 4.2.2 application : ```text .--. 1 : '__"__'__"__"__"__'__'__"__"__'__'__"__'__"__' @@ -321,7 +322,7 @@ c = . . . . . . . . . 0 str[i] != ' | " ; -> *[\go to sommaire](#markdown-header-sommaire)* -### 3.3 comportement reel chelou : +### 4.3 comportement reel chelou : ```text echo "_" _ @@ -366,7 +367,7 @@ _'___"___'___"_"___'___"___'_ *[\go to sommaire](#markdown-header-sommaire)* -## 4. notes : +## 5. notes : --- Ordre Interpreteur : From 533128af894c881037fd15aab110e7e394a7f337 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 4 Nov 2021 15:46:31 +0100 Subject: [PATCH 04/13] still continue to fill readme with external functions --- README.md | 126 +++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 0e22f61..325b23b 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,3 @@ -## 2. external functions : ---- -### readline : -- **readline** : `char *readline (const char *prompt);` will read a line from the terminal and return it, using prompt as a prompt -- **rl_clear_history** : ` ` -- **rl_on_new_line** : ` ` -- **rl_replace_line** : ` ` -- **rl_redisplay** : ` ` -- **add_history** : ` ` -### files : -- **access** : `int access(const char *pathname, int mode);` checks whether the calling process can access the file pathname -- **open** : `int open(const char *pathname, int flags, [mode_t mode]);` system call opens the file specified by pathname -- **read** : `ssize_t read(int fd, void *buf, size_t count);` attempts to read up to count bytes from file descriptor fd into the buffer starting at buf -- **close** : `int close(int fd);` closes a file descriptor, so that it no longer refers to any file and may be reused -- **dup** : `int dup(int oldfd);` creates a copy of the file descriptor oldfd, using the lowest-numbered unused file descriptor for the new descriptor -- **dup2** : `int dup2(int oldfd, int newfd);` performs the same task as dup(), but instead of using the lowest-numbered unused file descriptor, it uses the file descriptor number specified in newfd -- **pipe** : `int pipe(int pipefd[2]);` creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe. pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe -- **stat** : `int stat(const char *pathname, struct stat *statbuf);` returns information about a file, in the buffer pointed to by statbuf -- **lstat** : `int fstat(int fd, struct stat *statbuf);` lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to -- **fstat** : `int lstat(const char *pathname, struct stat *statbuf);` fstat() is identical to stat(), except that the file about which information is to be retrieved is specified by the file descriptor fd -- **unlink** : `int unlink(const char *pathname);` unlink() deletes a name from the filesystem -### process : -- **fork** : ` ` -- **wait** : ` ` -- **waitpid** : ` ` -- **wait3** : ` ` -- **wait4** : ` ` -- **exit** : ` ` -### signals : -- **signal** : ` ` -- **sigaction** : ` ` -- **kill** : ` ` -### directories : -- **getcwd** : `char *getcwd(char *buf, size_t size);` returns a null-terminated string containing an absolute pathname that is the current working directory of the calling process -- **chdir** : `int chdir(const char *path);` changes the current working directory of the calling process to the directory specified in path -- **execve** : `int execve(const char *filename, char *const argv[], char *const envp[]);` executes the program pointed to by filename -- **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);` returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dirp -- **closedir** : `int closedir(DIR *dirp);` closes the directory stream associated with dirp -### errors : -- **strerror** : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum -- **perror** : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function -### other : -- **printf** : ` ` -- **malloc** : ` ` -- **free** : ` ` -- **write** : ` ` - -- **isatty** : ` ` -- **ttyname** : ` ` -- **ttyslot** : ` ` -- **ioctl** : ` ` -- **getenv** : ` ` -- **tcsetattr** : ` ` -- **tcgetattr** : ` ` -- **tgetent** : ` ` -- **tgetflag** : ` ` -- **tgetnum** : ` ` -- **tgetstr** : ` ` -- **tgoto** : ` ` -- **tputs** : ` ` - - ## sommaire : --- - [1. todo list :](#markdown-header-1-todo-list) @@ -120,6 +57,69 @@ *[\go to sommaire](#markdown-header-sommaire)* +## 2. external functions : +--- +### readline : +- **readline** : `char *readline (const char *prompt);` will read a line from the terminal and return it, using prompt as a prompt +- **rl_clear_history** : ` ` +- **rl_on_new_line** : ` ` +- **rl_replace_line** : ` ` +- **rl_redisplay** : ` ` +- **add_history** : ` ` +### files : +- **access** : `int access(const char *pathname, int mode);` checks whether the calling process can access the file pathname +- **open** : `int open(const char *pathname, int flags, [mode_t mode]);` system call opens the file specified by pathname +- **read** : `ssize_t read(int fd, void *buf, size_t count);` attempts to read up to count bytes from file descriptor fd into the buffer starting at buf +- **close** : `int close(int fd);` closes a file descriptor, so that it no longer refers to any file and may be reused +- **dup** : `int dup(int oldfd);` creates a copy of the file descriptor oldfd, using the lowest-numbered unused file descriptor for the new descriptor +- **dup2** : `int dup2(int oldfd, int newfd);` performs the same task as dup(), but instead of using the lowest-numbered unused file descriptor, it uses the file descriptor number specified in newfd +- **pipe** : `int pipe(int pipefd[2]);` creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe. pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe +- **stat** : `int stat(const char *pathname, struct stat *statbuf);` returns information about a file, in the buffer pointed to by statbuf +- **lstat** : `int fstat(int fd, struct stat *statbuf);` lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that it refers to +- **fstat** : `int lstat(const char *pathname, struct stat *statbuf);` fstat() is identical to stat(), except that the file about which information is to be retrieved is specified by the file descriptor fd +- **unlink** : `int unlink(const char *pathname);` unlink() deletes a name from the filesystem +### process : +- **fork** : `pid_t fork(void);` creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process +- **wait** : `pid_t wait(int *wstatus);` suspends execution of the calling process until one of its children terminates. The call wait(&wstatus) is equivalent to: waitpid(-1, &wstatus, 0); +- **waitpid** : `pid_t waitpid(pid_t pid, int *wstatus, int options);` suspends execution of the calling process until a child specified by pid argument has changed state +- **wait3** : `pid_t wait3(int *wstatus, int options, struct rusage *rusage);` obsolete; use waitpid(2). similar to waitpid(2), but additionally return resource usage information about the child in the structure pointed to by rusage +- **wait4** : `pid_t wait4(pid_t pid, int *wstatus, int options, struct rusage *rusage);` like wait3() but additionally can be used to select a specific child +- **exit** : `void exit(int status);` causes normal process termination and the value of status & 0377 is returned to the parent (see wait()) +### signals : +- **signal** : `sighandler_t signal(int signum, sighandler_t handler(int));` sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer-defined function (a "signal handler") +- **sigaction** : `int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);` change the action taken by a process on receipt of a specific signal. +- **kill** : `int kill(pid_t pid, int sig);` send any signal to any process group or process +### directories : +- **getcwd** : `char *getcwd(char *buf, size_t size);` returns a null-terminated string containing an absolute pathname that is the current working directory of the calling process +- **chdir** : `int chdir(const char *path);` changes the current working directory of the calling process to the directory specified in path +- **execve** : `int execve(const char *filename, char *const argv[], char *const envp[]);` executes the program pointed to by filename +- **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);` returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dirp +- **closedir** : `int closedir(DIR *dirp);` closes the directory stream associated with dirp +### errors : +- **strerror** : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum +- **perror** : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function +### other : +- **printf** : `int printf(const char *format, ...);` produce output to stdout according to a specified format +- **malloc** : `void *malloc(size_t size);` allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized +- **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 bytes from the buffer starting at to the file referred to by the file descriptor + +- **isatty** : ` ` +- **ttyname** : ` ` +- **ttyslot** : ` ` +- **ioctl** : ` ` +- **getenv** : ` ` +- **tcsetattr** : ` ` +- **tcgetattr** : ` ` +- **tgetent** : ` ` +- **tgetflag** : ` ` +- **tgetnum** : ` ` +- **tgetstr** : ` ` +- **tgoto** : ` ` +- **tputs** : ` ` + + ## 3. parsing : --- From 03acb6588054ac99ad97d2c9495b64e82b2b6449 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 4 Nov 2021 17:36:19 +0100 Subject: [PATCH 05/13] external functions in readme ok --- README.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 325b23b..0567cd0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ ## 2. external functions : --- +(extracts of manuals) ### readline : - **readline** : `char *readline (const char *prompt);` will read a line from the terminal and return it, using prompt as a prompt - **rl_clear_history** : ` ` @@ -99,26 +100,31 @@ ### errors : - **strerror** : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum - **perror** : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function +### termcap : +The termcap data base describes the capabilities of hundreds of different display terminals in great detail The termcap library is provided for easy access this data base in programs that want to do terminal-independent character-based display output +- **tgetent** : `int tgetent (char *buffer, char *termtype);` finds the description of the terminal type and remembers it internally so that you can interrogate it about specific terminal capabilities +Each piece of information recorded in a terminal description is called a capability +There are three functions to use to get the value of a capability : +- **tgetflag** : `int tgetflag (char *name);` get a boolean value +- **tgetnum** : `int tgetnum (char *name);` get a capability value that is numeric +- **tgetstr** : `char *tgetstr (char *name, char **area);` get a string value +- **tgoto** : `char *tgoto (char *cstring, int hpos, int vpos)` encoding numeric parameters such as cursor positions into the terminal-specific form required for display commands +- **tputs** : `int tputs (char *string, int nlines, int (*outfun) ());` output a string containing an optional padding spec ### other : - **printf** : `int printf(const char *format, ...);` produce output to stdout according to a specified format - **malloc** : `void *malloc(size_t size);` allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized - **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 bytes from the buffer starting at to the file referred to by the file descriptor +- **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 device that is open on the file descriptor fd, or NULL on error (for example, if fd is not connected to a terminal) +- **ttyslot** : `int ttyslot(void);` returns the index of the current user's entry in some file +- **ioctl** : `int ioctl(int fd, unsigned long request, ...);` manipulates the underlying device parameters of special files. In particular, many operating characteristics of character special files (e.g., terminals) may be controlled with ioctl() requests. The argument fd must be an open file descriptor +- **getenv** : `char *getenv(const char *name);` searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string +- **tcsetattr** : `int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);` tcsetattr() only works in an environment where either a controlling terminal exists, or stdin and stderr refer to tty devices. Specifically, it does not work in a TSO environment. Changes the attributes associated with a terminal. New attributes are specified with a termios control structure. Programs should always issue a tcgetattr() first, modify the desired fields, and then issue a tcsetattr(). tcsetattr() should never be issued using a termios structure that was not obtained using tcgetattr(). tcsetattr() should use only a termios structure that was obtained by tcgetattr() +- **tcgetattr** : `int tcgetattr(int fildes, struct termios *termptr);` Gets a termios structure, which contains control information for a terminal associated with fildes. It stores that information in a memory location that termptr points to. The contents of a termios structure are described in tcsetattr() -- **isatty** : ` ` -- **ttyname** : ` ` -- **ttyslot** : ` ` -- **ioctl** : ` ` -- **getenv** : ` ` -- **tcsetattr** : ` ` -- **tcgetattr** : ` ` -- **tgetent** : ` ` -- **tgetflag** : ` ` -- **tgetnum** : ` ` -- **tgetstr** : ` ` -- **tgoto** : ` ` -- **tputs** : ` ` +*[\go to sommaire](#markdown-header-sommaire)* ## 3. parsing : --- From a6959ac1f80e415617b091bc08935422b05059c7 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 4 Nov 2021 17:37:19 +0100 Subject: [PATCH 06/13] external functions in readme ok --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 0567cd0..51dc27d 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,12 @@ - **perror** : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function ### termcap : The termcap data base describes the capabilities of hundreds of different display terminals in great detail The termcap library is provided for easy access this data base in programs that want to do terminal-independent character-based display output + - **tgetent** : `int tgetent (char *buffer, char *termtype);` finds the description of the terminal type and remembers it internally so that you can interrogate it about specific terminal capabilities + Each piece of information recorded in a terminal description is called a capability There are three functions to use to get the value of a capability : + - **tgetflag** : `int tgetflag (char *name);` get a boolean value - **tgetnum** : `int tgetnum (char *name);` get a capability value that is numeric - **tgetstr** : `char *tgetstr (char *name, char **area);` get a string value From 5a98927effb5e16d7127a4ba47492436753f1314 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Fri, 5 Nov 2021 14:38:11 +0100 Subject: [PATCH 07/13] ajout des descriptions des functions de readline --- README.md | 19 ++++++++---- test_rl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ trap | 13 ++++++++ 3 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 test_rl.c create mode 100644 trap diff --git a/README.md b/README.md index 51dc27d..27e4f4e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +## understanding some things : +- [how to send EOF to stdin of a shell process](https://unix.stackexchange.com/questions/493578/how-to-send-d-eot-character-to-stdin-of-a-shell-process) + - [get root access 1](https://vitux.com/how-to-become-root-user-in-ubuntu-command-line-using-su-and-sudo/) + - [get root access using sudo su](https://superuser.com/questions/408990/how-do-i-log-out-of-sudo-su) +- [what is a tty](https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/) + ## sommaire : --- - [1. todo list :](#markdown-header-1-todo-list) @@ -62,11 +68,11 @@ (extracts of manuals) ### readline : - **readline** : `char *readline (const char *prompt);` will read a line from the terminal and return it, using prompt as a prompt -- **rl_clear_history** : ` ` -- **rl_on_new_line** : ` ` -- **rl_replace_line** : ` ` -- **rl_redisplay** : ` ` -- **add_history** : ` ` +- **rl_clear_history** : `void rl_clear_history (void)` clear the history list by deleting all of the entries, in the same manner as the History library's clear_history() function +- **rl_on_new_line** : `int rl_on_new_line (void)` tell the update functions that we have moved onto a new (empty) line, usually after outputting a newline +- **rl_replace_line** : `void rl_replace_line (const char *text, int clear_undo)` replace the contents of rl_line_buffer with text. The point and mark are preserved, if possible. If clear_undo is non-zero, the undo list associated with the current line is cleared +- **rl_redisplay** : `void rl_redisplay (void)` change what's displayed on the screen to reflect the current contents of rl_line_buffer +- **add_history** : `bool readline_add_history (string $prompt)` save the line away in a history list of such lines ### files : - **access** : `int access(const char *pathname, int mode);` checks whether the calling process can access the file pathname - **open** : `int open(const char *pathname, int flags, [mode_t mode]);` system call opens the file specified by pathname @@ -101,7 +107,8 @@ - **strerror** : `char *strerror(int errnum);` returns a pointer to a string that describes the error code passed in the argument errnum - **perror** : `void perror(const char *s);` produces a message on standard error describing the last error encountered during a call to a system or library function ### termcap : -The termcap data base describes the capabilities of hundreds of different display terminals in great detail The termcap library is provided for easy access this data base in programs that want to do terminal-independent character-based display output +The termcap data base describes the capabilities of hundreds of different display terminals in great detail +The termcap library is provided for easy access this data base in programs that want to do terminal-independent character-based display output - **tgetent** : `int tgetent (char *buffer, char *termtype);` finds the description of the terminal type and remembers it internally so that you can interrogate it about specific terminal capabilities diff --git a/test_rl.c b/test_rl.c new file mode 100644 index 0000000..d0046c7 --- /dev/null +++ b/test_rl.c @@ -0,0 +1,92 @@ +# include +# include +# include +# include +# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include +//# include + +void handler_sigint(int id) +{ + (void)id; + write(1, "\n", 1); +} + +int main(int argc, char *argv[], char *envp[]) +{ + (void)argc; + (void)argv; + char *line_input; + char *prompt; + +// t_cmd **cmd_arr; +// char **envp; +// char *prompt_base; +// char *prompt; +// t_token *token_list; +// int last_exit_status; +// struct termios ori_termios; +// struct termios interactive_termios; +// int termios_changed; +// struct sigaction ori_signal_behaviour; +// struct sigaction signal_behaviour; + + signal(SIGINT, handler_sigint); + line_input = NULL; + prompt = strdup("\e[0;31mtest>\e[0m "); + while (1) + { + if (line_input) + free(line_input); + line_input = readline(prompt); + if (line_input && *line_input) + { + // A faire aprés être sortie du mode interactif + // - Ignorer tout les signaux + // - Remettre ori_termios +// c->signal_behaviour.sa_handler = SIG_IGN; +// sigaction(SIGINT, &c->signal_behaviour, NULL); +// sigaction(SIGQUIT, &c->signal_behaviour, NULL); +// tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); +// if (!fork()) +// { +// char *arg_test[3]; +// +// arg_test[0] = ft_strdup("sleep"); +// arg_test[1] = ft_strdup("3"); +// arg_test[2] = NULL; +// sigaction(SIGQUIT, &c->ori_signal_behaviour, NULL); +// sigaction(SIGINT, &c->ori_signal_behaviour, NULL); +// execve("/bin/sleep", arg_test, c->envp); +// } +// else +// { +// int wait_test; +// wait(&wait_test); +// c->signal_behaviour.sa_handler = sigint_handler; +// sigaction(SIGINT, &c->signal_behaviour, NULL); +// c->signal_behaviour.sa_handler = SIG_IGN; +// sigaction(SIGQUIT, &c->signal_behaviour, NULL); +// tcsetattr(STDIN_FILENO, TCSANOW, &c->interactive_termios); +// } + + printf("%s\n", line_input); + } + else if (!line_input) + write(1, "\n", 1); + } + + return (0); +} diff --git a/trap b/trap new file mode 100644 index 0000000..f89ed5a --- /dev/null +++ b/trap @@ -0,0 +1,13 @@ +#!/bin/bash + +# trap ctrl-c and call ctrl_c() +trap ctrl_c INT + +function ctrl_c() { + echo "** Trapped CTRL-C" +} + +for i in `seq 1 5`; do + sleep 1 + echo -n "." +done From 0a33916c7501c44db7396b1fba9b11deac759328 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Fri, 5 Nov 2021 16:26:27 +0100 Subject: [PATCH 08/13] tests ok pour modifier fonctionnement de minishell --- README.md | 25 ++++++++++++-- test_rl.c | 92 ------------------------------------------------- test_rl_base.c | 29 ++++++++++++++++ test_rl_modif.c | 43 +++++++++++++++++++++++ 4 files changed, 95 insertions(+), 94 deletions(-) delete mode 100644 test_rl.c create mode 100644 test_rl_base.c create mode 100644 test_rl_modif.c diff --git a/README.md b/README.md index 27e4f4e..b723992 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,30 @@ ## understanding some things : - [how to send EOF to stdin of a shell process](https://unix.stackexchange.com/questions/493578/how-to-send-d-eot-character-to-stdin-of-a-shell-process) - - [get root access 1](https://vitux.com/how-to-become-root-user-in-ubuntu-command-line-using-su-and-sudo/) - - [get root access using sudo su](https://superuser.com/questions/408990/how-do-i-log-out-of-sudo-su) + - [get root access 1](https://vitux.com/how-to-become-root-user-in-ubuntu-command-line-using-su-and-sudo/) + - [get root access using sudo su](https://superuser.com/questions/408990/how-do-i-log-out-of-sudo-su) - [what is a tty](https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/) +``` + | BASH | MINISHELL | + ----------------------------------- + | print | action | print | action | +---------------|-----------------|----------------|----------------| + | SIGINT / ctrl-C | ^C | \n | ^C | exit | + prompt> |-----------------|----------------|----------------| + | EOF / ctrl-D | exit | exit | Ø | \n | +---------------|-----------------|----------------|----------------| + | SIGINT / ctrl-C | bla^C | \n | bla^C | exit | +prompt> blabla |-----------------|----------------|----------------| + | EOF / ctrl-D | Ø | Ø | Ø | Ø | +---------------|-----------------|----------------|----------------| + +-> change signal handler for SIGINT, to print a \n instead of exit +-> change when readline receive an EOF and line is empty, to print exit and exit + -> when readline receive an EOF and line is empty, it return NULL + -> if line isn't empty it does nothing + +``` + ## sommaire : --- - [1. todo list :](#markdown-header-1-todo-list) diff --git a/test_rl.c b/test_rl.c deleted file mode 100644 index d0046c7..0000000 --- a/test_rl.c +++ /dev/null @@ -1,92 +0,0 @@ -# include -# include -# include -# include -# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include -//# include - -void handler_sigint(int id) -{ - (void)id; - write(1, "\n", 1); -} - -int main(int argc, char *argv[], char *envp[]) -{ - (void)argc; - (void)argv; - char *line_input; - char *prompt; - -// t_cmd **cmd_arr; -// char **envp; -// char *prompt_base; -// char *prompt; -// t_token *token_list; -// int last_exit_status; -// struct termios ori_termios; -// struct termios interactive_termios; -// int termios_changed; -// struct sigaction ori_signal_behaviour; -// struct sigaction signal_behaviour; - - signal(SIGINT, handler_sigint); - line_input = NULL; - prompt = strdup("\e[0;31mtest>\e[0m "); - while (1) - { - if (line_input) - free(line_input); - line_input = readline(prompt); - if (line_input && *line_input) - { - // A faire aprés être sortie du mode interactif - // - Ignorer tout les signaux - // - Remettre ori_termios -// c->signal_behaviour.sa_handler = SIG_IGN; -// sigaction(SIGINT, &c->signal_behaviour, NULL); -// sigaction(SIGQUIT, &c->signal_behaviour, NULL); -// tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); -// if (!fork()) -// { -// char *arg_test[3]; -// -// arg_test[0] = ft_strdup("sleep"); -// arg_test[1] = ft_strdup("3"); -// arg_test[2] = NULL; -// sigaction(SIGQUIT, &c->ori_signal_behaviour, NULL); -// sigaction(SIGINT, &c->ori_signal_behaviour, NULL); -// execve("/bin/sleep", arg_test, c->envp); -// } -// else -// { -// int wait_test; -// wait(&wait_test); -// c->signal_behaviour.sa_handler = sigint_handler; -// sigaction(SIGINT, &c->signal_behaviour, NULL); -// c->signal_behaviour.sa_handler = SIG_IGN; -// sigaction(SIGQUIT, &c->signal_behaviour, NULL); -// tcsetattr(STDIN_FILENO, TCSANOW, &c->interactive_termios); -// } - - printf("%s\n", line_input); - } - else if (!line_input) - write(1, "\n", 1); - } - - return (0); -} diff --git a/test_rl_base.c b/test_rl_base.c new file mode 100644 index 0000000..02d291f --- /dev/null +++ b/test_rl_base.c @@ -0,0 +1,29 @@ +# include +# include +# include + +int main(int argc, char *argv[], char *envp[]) +{ + (void)argc; + (void)argv; + char *line_input; + char *prompt; + + line_input = NULL; + prompt = strdup("\e[0;31mtest>\e[0m "); + while (1) + { + if (line_input) + free(line_input); + line_input = readline(prompt); + if (line_input && *line_input) + { + write(1, line_input, strlen(line_input)); + write(1, "\n", 1); + } + else if (!line_input) + write(1, "\n", 1); + } + + return (0); +} diff --git a/test_rl_modif.c b/test_rl_modif.c new file mode 100644 index 0000000..097cb04 --- /dev/null +++ b/test_rl_modif.c @@ -0,0 +1,43 @@ +# include +# include +# include +# include + +void handler_sigint(int id) +{ + (void)id; + write(1, "\n", 1); + rl_replace_line("", 1); + rl_on_new_line(); + rl_redisplay(); +} + +int main(int argc, char *argv[], char *envp[]) +{ + (void)argc; + (void)argv; + char *line_input; + char *prompt; + + signal(SIGINT, handler_sigint); + line_input = NULL; + prompt = strdup("\e[0;31mtest>\e[0m "); + while (1) + { + if (line_input) + free(line_input); + line_input = readline(prompt); + if (line_input && *line_input) + { + write(1, line_input, strlen(line_input)); + write(1, "\n", 1); + } + else if (!line_input) + { + write(1, "exit\n", 5); + exit(0); + } + } + + return (0); +} From d65a7011868c72a764e4d96526f9c9620a77d84f Mon Sep 17 00:00:00 2001 From: hugogogo Date: Wed, 10 Nov 2021 13:46:17 +0100 Subject: [PATCH 09/13] add ctrl-c and ctrl-d aka eof handling --- Makefile | 2 +- headers/minishell_prototypes.h | 13 +++--- srcs/init.c | 10 +---- srcs/shell_loop.c | 43 +++----------------- srcs/signals.c | 74 +++++----------------------------- 5 files changed, 26 insertions(+), 116 deletions(-) diff --git a/Makefile b/Makefile index 0f7d936..696f6f0 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ LIBFT_D = ./libft LIBFT = $(LIBFT_D)/libft.a SRCS = main.c init.c free.c generic.c \ - signals.c terminal.c \ + signals.c \ shell_loop.c shell_script.c \ lexing.c fill_token.c check_operators.c \ parsing.c \ diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index d1724d2..3e9f08d 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/11/02 14:03:51 by hulamy ### ########.fr */ +/* Updated: 2021/11/10 13:41:58 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,11 +15,12 @@ // Init int init(t_all *c, char *envp[]); -int set_signals_handling(struct sigaction *ori_signal_behaviour, - struct sigaction *signal_behaviour); -int set_terminal_attributes(struct termios *ori_termios, - struct termios *interactive_termios, - int *termios_changed); +//int set_signals_handling(struct sigaction *ori_signal_behaviour, +// struct sigaction *signal_behaviour); +int set_signals_handling(struct sigaction *signal_behaviour); +//int set_terminal_attributes(struct termios *ori_termios, +// struct termios *interactive_termios, +// int *termios_changed); // Shell modes void shell_loop(t_all *c); diff --git a/srcs/init.c b/srcs/init.c index f6e6484..814ec56 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/11/02 13:50:33 by hulamy ### ########.fr */ +/* Updated: 2021/11/10 13:43:59 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,13 +28,7 @@ int init(t_all *c, char *envp[]) c->prompt = init_prompt(c->prompt_base); if (!c->prompt) return (ft_reti_perror(0, "init_prompt() error")); - set_signals_handling(&c->ori_signal_behaviour, &c->signal_behaviour); - if (isatty(STDIN_FILENO)) - { - if (!set_terminal_attributes(&c->ori_termios, &c->interactive_termios, - &c->termios_changed)) - return (ft_reti_perror(0, "set_terminal_attributes() error")); - } + set_signals_handling(&c->signal_behaviour); return (1); } diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 878be8a..11bc76b 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,16 +6,12 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/02 14:15:04 by hulamy ### ########.fr */ +/* Updated: 2021/11/10 13:43:10 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -//static char **tokens_list_to_argv(t_token *t); // temp test -void sigint_handler(int signum); //tmp -void sigquit_aka_eof_handler(int signum); //tmp - void close_fd(t_cmd *cmd); void execute_cmd(char **envp, t_cmd **cmd_arr); @@ -33,44 +29,15 @@ void shell_loop(t_all *c) { add_history(line_input); c->token_list = input_to_tokens(line_input); - - // TEMP - // A faire aprés être sortie du mode interactif - // - Ignorer tout les signaux - // - Remettre ori_termios - c->signal_behaviour.sa_handler = SIG_IGN; - sigaction(SIGINT, &c->signal_behaviour, NULL); - sigaction(SIGQUIT, &c->signal_behaviour, NULL); - tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); - if (!fork()) - { - char *arg_test[3]; - - arg_test[0] = ft_strdup("sleep"); - arg_test[1] = ft_strdup("3"); - arg_test[2] = NULL; - sigaction(SIGQUIT, &c->ori_signal_behaviour, NULL); - sigaction(SIGINT, &c->ori_signal_behaviour, NULL); - execve("/bin/sleep", arg_test, c->envp); - } - else - { - int wait_test; - wait(&wait_test); - c->signal_behaviour.sa_handler = sigint_handler; - sigaction(SIGINT, &c->signal_behaviour, NULL); - c->signal_behaviour.sa_handler = SIG_IGN; - sigaction(SIGQUIT, &c->signal_behaviour, NULL); - tcsetattr(STDIN_FILENO, TCSANOW, &c->interactive_termios); - } - - // EXEC c->cmd_arr = parsing(c->token_list, c->envp); execute_cmd(c->envp, c->cmd_arr); ft_lstclear((t_list **)&c->token_list, free); } else if (!line_input) - write(1, "\n", 1); + { + write(1, "exit\n", 5); + exit(0); + } } } diff --git a/srcs/signals.c b/srcs/signals.c index f715783..e076bd5 100644 --- a/srcs/signals.c +++ b/srcs/signals.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ -/* Updated: 2021/10/30 14:28:08 by lperrey ### ########.fr */ +/* Updated: 2021/11/10 13:44:09 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,71 +14,19 @@ void sigint_handler(int signum) { - // Comment virer LE ^D De l'affichage ? Il ne fait pas partie de "rl_line_buffer". - if (rl_line_buffer && *rl_line_buffer) - { - return ; - } - else - { - free_exit(g_all, g_all->last_exit_status); - } - return ; -} - -/* void sigquit_aka_eof_handler(int signum) -{ - //ft_putstr_fd("TESTS\n", 1); - ft_putstr_fd("\n", 1); + (void)signum; + write(1, "\n", 1); rl_replace_line("", 1); rl_on_new_line(); rl_redisplay(); return ; -} */ - -int set_signals_handling(struct sigaction *ori_signal_behaviour, - struct sigaction *signal_behaviour) -{ - ori_signal_behaviour->sa_handler = SIG_DFL; - - /* ctrl-D exit the shell. - eof = ^D; */ - signal_behaviour->sa_handler = sigint_handler; - sigaction(SIGINT, signal_behaviour, NULL); - - /* ctrl-\ do nothing. - quit = ^\; */ - signal_behaviour->sa_handler = SIG_IGN; - //signal_behaviour->sa_handler = sigquit_aka_eof_handler; - sigaction(SIGQUIT, signal_behaviour, NULL); - - /* - ** remap (^D to ^C) and (^C to ^D) in terminal - ** ^D is now "SIGINT" (handle here) - ** ^C is now EOF (handle in shell_loop()) - */ - return (1); } -/* -ctrl-C print a new prompt on a newline. -intr = ^C; -ctrl-D exit the shell. -eof = ^D; -ctrl-\ do nothing. -quit = ^\; -*/ - -/* -speed 38400 baud; rows 22; columns 90; line = 0; -erase = ^?; kill = ^U; -eol = M-^?; eol2 = M-^?; -swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; -discard = ^O; min = 1; time = 0; --parenb -parodd -cmspar cs8 hupcl -cstopb cread -clocal -crtscts --ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany -imaxbel iutf8 -opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke --flusho -extproc -*/ +int set_signals_handling(struct sigaction *signal_behaviour) +{ + signal_behaviour->sa_handler = sigint_handler; + sigaction(SIGINT, signal_behaviour, NULL); + signal_behaviour->sa_handler = SIG_IGN; + sigaction(SIGQUIT, signal_behaviour, NULL); + return (1); +} From 47ae67ed14831a69b2dc3a98ff017b6c5b4e1b22 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 11 Nov 2021 17:44:42 +0100 Subject: [PATCH 10/13] ajout des builtins pwd cd et export --- Makefile | 2 +- README.md | 4 +- headers/minishell_prototypes.h | 13 ++-- headers/minishell_structs.h | 12 ++-- srcs/builtins/cd.c | 10 +++ srcs/builtins/export.c | 47 ++++++++++++++ srcs/builtins/pwd.c | 15 +++++ srcs/builtins/unset.c | 10 +++ srcs/execute.c | 110 --------------------------------- srcs/free.c | 6 +- srcs/parsing/parsing.c | 26 ++++---- srcs/shell_loop.c | 19 ++++-- 12 files changed, 127 insertions(+), 147 deletions(-) create mode 100644 srcs/builtins/cd.c create mode 100644 srcs/builtins/export.c create mode 100644 srcs/builtins/pwd.c create mode 100644 srcs/builtins/unset.c delete mode 100644 srcs/execute.c diff --git a/Makefile b/Makefile index 696f6f0..25c8766 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ SRCS = main.c init.c free.c generic.c \ lexing.c fill_token.c check_operators.c \ parsing.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ - env.c exit.c echo.c + cd.c pwd.c export.c unset.c exit.c env.c echo.c DIR_OBJS = builds OBJS = $(SRCS:%.c=$(DIR_OBJS)/%.o) diff --git a/README.md b/README.md index b723992..4034ec2 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ - [get root access using sudo su](https://superuser.com/questions/408990/how-do-i-log-out-of-sudo-su) - [what is a tty](https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/) -``` +```text | BASH | MINISHELL | ----------------------------------- | print | action | print | action | @@ -150,7 +150,7 @@ There are three functions to use to get the value of a capability : - **ttyname** : `char *ttyname(int fd);` returns a pointer to the null-terminated pathname of the terminal device that is open on the file descriptor fd, or NULL on error (for example, if fd is not connected to a terminal) - **ttyslot** : `int ttyslot(void);` returns the index of the current user's entry in some file - **ioctl** : `int ioctl(int fd, unsigned long request, ...);` manipulates the underlying device parameters of special files. In particular, many operating characteristics of character special files (e.g., terminals) may be controlled with ioctl() requests. The argument fd must be an open file descriptor -- **getenv** : `char *getenv(const char *name);` searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string +- **getenv** : `char *getenv(const char *name);` searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string, or NULL if not found - **tcsetattr** : `int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);` tcsetattr() only works in an environment where either a controlling terminal exists, or stdin and stderr refer to tty devices. Specifically, it does not work in a TSO environment. Changes the attributes associated with a terminal. New attributes are specified with a termios control structure. Programs should always issue a tcgetattr() first, modify the desired fields, and then issue a tcsetattr(). tcsetattr() should never be issued using a termios structure that was not obtained using tcgetattr(). tcsetattr() should use only a termios structure that was obtained by tcgetattr() - **tcgetattr** : `int tcgetattr(int fildes, struct termios *termptr);` Gets a termios structure, which contains control information for a terminal associated with fildes. It stores that information in a memory location that termptr points to. The contents of a termios structure are described in tcsetattr() diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 3e9f08d..937b5e9 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/11/10 13:41:58 by hulamy ### ########.fr */ +/* Updated: 2021/11/11 09:58:01 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,12 +15,7 @@ // Init int init(t_all *c, char *envp[]); -//int set_signals_handling(struct sigaction *ori_signal_behaviour, -// struct sigaction *signal_behaviour); int set_signals_handling(struct sigaction *signal_behaviour); -//int set_terminal_attributes(struct termios *ori_termios, -// struct termios *interactive_termios, -// int *termios_changed); // Shell modes void shell_loop(t_all *c); @@ -38,8 +33,12 @@ t_cmd **fill_cmd(t_token *token, char **envp); void cmd_expansion(t_cmd **cmd_arr, char **envp); // Builtins -int builtin_env(int argc, char *argv[], t_all *c); +int builtin_cd(int argc, char *argv[], t_all *c); +int builtin_pwd(int argc, char *argv[], t_all *c); +int builtin_export(int argc, char *argv[], t_all *c); +int builtin_unset(int argc, char *argv[], t_all *c); int builtin_exit(int argc, char *argv[], t_all *c); +int builtin_env(int argc, char *argv[], t_all *c); int builtin_echo(int argc, char *argv[], t_all *c); // Free diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 84f4fc6..fd641af 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/10/30 13:31:07 by lperrey ### ########.fr */ +/* Updated: 2021/11/10 17:33:37 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,7 +35,7 @@ typedef struct s_token enum e_token_id id; } t_token; -typedef int (*t_builtin_ptr)(int,char **,struct s_all *); +typedef int t_builtin_ptr(int,char **,struct s_all *); typedef struct s_cmd { @@ -54,10 +54,10 @@ typedef struct s_all char *prompt; t_token *token_list; int last_exit_status; - struct termios ori_termios; - struct termios interactive_termios; - int termios_changed; - struct sigaction ori_signal_behaviour; +// struct termios ori_termios; +// struct termios interactive_termios; +// int termios_changed; +// struct sigaction ori_signal_behaviour; struct sigaction signal_behaviour; } t_all; diff --git a/srcs/builtins/cd.c b/srcs/builtins/cd.c new file mode 100644 index 0000000..4626164 --- /dev/null +++ b/srcs/builtins/cd.c @@ -0,0 +1,10 @@ + +#include "minishell.h" + +int builtin_cd(int argc, char *argv[], t_all *c) +{ + (void)argc; + (void)c; + chdir(argv[1]); + return (0); +} diff --git a/srcs/builtins/export.c b/srcs/builtins/export.c new file mode 100644 index 0000000..26e6644 --- /dev/null +++ b/srcs/builtins/export.c @@ -0,0 +1,47 @@ + +#include "minishell.h" + +int getenv_position(char **envp, char *name) +{ + int i; + + i = 0; + while (envp[i] && ft_strncmp(envp[i], name, ft_strlen(name))) + i++; + if (!envp[i]) + return (-1); + return (i); +} + +int builtin_export(int argc, char *argv[], t_all *c) +{ + char **var; + int position; + + (void)argc; + var = ft_split(argv[1], '='); + position = getenv_position(c->envp, var[0]); + if (position == -1 || !ft_strchr(argv[1], '=')) + return (0); + c->envp[position] = ft_strjoin(var[0], "="); + if (var[1]) // parce que ft_strjoin return NULL si var[1] est null, pourquoi ? + c->envp[position] = ft_strjoin(c->envp[position], var[1]); + return (0); +} + +/* +** comportement de bash : +** 1. modifier une variable dans bash : +** > ca ne la modifie pas dans zsh +** > ca ne la garde pas apres exit de bash +** 2. ajouter une variable dans bash : +** > ca ne la modifie pas dans zsh +** > ca ne la garde pas apres exit de bash +** 3. ajouter une variable avec erreur : +** > 'export VARIABLE' n'exporte rien +** > 'export VARIABLE=' exporte une variable vide +** 4. ordre d'insertion d'une nouvelle variable : +** +** +*/ + diff --git a/srcs/builtins/pwd.c b/srcs/builtins/pwd.c new file mode 100644 index 0000000..7b4f630 --- /dev/null +++ b/srcs/builtins/pwd.c @@ -0,0 +1,15 @@ + +#include "minishell.h" + +int builtin_pwd(int argc, char *argv[], t_all *c) +{ + char *pwd; + + (void)argc; + (void)argv; + (void)c; + pwd = getcwd(NULL, 0); + write(1, pwd, ft_strlen(pwd)); + write(1, "\n", 1); + return (0); +} diff --git a/srcs/builtins/unset.c b/srcs/builtins/unset.c new file mode 100644 index 0000000..9377a67 --- /dev/null +++ b/srcs/builtins/unset.c @@ -0,0 +1,10 @@ + +#include "minishell.h" + +int builtin_unset(int argc, char *argv[], t_all *c) +{ + (void)argc; + (void)argv; + (void)c; + return (0); +} diff --git a/srcs/execute.c b/srcs/execute.c deleted file mode 100644 index 2933074..0000000 --- a/srcs/execute.c +++ /dev/null @@ -1,110 +0,0 @@ -#include "minishell.h" - -void close_fd(t_cmd *cmd) -{ - if (cmd->fd_in != 0) - close(cmd->fd_in); - if (cmd->fd_out != 1) - close(cmd->fd_out); -} - -void exec_cmd(char **envp, t_list *cmd_list) -{ - t_cmd *cmd; - pid_t pid; - pid_t wpid; - int status; - - while(cmd_list) - { - cmd = cmd_list->content; - pid = fork(); - if (pid == 0) - { - if (cmd->fd_in != 0) - dup2(cmd->fd_in, STDIN_FILENO); - if (cmd->fd_out != 1) - dup2(cmd->fd_out, STDOUT_FILENO); - close_fd(cmd); - execve(cmd->argv[0], cmd->argv, envp); - } - else - close_fd(cmd); - cmd_list = cmd_list->next; - } - // waitpid pour la derniere commande (pour '$?') - while ((wpid = wait(&status)) > 0); -} - -int nbr_pipes(char *input) -{ - int i; - int count; - - i = -1; - count = 0; - while (input[++i]) - if (input[i] == '|') - count++; - return (count); -} - -int handle_fdd(char *input, int fdin, t_cmd *cmd) -{ - int *pipes_fd; - int next_in; - char *tmp; - - cmd->fd_in = fdin; - cmd->fd_out = 1; - next_in = 0; - if (input + 1) - { - pipes_fd = calloc(2, sizeof(int)); - pipe(pipes_fd); - cmd->fd_out = pipes_fd[1]; - next_in = pipes_fd[0]; - } - tmp = ft_strchr(input, '>'); - if (tmp) - { - tmp[0] = '\0'; - tmp = ft_strtrim(tmp + 2, " "); // +2 for "> " - if (cmd->fd_out != 1) - close(cmd->fd_out); - cmd->fd_out = open(tmp, O_RDWR | O_TRUNC); - } - tmp = ft_strchr(input, '<'); - if (tmp) - { - tmp[0] = '\0'; - tmp = ft_strtrim(tmp + 2, " "); // +2 for "> " - if (cmd->fd_in != 0) - close(cmd->fd_in); - cmd->fd_in = open(tmp, O_RDONLY); - } -printf(" handle_fd: %s\n", input); - return (next_in); -} - -t_cmd *fill_cmd(char *input, char **envp) -{ - t_cmd *cmd; - char **input_split; - int i; - int tmp_fd; - - cmd = calloc(nbr_pipes(input), sizeof(t_cmd)); - input_split = ft_split(input, '|'); - tmp_fd = 0; - i = 0; - while (input_split[i]) - { - tmp_fd = handle_fdd(input_split[i], tmp_fd, &cmd[i]); - cmd[i].argv = ft_split(input_split[i], ' '); - cmd[i].builtin = cmd_path(cmd[i].argv, envp); - i++; - } - return (cmd); -} - diff --git a/srcs/free.c b/srcs/free.c index d02f438..e0ca7e8 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */ -/* Updated: 2021/10/30 14:18:09 by lperrey ### ########.fr */ +/* Updated: 2021/11/10 17:15:44 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,8 +18,8 @@ int free_exit(t_all *c, int exit_status) free(c->prompt); ft_lstclear((t_list **)&c->token_list, free); // a voir avec Hugo, il y a un truc qui me semble superflu dans la fonction ft_free_2d_arr(c->envp); - if (c->termios_changed) - tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); +// if (c->termios_changed) +// tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); rl_clear_history(); exit(exit_status); } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 9c01d48..d8823a7 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/02 13:49:06 by hulamy ### ########.fr */ +/* Updated: 2021/11/11 13:11:55 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -140,26 +140,26 @@ void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr) int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)) { - cmd->builtin_command = &builtin; + cmd->builtin_command = builtin; return (1); } int handle_builtin(t_cmd *cmd) { if (!ft_strncmp(cmd->argv[0], "echo", 4)) - return (fill_builtin(cmd, &builtin_echo)); -// else if (!ft_strncmp(cmd->argv[0], "cd", 2)) -// return (fill_builtin(cmd, &builtin_cd)); -// else if (!ft_strncmp(cmd->argv[0], "pwd", 3)) -// return (fill_builtin(cmd, &builtin_pwd)); -// else if (!ft_strncmp(cmd->argv[0], "export", 6)) -// return (fill_builtin(cmd, &builtin_export)); -// else if (!ft_strncmp(cmd->argv[0], "unset", 5)) -// return (fill_builtin(cmd, &builtin_unset)); + return (fill_builtin(cmd, builtin_echo)); + else if (!ft_strncmp(cmd->argv[0], "cd", 2)) + return (fill_builtin(cmd, &builtin_cd)); + else if (!ft_strncmp(cmd->argv[0], "pwd", 3)) + return (fill_builtin(cmd, builtin_pwd)); + else if (!ft_strncmp(cmd->argv[0], "export", 6)) + return (fill_builtin(cmd, &builtin_export)); + else if (!ft_strncmp(cmd->argv[0], "unset", 5)) + return (fill_builtin(cmd, &builtin_unset)); else if (!ft_strncmp(cmd->argv[0], "env", 3)) - return (fill_builtin(cmd, &builtin_env)); + return (fill_builtin(cmd, builtin_env)); else if (!ft_strncmp(cmd->argv[0], "exit", 4)) - return (fill_builtin(cmd, &builtin_exit)); + return (fill_builtin(cmd, builtin_exit)); return (0); } diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 11bc76b..cc2fec1 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,14 +6,14 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/10 13:43:10 by hulamy ### ########.fr */ +/* Updated: 2021/11/11 09:54:40 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" void close_fd(t_cmd *cmd); -void execute_cmd(char **envp, t_cmd **cmd_arr); +void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c); void shell_loop(t_all *c) { @@ -30,7 +30,7 @@ void shell_loop(t_all *c) add_history(line_input); c->token_list = input_to_tokens(line_input); c->cmd_arr = parsing(c->token_list, c->envp); - execute_cmd(c->envp, c->cmd_arr); + execute_cmd(c->envp, c->cmd_arr, c); ft_lstclear((t_list **)&c->token_list, free); } else if (!line_input) @@ -49,12 +49,13 @@ void close_fd(t_cmd *cmd) close(cmd->fd_out); } -void execute_cmd(char **envp, t_cmd **cmd_arr) +void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c) { pid_t pid; pid_t wpid; int status; int i; + int argc; i = 0; while(cmd_arr[i]) @@ -67,7 +68,15 @@ void execute_cmd(char **envp, t_cmd **cmd_arr) if (cmd_arr[i]->fd_out != 1) dup2(cmd_arr[i]->fd_out, STDOUT_FILENO); close_fd(cmd_arr[i]); - execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp); + if (cmd_arr[i]->builtin_command) + { + argc = 0; + while (cmd_arr[i]->argv[argc]) + argc++; + cmd_arr[i]->builtin_command(argc, cmd_arr[i]->argv, c); + } + else + execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp); } else close_fd(cmd_arr[i]); From 57c271b9e2770bd41f32dfb6ae350368dbbf197e Mon Sep 17 00:00:00 2001 From: hugogogo Date: Mon, 15 Nov 2021 16:09:19 +0100 Subject: [PATCH 11/13] signaux fonctionnent sur test --- headers/minishell_prototypes.h | 3 ++- srcs/builtins/export.c | 9 ++++--- srcs/builtins/unset.c | 15 ++++++++++- test_rl_modif.c | 47 +++++++++++++++++++++++++++++++--- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 937b5e9..cdc8a97 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/11/11 09:58:01 by hulamy ### ########.fr */ +/* Updated: 2021/11/12 10:45:33 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -40,6 +40,7 @@ int builtin_unset(int argc, char *argv[], t_all *c); int builtin_exit(int argc, char *argv[], t_all *c); int builtin_env(int argc, char *argv[], t_all *c); int builtin_echo(int argc, char *argv[], t_all *c); +int getenv_position(char **envp, char *name); // Free int free_exit(t_all *c, int exit_status); diff --git a/srcs/builtins/export.c b/srcs/builtins/export.c index 26e6644..9c1f923 100644 --- a/srcs/builtins/export.c +++ b/srcs/builtins/export.c @@ -22,10 +22,14 @@ int builtin_export(int argc, char *argv[], t_all *c) var = ft_split(argv[1], '='); position = getenv_position(c->envp, var[0]); if (position == -1 || !ft_strchr(argv[1], '=')) + { + ft_free_2d_arr(var); return (0); + } c->envp[position] = ft_strjoin(var[0], "="); if (var[1]) // parce que ft_strjoin return NULL si var[1] est null, pourquoi ? - c->envp[position] = ft_strjoin(c->envp[position], var[1]); + c->envp[position] = ft_strjoinfree_s1(c->envp[position], var[1]); + ft_free_2d_arr(var); return (0); } @@ -41,7 +45,6 @@ int builtin_export(int argc, char *argv[], t_all *c) ** > 'export VARIABLE' n'exporte rien ** > 'export VARIABLE=' exporte une variable vide ** 4. ordre d'insertion d'une nouvelle variable : -** -** +** > aucune idee */ diff --git a/srcs/builtins/unset.c b/srcs/builtins/unset.c index 9377a67..7e9caa4 100644 --- a/srcs/builtins/unset.c +++ b/srcs/builtins/unset.c @@ -3,8 +3,21 @@ int builtin_unset(int argc, char *argv[], t_all *c) { + int position; + (void)argc; - (void)argv; (void)c; + position = getenv_position(c->envp, argv[1]); + if (position == -1) + return (0); + while (c->envp[position]) + { +write(1, "1", 1); + free(c->envp[position]); + c->envp[position] = ft_strdup(c->envp[position + 1]); + position++; + } +write(1, "2", 1); + free(c->envp[position]); return (0); } diff --git a/test_rl_modif.c b/test_rl_modif.c index 097cb04..5e12af6 100644 --- a/test_rl_modif.c +++ b/test_rl_modif.c @@ -2,6 +2,7 @@ # include # include # include +# include void handler_sigint(int id) { @@ -12,16 +13,24 @@ void handler_sigint(int id) rl_redisplay(); } +void handler_sigint_execution(int id) +{ + (void)id; + write(1, "\n", 1); + exit(0); +} + int main(int argc, char *argv[], char *envp[]) { (void)argc; (void)argv; char *line_input; char *prompt; + pid_t pid; - signal(SIGINT, handler_sigint); + signal(SIGINT, handler_sigint); // signal handling for SINGINT while interactive mode line_input = NULL; - prompt = strdup("\e[0;31mtest>\e[0m "); + prompt = strdup("\e[0;31m>\e[0m "); while (1) { if (line_input) @@ -29,8 +38,38 @@ int main(int argc, char *argv[], char *envp[]) line_input = readline(prompt); if (line_input && *line_input) { - write(1, line_input, strlen(line_input)); - write(1, "\n", 1); + signal(SIGINT, SIG_IGN); // stop signal handling for SIGINT because end of interactive mode + pid = fork(); + if (pid == 0) + { + signal(SIGINT, handler_sigint_execution); // start signal handling for SIGINT in child process + if (!strncmp("echo", line_input, 4)) + { + write(1, "3", 2); + sleep(1); + write(1, "\b2", 2); + sleep(1); + write(1, "\b1", 2); + sleep(1); + write(1, "\b0\n", 3); + execve("/bin/echo", argv, envp); + } + else + { + write(1, line_input, strlen(line_input)); + write(1, " 3", 2); + sleep(1); + write(1, "\b2", 2); + sleep(1); + write(1, "\b1", 2); + sleep(1); + write(1, "\b0\n", 3); + exit(0); + } + } + else + wait(0); + signal(SIGINT, handler_sigint); // restart signal handling for SIGINT because re-entring in interactive mode } else if (!line_input) { From 36766501ba21c7f1447591f638e7bb691248e1f2 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Mon, 15 Nov 2021 21:56:50 +0100 Subject: [PATCH 12/13] gestion des signaux avec execve ok dans test --- README.md | 2 ++ headers/minishell_prototypes.h | 6 +++++- srcs/shell_loop.c | 17 ++++++++++++++++- srcs/signals.c | 14 ++++++++++---- test_rl_modif.c | 20 ++++++++++++++++++-- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4034ec2..7ce4ff2 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ - [get root access 1](https://vitux.com/how-to-become-root-user-in-ubuntu-command-line-using-su-and-sudo/) - [get root access using sudo su](https://superuser.com/questions/408990/how-do-i-log-out-of-sudo-su) - [what is a tty](https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/) +- [really handling process](https://stackoverflow.com/questions/47489128/handling-signals-sigstp-sigcont-sigint-with-child-process) +- [signal in a child process](https://stackoverflow.com/questions/55190460/using-signals-in-a-child-process) ```text | BASH | MINISHELL | diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index cdc8a97..d4ce5c5 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/11/12 10:45:33 by hulamy ### ########.fr */ +/* Updated: 2021/11/15 19:23:23 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,4 +57,8 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr); void print_matrix(char **matrix, char *sep); t_list *ft_lstbeforelast(t_list *lst); +// signals.c +void sigint_handler_interactiv(int signum); +void sigint_handler_execution(int signum); + #endif diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index cc2fec1..ce18887 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/11 09:54:40 by hulamy ### ########.fr */ +/* Updated: 2021/11/15 20:21:59 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,12 +57,20 @@ void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c) int i; int argc; + // put signal handling for SIGINT to ignore so parent process will not activate signal_handling_executiv while childs are in process +// c->signal_behaviour.sa_handler = SIG_IGN; +// sigaction(SIGINT, &c->signal_behaviour, NULL); +signal(SIGINT, SIG_IGN); i = 0; while(cmd_arr[i]) { pid = fork(); if (pid == 0) { + // activate singal handling for execution mode + // c->signal_behaviour.sa_handler = sigint_handler_execution; + // sigaction(SIGINT, &c->signal_behaviour, NULL); + signal(SIGINT, sigint_handler_execution); if (cmd_arr[i]->fd_in != 0) dup2(cmd_arr[i]->fd_in, STDIN_FILENO); if (cmd_arr[i]->fd_out != 1) @@ -74,9 +82,13 @@ void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c) while (cmd_arr[i]->argv[argc]) argc++; cmd_arr[i]->builtin_command(argc, cmd_arr[i]->argv, c); + exit(0); } else + { + write(1, "1", 1); execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp); + } } else close_fd(cmd_arr[i]); @@ -84,4 +96,7 @@ void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c) } // waitpid pour la derniere commande (pour '$?') while ((wpid = wait(&status)) > 0); + // put signal handling for sigint back to the signal handler for interactiv mode + c->signal_behaviour.sa_handler = sigint_handler_interactiv; + sigaction(SIGINT, &c->signal_behaviour, NULL); } diff --git a/srcs/signals.c b/srcs/signals.c index e076bd5..35b7d43 100644 --- a/srcs/signals.c +++ b/srcs/signals.c @@ -6,25 +6,31 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ -/* Updated: 2021/11/10 13:44:09 by hulamy ### ########.fr */ +/* Updated: 2021/11/15 20:08:26 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void sigint_handler(int signum) +void sigint_handler_interactiv(int signum) { (void)signum; write(1, "\n", 1); rl_replace_line("", 1); rl_on_new_line(); rl_redisplay(); - return ; +} + +void sigint_handler_execution(int signum) +{ + (void)signum; + write(1, "\n", 1); +// exit(0); } int set_signals_handling(struct sigaction *signal_behaviour) { - signal_behaviour->sa_handler = sigint_handler; + signal_behaviour->sa_handler = sigint_handler_interactiv; sigaction(SIGINT, signal_behaviour, NULL); signal_behaviour->sa_handler = SIG_IGN; sigaction(SIGQUIT, signal_behaviour, NULL); diff --git a/test_rl_modif.c b/test_rl_modif.c index 5e12af6..a043aa7 100644 --- a/test_rl_modif.c +++ b/test_rl_modif.c @@ -27,6 +27,8 @@ int main(int argc, char *argv[], char *envp[]) char *line_input; char *prompt; pid_t pid; + char **argvtmp; + int wstatus; signal(SIGINT, handler_sigint); // signal handling for SINGINT while interactive mode line_input = NULL; @@ -43,7 +45,15 @@ int main(int argc, char *argv[], char *envp[]) if (pid == 0) { signal(SIGINT, handler_sigint_execution); // start signal handling for SIGINT in child process - if (!strncmp("echo", line_input, 4)) + if (!strncmp("sleep", line_input, 5)) + { + argvtmp = malloc(sizeof(char*) * 3); + argvtmp[0] = strdup("sleep"); + argvtmp[1] = strdup("2"); + argvtmp[2] = NULL; + execve("/bin/sleep", argvtmp, envp); + } + else if (!strncmp("echo", line_input, 4)) { write(1, "3", 2); sleep(1); @@ -68,7 +78,13 @@ int main(int argc, char *argv[], char *envp[]) } } else - wait(0); + { + wait(&wstatus); + if (WIFEXITED(wstatus)) + write(1, "the child terminated normally\n", 30); + if (WIFSIGNALED(wstatus)) + write(1, "the child was terminated by a signal\n", 37); + } signal(SIGINT, handler_sigint); // restart signal handling for SIGINT because re-entring in interactive mode } else if (!line_input) From f70ee4bae00661c2fc2f3116203e44f4ec3c33a4 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Tue, 16 Nov 2021 19:11:15 +0100 Subject: [PATCH 13/13] before merging with lucky --- README.md | 2 ++ srcs/shell_loop.c | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7ce4ff2..3263a39 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ - [what is a tty](https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/) - [really handling process](https://stackoverflow.com/questions/47489128/handling-signals-sigstp-sigcont-sigint-with-child-process) - [signal in a child process](https://stackoverflow.com/questions/55190460/using-signals-in-a-child-process) +- [send signal to process and childs](https://linuxconfig.org/how-to-propagate-a-signal-to-child-processes-from-a-bash-script) +- commande utile pour tester les process parents et enfants : while true ; do ps -o pid,pgid,cmd -C bash ; sleep 0.1 ; echo "\n" ; done ```text | BASH | MINISHELL | diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index ce18887..5e37a5b 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/15 20:21:59 by hulamy ### ########.fr */ +/* Updated: 2021/11/16 13:12:52 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,14 +53,13 @@ void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c) { pid_t pid; pid_t wpid; - int status; + int wstatus; int i; int argc; // put signal handling for SIGINT to ignore so parent process will not activate signal_handling_executiv while childs are in process -// c->signal_behaviour.sa_handler = SIG_IGN; -// sigaction(SIGINT, &c->signal_behaviour, NULL); -signal(SIGINT, SIG_IGN); + c->signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGINT, &c->signal_behaviour, NULL); i = 0; while(cmd_arr[i]) { @@ -68,9 +67,8 @@ signal(SIGINT, SIG_IGN); if (pid == 0) { // activate singal handling for execution mode - // c->signal_behaviour.sa_handler = sigint_handler_execution; - // sigaction(SIGINT, &c->signal_behaviour, NULL); - signal(SIGINT, sigint_handler_execution); + c->signal_behaviour.sa_handler = sigint_handler_execution; + sigaction(SIGINT, &c->signal_behaviour, NULL); if (cmd_arr[i]->fd_in != 0) dup2(cmd_arr[i]->fd_in, STDIN_FILENO); if (cmd_arr[i]->fd_out != 1) @@ -95,7 +93,12 @@ signal(SIGINT, SIG_IGN); i++; } // waitpid pour la derniere commande (pour '$?') - while ((wpid = wait(&status)) > 0); + wpid = 1; + while (wpid > 0) + wpid = wait(&wstatus); + // to print a \n after execve was terminated by a signal + if (WIFSIGNALED(wstatus)) + write(1, "\n", 1); // put signal handling for sigint back to the signal handler for interactiv mode c->signal_behaviour.sa_handler = sigint_handler_interactiv; sigaction(SIGINT, &c->signal_behaviour, NULL);