|
|
|
|
@@ -1,281 +1,56 @@
|
|
|
|
|
## ENVP vs ENVIRON
|
|
|
|
|
- main.c
|
|
|
|
|
- free.c
|
|
|
|
|
- init.c
|
|
|
|
|
- minishell_structs.h
|
|
|
|
|
- export.c
|
|
|
|
|
- subshell_exec.c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## TESTS SIGNAUX WITH HERE-DOCS :
|
|
|
|
|
**bash**
|
|
|
|
|
|
|
|
|
|
1. dans l'exemple ci-dessous j'ecris ^D a l'emplacement où je le tape, mais en vrai il n'apparait pas dans bash
|
|
|
|
|
et j'ai mis a gauche le compte des lignes de heredocs cumulés depuis le debut du process
|
|
|
|
|
```text
|
|
|
|
|
[zsh]$ bash
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
1 > ^D bash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
2 > ^D bash: warning: here-document at line 2 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
3 > ^D bash: warning: here-document at line 3 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
4 >
|
|
|
|
|
5 > ^D bash: warning: here-document at line 4 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
6 > ^D bash: warning: here-document at line 6 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
7 > ^D bash: warning: here-document at line 7 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
8 >
|
|
|
|
|
9 >
|
|
|
|
|
10 > ^D bash: warning: here-document at line 8 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
11 > ^D bash: warning: here-document at line 11 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
12 >
|
|
|
|
|
13 >
|
|
|
|
|
14 >
|
|
|
|
|
15 > ^D bash: warning: here-document at line 12 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
16 >
|
|
|
|
|
17 >
|
|
|
|
|
18 >
|
|
|
|
|
19 > ^D bash: warning: here-document at line 16 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
20 > ^D bash: warning: here-document at line 20 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
21 > EOF
|
|
|
|
|
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
22 > ^D bash: warning: here-document at line 23 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- le texte de warning ne decrit pas la ligne du heredoc au niveau de laquelle ^D a ete pressé
|
|
|
|
|
|
|
|
|
|
- il decrit la premiere ligne de chaque heredoc (donc peut importe qu'on ai fait un heredoc de 1 ligne ou de 25 lignes, il donne le numero de la premiere), plus le nombre total de lignes de tous les heredocs depuis le debut du process (j'ai l'impression)
|
|
|
|
|
|
|
|
|
|
- et quand il rencontre un DELIMITER ca compte pour deux lignes (DELIMITER + '\n' je pense)
|
|
|
|
|
|
|
|
|
|
2. Ctrl-C quite le mode heredoc a n'importe quel moment, Ctrl-D quite le mode heredoc avec un message, uniquement si le curseur est vide
|
|
|
|
|
```text
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
> ^C
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
> sdfdffs^C
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
> ^D bash: warning: here-document at line 3 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
> blablabla^Dblabla^D^D^Dblabla ^D blabla
|
|
|
|
|
> ^D bash: warning: here-document at line 5 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
3. heredoc avec un echo interrompu par un Ctrl-D saute un ligne avant le nouveau prompt, mais pas heredoc avec un cat :
|
|
|
|
|
```text
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
> ^C
|
|
|
|
|
[bash]$ echo << EOF
|
|
|
|
|
> ^D bash: warning: here-document at line 2 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
> ^C
|
|
|
|
|
[bash]$ cat << EOF
|
|
|
|
|
> ^D bash: warning: here-document at line 4 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
[bash]$
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
4. avec une redirection dans un fichier, le heredoc ecrit dans le fichier a la reception du DELIMITER ou bien d'un Ctrl-D, mais pas d'un Ctrl-C :
|
|
|
|
|
|
|
|
|
|
- avec Ctrl-D :
|
|
|
|
|
```text
|
|
|
|
|
[bash]$ cat << EOF > file.txt
|
|
|
|
|
> hello
|
|
|
|
|
> test
|
|
|
|
|
> ^D bash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
[bash]$ cat file.txt
|
|
|
|
|
hello
|
|
|
|
|
test
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- avec Ctrl-C
|
|
|
|
|
```text
|
|
|
|
|
[bash]$ cat << EOF > file.txt
|
|
|
|
|
> bonjour
|
|
|
|
|
> heredoc a l'appareil
|
|
|
|
|
> ^C
|
|
|
|
|
[bash]$ cat file.txt
|
|
|
|
|
hello
|
|
|
|
|
test
|
|
|
|
|
```
|
|
|
|
|
5. chaque nouvelle ligne doit afficher :
|
|
|
|
|
|
|
|
|
|
- non pas les characters "> "
|
|
|
|
|
|
|
|
|
|
- mais le contenu de la variable PS2 (qui par defaut est la chaine de characater "> ")
|
|
|
|
|
|
|
|
|
|
- (au passage, les characaters "$ " affichés a la fin de chaque prompt devraient etre ceux de la variable PS1)
|
|
|
|
|
|
|
|
|
|
- [infos ici](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03)
|
|
|
|
|
|
|
|
|
|
6. un heredoc interrompu par un Ctrl-D n'arrete pas la pipeline, mais un Ctrl-C si :
|
|
|
|
|
```text
|
|
|
|
|
[bash]$ echo << EOF | wc
|
|
|
|
|
> ^D bash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
|
|
|
|
|
1 0 1
|
|
|
|
|
[bash]$ echo << EOF | wc
|
|
|
|
|
> ^C
|
|
|
|
|
[bash]$
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
7. [force readline return without pressing ctrl-c](https://stackoverflow.com/questions/53165704/readline-c-force-return-of-certain-text-in-readline)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## schema d'execution :
|
|
|
|
|
```text
|
|
|
|
|
________________________________________________
|
|
|
|
|
|LOOP: shell_loop() |
|
|
|
|
|
| ______________________________________________ |
|
|
|
|
|
||mode interactif ||
|
|
|
|
|
|| *signal(SIGINT, handler)* ||
|
|
|
|
|
|| readline return line_input ||
|
|
|
|
|
||______________________________________________||
|
|
|
|
|
| ______________________________________________ |
|
|
|
|
|
||mode execution ||
|
|
|
|
|
|| *signal(SIGINT, ignore)* ||
|
|
|
|
|
|| ____________________________________________ ||
|
|
|
|
|
||| lexing |||
|
|
|
|
|
|||____________________________________________|||
|
|
|
|
|
|| ____________________________________________ ||
|
|
|
|
|
||| parsing |||
|
|
|
|
|
|||____________________________________________|||
|
|
|
|
|
|| ____________________________________________ ||
|
|
|
|
|
||| execution |||
|
|
|
|
|
|||____________________________________________|||
|
|
|
|
|
||______________________________________________||
|
|
|
|
|
|________________________________________________|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 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/)
|
|
|
|
|
- [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
|
|
|
|
|
- [exit code status](https://tldp.org/LDP/abs/html/exitcodes.html)
|
|
|
|
|
- [`char **s` vs `char *s[]`](https://stackoverflow.com/questions/46830654/what-is-the-difference-between-extern-char-environ-and-extern-char-environ)
|
|
|
|
|
- [extern and global](https://stackoverflow.com/questions/2652545/extern-and-global-in-c)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
| 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)
|
|
|
|
|
- [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 :
|
|
|
|
|
## todo list :
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
- **global features :**
|
|
|
|
|
- `prompt` *show a prompt*
|
|
|
|
|
- `history` **? the command history ?**
|
|
|
|
|
- `history` *use history with arrows*
|
|
|
|
|
- `binaries` *fetch and launch the right executable*
|
|
|
|
|
- `'` `"` `;` `\` **? don't interpret special characters and unclosed quotes ?**
|
|
|
|
|
- **pipes :** [video vulgarisation](https://www.youtube.com/watch?v=bKzonnwoR2I)
|
|
|
|
|
- `'` `"` `;` `\` *don't interpret special characters and unclosed quotes*
|
|
|
|
|
- **pipes :** [video on pipes](https://www.youtube.com/watch?v=bKzonnwoR2I)
|
|
|
|
|
- `|` *pipes*
|
|
|
|
|
- **expensions :**
|
|
|
|
|
- `$` *variable expension*
|
|
|
|
|
- `$?` *exit return of last executed process* [ressource stackoverflow](https://stackoverflow.com/questions/7248031/meaning-of-dollar-question-mark-in-shell-scripts)
|
|
|
|
|
- **quotes :** [ressource](https://linuxhandbook.com/quotes-in-bash/)
|
|
|
|
|
- `$?` *exit return of last executed process* [meaning-of $?](https://stackoverflow.com/questions/7248031/meaning-of-dollar-question-mark-in-shell-scripts)
|
|
|
|
|
- **quotes :** [quotes in bash](https://linuxhandbook.com/quotes-in-bash/)
|
|
|
|
|
- `'` *(ignore any special characters)*
|
|
|
|
|
- `"` *(ignore any special characters except '$')*
|
|
|
|
|
- **redirections & heredocs :** [ressource](https://www.gnu.org/software/bash/manual/html_node/Redirections.html) / [heredocs for readability](https://www.techrepublic.com/article/use-heredoc-in-shell-scripts/)
|
|
|
|
|
- **redirections & heredocs :** [redirections](https://www.gnu.org/software/bash/manual/html_node/Redirections.html) / [heredocs](https://www.techrepublic.com/article/use-heredoc-in-shell-scripts/)
|
|
|
|
|
- `<` *redirect input*
|
|
|
|
|
- `>` *redirect output*
|
|
|
|
|
- `<<` *read input until empty line --* **? doesn't update history ?**
|
|
|
|
|
- `<<` *read input until empty line --*
|
|
|
|
|
- `>>` *redirect and append*
|
|
|
|
|
- **signals :**
|
|
|
|
|
- `^C` *close process*
|
|
|
|
|
- `^D` *exit minishell*
|
|
|
|
|
- `^\` *do nothing*
|
|
|
|
|
- **builtins (can't be executed in child process) :**
|
|
|
|
|
- **builtins :** (can't be executed in child process)
|
|
|
|
|
- `cd <relative path>`
|
|
|
|
|
- `cd <absolute path>`
|
|
|
|
|
- `pwd`
|
|
|
|
|
- `export`
|
|
|
|
|
- `unset`
|
|
|
|
|
- ~~`exit`~~
|
|
|
|
|
- **builtins (don't need to be) :** [source](https://git.42l.fr/Fabien/minishell)
|
|
|
|
|
- `exit`
|
|
|
|
|
- **builtins :** (but they don't need to be)
|
|
|
|
|
- `env`
|
|
|
|
|
- ~~`echo`~~
|
|
|
|
|
- `echo`
|
|
|
|
|
- `echo -n`
|
|
|
|
|
- **autres :**
|
|
|
|
|
- `termcap` [man](https://www.gnu.org/software/termutils/manual/termcap-1.3/html_chapter/termcap_toc.html)
|
|
|
|
|
- `readline` [man](https://tiswww.case.edu/php/chet/readline/rltop.html) / [second source](https://tiswww.case.edu/php/chet/readline/README)
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
## 2. external functions :
|
|
|
|
|
## allowed external functions :
|
|
|
|
|
---
|
|
|
|
|
(extracts of manuals)
|
|
|
|
|
### readline :
|
|
|
|
|
|
|
|
|
|
**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** : `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 :
|
|
|
|
|
|
|
|
|
|
**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
|
|
|
|
|
@@ -287,28 +62,38 @@ prompt> blabla |-----------------|----------------|----------------|
|
|
|
|
|
- **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 :
|
|
|
|
|
|
|
|
|
|
**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 :
|
|
|
|
|
|
|
|
|
|
**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 :
|
|
|
|
|
|
|
|
|
|
**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 :
|
|
|
|
|
|
|
|
|
|
**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 :
|
|
|
|
|
|
|
|
|
|
**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
|
|
|
|
|
|
|
|
|
|
@@ -320,9 +105,14 @@ 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
|
|
|
|
|
|
|
|
|
|
two more functions :
|
|
|
|
|
|
|
|
|
|
- **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 :
|
|
|
|
|
|
|
|
|
|
**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()
|
|
|
|
|
@@ -336,435 +126,39 @@ There are three functions to use to get the value of a capability :
|
|
|
|
|
- **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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
## 3. parsing :
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 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)
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
ARCHITECTURE :
|
|
|
|
|
all
|
|
|
|
|
expend $
|
|
|
|
|
. pipes
|
|
|
|
|
. . redirections (program function or file)
|
|
|
|
|
. . . arguments (nom arg arg arg ...)
|
|
|
|
|
. . . .
|
|
|
|
|
EXEMPLE : . .
|
|
|
|
|
[sort < ./prgrm 'arg1 '$VARIABLE" arg3" | grep "word.$EXTENSION" | wc -l > file]
|
|
|
|
|
[sort < ./prgrm 'arg1 'arg2" arg3" | grep "word.md" | wc -l > file]
|
|
|
|
|
. [sort < ./prgrm 'arg1 'arg2" arg3"]
|
|
|
|
|
. . [sort]
|
|
|
|
|
. . [./prgrm 'arg1 'arg2" arg3"]
|
|
|
|
|
. . . [./prgrm]
|
|
|
|
|
. . . ['arg1 ']
|
|
|
|
|
. . . [arg2]
|
|
|
|
|
. . . [" arg3"]
|
|
|
|
|
. [grep "word.md"]
|
|
|
|
|
. . . [grep]
|
|
|
|
|
. . . ["word.md"]
|
|
|
|
|
. [wc -l > file]
|
|
|
|
|
. . [wc -l]
|
|
|
|
|
. . . [wc]
|
|
|
|
|
. . . [-l]
|
|
|
|
|
. . [file]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
## 4. gerer les quotes et la separation des arguments :
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 4.1 tentative methode 1 :
|
|
|
|
|
|
|
|
|
|
#### 4.1.1 pseudo code :
|
|
|
|
|
```text
|
|
|
|
|
q = 0 // first quote
|
|
|
|
|
c = 0 // count
|
|
|
|
|
i = 0
|
|
|
|
|
while (str[i])
|
|
|
|
|
{
|
|
|
|
|
if (str[i] == ')
|
|
|
|
|
{
|
|
|
|
|
if (q == ')
|
|
|
|
|
{
|
|
|
|
|
c--;
|
|
|
|
|
if (c == 0)
|
|
|
|
|
{
|
|
|
|
|
q = 0;
|
|
|
|
|
create_new_substr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
c++;
|
|
|
|
|
if (q == 0)
|
|
|
|
|
q = ';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (str[i] == ")
|
|
|
|
|
{
|
|
|
|
|
if (q == ")
|
|
|
|
|
{
|
|
|
|
|
c--;
|
|
|
|
|
if (c == 0)
|
|
|
|
|
{
|
|
|
|
|
q = 0;
|
|
|
|
|
create_new_substr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
c++;
|
|
|
|
|
if (q == 0)
|
|
|
|
|
q = ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
#### 4.1.2 application :
|
|
|
|
|
```text
|
|
|
|
|
['][a][r][g][1][ ]['][a][r][g][2]["][ ][a][r][g][3]["]
|
|
|
|
|
c = 0 . . . . . . . . . . . . . . . . . .
|
|
|
|
|
c = 1 . . . . . . . . . . . . . . . . . str[i] == ' ; q == 0 c == 0 -> c++; q = '
|
|
|
|
|
c = . 1 . . . . . . . . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . 1 . . . . . . . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . 1 . . . . . . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . 1 . . . . . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . 1 . . . . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . 0 . . . . . . . . . . . str[i] == ' ; q == ' c == 1 -> c--; q = 0;
|
|
|
|
|
arg1 = [a][r][g][1][ ]
|
|
|
|
|
c = . . . . . . . 0 . . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . 0 . . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . 0 . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . 0 . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . . 1 . . . . . . str[i] == " ; q != " c == 0 -> c++; q = ";
|
|
|
|
|
arg2 = [a][r][g][2]
|
|
|
|
|
c = . . . . . . . . . . . . 1 . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . . . . 1 . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . . . . . 1 . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . . . . . . 1 . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . . . . . . . 1 . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . . . . . . . . . 0 str[i] == " ; q == " c == 1 -> c--; q = 0;
|
|
|
|
|
arg3 = [ ][a][r][g][3]
|
|
|
|
|
|
|
|
|
|
['][a]["][r]['][g][']["][1][']
|
|
|
|
|
c = 0 . . . . . . . . . .
|
|
|
|
|
c = 1 . . . . . . . . . str[i] == ' ; q == 0 c == 0 -> c++; q = '
|
|
|
|
|
c = . 1 . . . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . 2 . . . . . . . str[i] == " ; q != " c == 1 -> c++;
|
|
|
|
|
c = . . . 2 . . . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . 3 . . . . . str[i] == ' | " ; q == ' c == 2 -> c++;
|
|
|
|
|
c = . . . . . 3 . . . . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . 2 . . . str[i] == ' ; q == ' c == 3 -> c--; q = 0;
|
|
|
|
|
c = . . . . . . . 1 . . str[i] == " ; q != " c == 2 ->
|
|
|
|
|
ERROR ...
|
|
|
|
|
c = . . . . . . . . 1 . str[i] != ' | " ; ->
|
|
|
|
|
c = . . . . . . . . . 0 str[i] != ' | " ; ->
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
#### 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" !
|
|
|
|
|
|
|
|
|
|
-> donc plutot partir sur une recursive
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
### 4.2 tentative methode 2 :
|
|
|
|
|
|
|
|
|
|
#### 4.2.1 deroulement :
|
|
|
|
|
```text
|
|
|
|
|
.--------------------------------------------.
|
|
|
|
|
: .--------------------------------------. :
|
|
|
|
|
: : .--------------------------------. : :
|
|
|
|
|
: : : .--------. .--------. : : :
|
|
|
|
|
: : : .--. : .--. : : .--. : : : :
|
|
|
|
|
'__"__'__"__"__"__'__'__"__"__'__'__"__'__"__'
|
|
|
|
|
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
|
|
|
|
|
```
|
|
|
|
|
-> identifier les paires de quotes ou dquotes
|
|
|
|
|
-> piège :
|
|
|
|
|
```text
|
|
|
|
|
| |
|
|
|
|
|
.--. .--. v v .--.
|
|
|
|
|
'__"__'__"__"__"__'__'__"__"__'__'__"__'__"__'
|
|
|
|
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
0. envoyer une copie de la str dans une fonction
|
|
|
|
|
1. chercher la premiere pair
|
|
|
|
|
2. l'effacer
|
|
|
|
|
3. recommencer en boucle
|
|
|
|
|
4. stop quand la premier quote a trouvé sa paire
|
|
|
|
|
5. renvoyer l'emplacement de la pair
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
#### 4.2.2 application :
|
|
|
|
|
```text
|
|
|
|
|
.--.
|
|
|
|
|
1 : '__"__'__"__"__"__'__'__"__"__'__'__"__'__"__'
|
|
|
|
|
|
|
|
|
|
.--.
|
|
|
|
|
2 : '__"__'________"__'__'__"__"__'__'__"__'__"__'
|
|
|
|
|
|
|
|
|
|
.--------.
|
|
|
|
|
3 : '__"__'________"________"__"__'__'__"__'__"__'
|
|
|
|
|
|
|
|
|
|
.--.
|
|
|
|
|
4 : '__"__'____________________"__'__'__"__'__"__'
|
|
|
|
|
|
|
|
|
|
.--------.
|
|
|
|
|
5 : '__"__'____________________"________"__'__"__'
|
|
|
|
|
|
|
|
|
|
.--------------------------------.
|
|
|
|
|
6 : '__"__'________________________________'__"__'
|
|
|
|
|
|
|
|
|
|
.--------------------------------------.
|
|
|
|
|
7 : '__"______________________________________"__'
|
|
|
|
|
|
|
|
|
|
.--------------------------------------------.
|
|
|
|
|
8 : '____________________________________________'
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
### 4.3 comportement reel chelou :
|
|
|
|
|
```text
|
|
|
|
|
echo "_"
|
|
|
|
|
_
|
|
|
|
|
|
|
|
|
|
echo "_'_'_"
|
|
|
|
|
_'_'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_"_'_"
|
|
|
|
|
_'___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_'_"_'_"
|
|
|
|
|
_'_____'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_"_'_"_'_"
|
|
|
|
|
_'___"_"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_"_"_"_'_"
|
|
|
|
|
_'_____'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_"_"_"_'_"_'_"
|
|
|
|
|
_'___"_"_"_"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_'_'_"_'_"_'_"
|
|
|
|
|
_'___"___"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_'_"_"_'_"_'_"_'_"
|
|
|
|
|
_'___"_____"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_'_"_'_'_"_'_"_'_"_'_"
|
|
|
|
|
_'___"___'_'___"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_'_"_'_"_"_'_"_'_"_'_"_'_"
|
|
|
|
|
_'___"___'___'___"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_'_"_'_"_'_'_"_'_"_'_"_'_"_'_"
|
|
|
|
|
_'___"___'_____'___"___'_
|
|
|
|
|
|
|
|
|
|
echo "_'_"_'_"_'_"_'_"_'_"_"_'_"_'_"_'_"_'_"_'_"
|
|
|
|
|
_'___"___'___"_"___'___"___'_
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
## 5. notes :
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
Ordre Interpreteur :
|
|
|
|
|
1) Couper les mots (comment faire ? je ne vois pas comment gerer ce genre de bordel ci dessous)
|
|
|
|
|
```
|
|
|
|
|
shell@prompt> ./arg_test 'mot1 '$NAME" mot2"
|
|
|
|
|
argc = 2
|
|
|
|
|
argv[0] = |./arg_test|
|
|
|
|
|
argv[1] = |mot1 Tour-Lemdows10 mot2|
|
|
|
|
|
shell@prompt>
|
|
|
|
|
```
|
|
|
|
|
2) $ - Env Vars Expand. if $VAR not set, expand to nothing("").
|
|
|
|
|
Dont save it as "" argument for fonctions, just delete.
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
Commandes dans variables d'env fonctionne :
|
|
|
|
|
```
|
|
|
|
|
shell@prompt> export VAR_TEST="echo"
|
|
|
|
|
shell@prompt> $VAR_TEST "string :)"
|
|
|
|
|
string :)
|
|
|
|
|
shell@prompt>
|
|
|
|
|
```
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
l'expension des variables dans des variables est fait au moment de export(),
|
|
|
|
|
donc pas de recursivité infini et de prise de tête au moment de l'interpretation.
|
|
|
|
|
Il suffit de faire "une passe" pour dévelloper les variables,
|
|
|
|
|
aucun besoin de refaire des passes succesives pour d'éventuels nouvelles variables aprés dévellopement :
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
export :
|
|
|
|
|
export VAR_TEST="test $NAME"
|
|
|
|
|
dans l'env :
|
|
|
|
|
NAME="Tour-Lemdows10"
|
|
|
|
|
VAR_TEST="test Tour-Lemdows10"
|
|
|
|
|
|
|
|
|
|
export :
|
|
|
|
|
export NAME="Un nouveau nom"
|
|
|
|
|
dans l'env :
|
|
|
|
|
NAME="Un nouveau nom"
|
|
|
|
|
VAR_TEST="test Tour-Lemdows10"
|
|
|
|
|
```
|
|
|
|
|
```
|
|
|
|
|
export :
|
|
|
|
|
export VAR_TEST="test $VAR_TEST"
|
|
|
|
|
dans l'env :
|
|
|
|
|
VAR_TEST="test test Tour-Lemdows10"
|
|
|
|
|
|
|
|
|
|
export :
|
|
|
|
|
export VAR_TEST="test $VAR_TEST"
|
|
|
|
|
dans l'env :
|
|
|
|
|
VAR_TEST="test test test Tour-Lemdows10"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
Tests pour Hugo, pour illustrer les pipes simultanés :
|
|
|
|
|
```
|
|
|
|
|
sleep 3 ; sleep 3 ; sleep 3 ; sleep 3
|
|
|
|
|
sleep 3 | sleep 3 | sleep 3 | sleep 3
|
|
|
|
|
|
|
|
|
|
sleep 5 ; ls | wc -l
|
|
|
|
|
sleep 5 | ls | wc -l
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
argv passé à execv(), telle quelle ou aprés avoir trouvé le PATH ?
|
|
|
|
|
exemple, si j'apelle "cat file.txt", dans un shell genre bash/zsh,
|
|
|
|
|
la commande cat recoit t'elle :
|
|
|
|
|
```
|
|
|
|
|
argv[0] == "cat"
|
|
|
|
|
argv[1] == "file.txt"
|
|
|
|
|
```
|
|
|
|
|
OU
|
|
|
|
|
```
|
|
|
|
|
argv[0] == "/bin/cat"
|
|
|
|
|
argv[1] == "file.txt"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
A test sur bash et minishell :
|
|
|
|
|
|
|
|
|
|
echo "phrase quelquonque" > file1 > file2 > file3
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
Pour les builtins dans une commande simple :
|
|
|
|
|
1) detecter la commande builtin
|
|
|
|
|
2) Ne pas fork() et execv().
|
|
|
|
|
A la place, chercher la fonction aproprié dans un tableau contenant les pointeurs vers les fonctions builtins.
|
|
|
|
|
Puis appeler la fonction dans le genre : builtin(ft_arrlen(cmd->argv), cmd->argv, &c).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pour les builtins dans une commande complexe (pipes, redirections, here doc, ...) :
|
|
|
|
|
1) detecter la commande builtin
|
|
|
|
|
2) fork()
|
|
|
|
|
3) Ne pas execv().
|
|
|
|
|
A la place, chercher la fonction aproprié dans un tableau contenant les pointeurs vers les fonctions builtins.
|
|
|
|
|
Puis appeler la fonction dans le genre : builtin(ft_arrlen(cmd->argv), cmd->argv, &c).
|
|
|
|
|
4) aprés la fin de la commande, free toute la mémoire du sous_processus, puis quitter le sous_processus en renvoyant le return de la commande builtin.
|
|
|
|
|
par exemple comme ça :
|
|
|
|
|
free_exit(&c, builtin(ft_arrlen(cmd->argv), cmd->argv, &c))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Peut-être faire un champ "void *builtin_command" dans une struct "cmd" pour contenir l'adresse de la fonction builtin.
|
|
|
|
|
```
|
|
|
|
|
typedef struct s_cmd
|
|
|
|
|
{
|
|
|
|
|
char **argv;
|
|
|
|
|
pid_t pid;
|
|
|
|
|
void *builtin_command;
|
|
|
|
|
} t_cmd;
|
|
|
|
|
```
|
|
|
|
|
Si la commande n'est pas builtin
|
|
|
|
|
|
|
|
|
|
cmd->builtin_command == NULL.
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
tester comment ce comporte minishell aprés le crash d'une commande (message sigfault comme dans bash ? Autres ?)
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
Implementer les exit status dans les builtins
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
EDIT : Aprés reflexion et verification, ça semble en effet le mieux a faire.
|
|
|
|
|
En l'etat le return de la derniere fonction marche correctement, j'ai verifier pas de problemes.
|
|
|
|
|
Si le child est deja fini avant l'apelle de wait, ça return quand même.
|
|
|
|
|
Cependant, pour optimiser la liberation des resources dés que possible,
|
|
|
|
|
il semble plus logique de liberer les sous_processus dés qu'ils ont terminés,
|
|
|
|
|
et donc, pas nécessairement dans l'ordre de la pipeline.
|
|
|
|
|
Donc, un waitpid() sur la derniere commande pour sauvegarder le retour,
|
|
|
|
|
puis wait() pour les autres, l'ordre n'ayant plus d'importance.
|
|
|
|
|
|
|
|
|
|
Revoir le wait() de mon pipex. Il n'est peut être pas correct.
|
|
|
|
|
En effet, j'attend que le premier process se ferme avec waitpid(), puis le deuxiéme, le troisiéme, ...
|
|
|
|
|
Mais en faite, il vaudrait peut être mieux attendre qu'un sous process QUELQUONQUE se ferme, puis le suivant, et le suivant, ...
|
|
|
|
|
|
|
|
|
|
Vu le fonctionnement des pipes, je crois que ce n'est pas toujours la premiere commande qui ce termine en premier,
|
|
|
|
|
et donc, qu'il ne faudrait pas attendre la fin de la premiere commande en particulier,
|
|
|
|
|
mais d'une commande QUELQUONQUE avec wait() plutot que waitpid().
|
|
|
|
|
|
|
|
|
|
IDÉE :
|
|
|
|
|
Attendre avec waitpid() la derniere commande pour obtenir son status, puis wait() en boucle les autres commandes,
|
|
|
|
|
et enfin renvoyer le status.
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
Faire des test avec
|
|
|
|
|
|
|
|
|
|
"env -i ./minishell"
|
|
|
|
|
pour voir si ça ne crash pas.
|
|
|
|
|
|
|
|
|
|
Normal si le comportement attendu n'est pas correct (en l'absence de PATH et tout ça) mais ça ne devrait pas crasher pour autant.
|
|
|
|
|
|
|
|
|
|
*[\go to sommaire](#markdown-header-sommaire)*
|
|
|
|
|
## ressources :
|
|
|
|
|
- [termcap](https://www.gnu.org/software/termutils/manual/termcap-1.3/html_chapter/termcap_toc.html)
|
|
|
|
|
- [readline](https://tiswww.case.edu/php/chet/readline/rltop.html)
|
|
|
|
|
- [readline](https://tiswww.case.edu/php/chet/readline/README)
|
|
|
|
|
- [transformer arbre normal en arbre binaire](https://fr.wikipedia.org/wiki/Arbre_binaire#Transformation_d'un_arbre_quelconque_en_un_arbre_binaire)
|
|
|
|
|
- [send EOF to 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/)
|
|
|
|
|
- [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)
|
|
|
|
|
- [exit code status](https://tldp.org/LDP/abs/html/exitcodes.html)
|
|
|
|
|
- [`char **s` vs `char *s[]`](https://stackoverflow.com/questions/46830654/what-is-the-difference-between-extern-char-environ-and-extern-char-environ)
|
|
|
|
|
- [extern and global](https://stackoverflow.com/questions/2652545/extern-and-global-in-c)
|
|
|
|
|
- [PS1 variable contain prompt](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03)
|
|
|
|
|
- [force readline return without pressing ctrl-c](https://stackoverflow.com/questions/53165704/readline-c-force-return-of-certain-text-in-readline)
|
|
|
|
|
|
|
|
|
|
**bash scripts :**
|
|
|
|
|
- [on which stream deos bash redirect its prompt](https://unix.stackexchange.com/questions/20826/which-stream-does-bash-write-its-prompt-to)
|
|
|
|
|
- [fd redirections &](https://putaindecode.io/articles/maitriser-les-redirections-shell)
|
|
|
|
|
- [fd redirections &-](https://wiki.bash-hackers.org/howto/redirection_tutorial)
|
|
|
|
|
- [redirect prompt output](https://stackoverflow.com/questions/2559076/how-do-i-redirect-output-to-a-variable-in-shell)
|
|
|
|
|
- [read, pipes, process substitution](https://stackoverflow.com/questions/15184358/how-to-avoid-bash-command-substitution-to-remove-the-newline-character)
|
|
|
|
|
- [process substitution](https://www.linuxjournal.com/content/shell-process-redirection)
|
|
|
|
|
- [read, IFS](https://unix.stackexchange.com/questions/164508/why-do-newline-characters-get-lost-when-using-command-substitution)
|
|
|
|
|
- [process substitution](https://www.gnu.org/software/bash/manual/bash.html#Process-Substitution)
|
|
|
|
|
- [variable substitution](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html)
|
|
|
|
|
- [send one command to two pipes](https://stackoverflow.com/questions/13107783/pipe-output-to-two-different-commands)
|
|
|
|
|
- [send two commands to one pipe](https://askubuntu.com/questions/133386/how-to-merge-and-pipe-results-from-two-different-commands-to-single-command)
|
|
|
|
|
- ["\[" vs "\[\[" in bash](https://stackoverflow.com/questions/13542832/difference-between-single-and-double-square-brackets-in-bash)
|
|
|
|
|
- [redirections in bash](https://stackoverflow.com/questions/818255/in-the-shell-what-does-21-mean)
|
|
|
|
|
- [bash variable of variable](https://stackoverflow.com/questions/10757380/bash-variable-variables)
|
|
|
|
|
- [bash fork &](https://unix.stackexchange.com/questions/7608/does-bash-support-forking-similar-to-cs-fork/7609#7609)
|
|
|
|
|
- [read a var line by line](https://unix.stackexchange.com/questions/9784/how-can-i-read-line-by-line-from-a-variable-in-bash)
|
|
|
|
|
- [wait for not-a-child process to finish](https://stackoverflow.com/questions/1058047/wait-for-a-process-to-finish)
|
|
|
|
|
|
|
|
|
|
|