diff --git a/content/progsys/6_les-tubes/files/presentation.pdf b/content/progsys/6_les-tubes/files/presentation.pdf
new file mode 100644
index 0000000..9ca304e
Binary files /dev/null and b/content/progsys/6_les-tubes/files/presentation.pdf differ
diff --git a/content/progsys/6_les-tubes/images/illustr_1.svg b/content/progsys/6_les-tubes/images/illustr_1.svg
new file mode 100644
index 0000000..f383122
--- /dev/null
+++ b/content/progsys/6_les-tubes/images/illustr_1.svg
@@ -0,0 +1,595 @@
+
+
diff --git a/content/progsys/6_les-tubes/images/illustr_2.svg b/content/progsys/6_les-tubes/images/illustr_2.svg
new file mode 100644
index 0000000..f87d3be
--- /dev/null
+++ b/content/progsys/6_les-tubes/images/illustr_2.svg
@@ -0,0 +1,1938 @@
+
+
diff --git a/content/progsys/6_les-tubes/images/tybe.svg b/content/progsys/6_les-tubes/images/tybe.svg
new file mode 100644
index 0000000..777b361
--- /dev/null
+++ b/content/progsys/6_les-tubes/images/tybe.svg
@@ -0,0 +1,353 @@
+
+
+
+
diff --git a/content/progsys/6_les-tubes/index.md b/content/progsys/6_les-tubes/index.md
new file mode 100644
index 0000000..410cc58
--- /dev/null
+++ b/content/progsys/6_les-tubes/index.md
@@ -0,0 +1,211 @@
+---
+title: "Les tubes"
+date: 2018-10-09
+categories: ["Programmation système", "Cours"]
+tags: ["C", "tubes", "pipes"]
+---
+
+Les tubes sont un mécanisme de communication entre processus (**IPC** pour
+*Inter Process Communication*). Sous *Unix*, les *IPC* peuvent prendre plusieurs
+formes. Il facilitent la vie du développeur et sont un élément clé de la
+réutilisation de composants.
+
+Les tubes (ou *pipes* en anglais) que l'on trouve en C représentent la même
+chose que les pipes en **shell** comme par exemple :
+
+```shell
+$ ps faux | less
+```
+
+Le but est toujours l'enchainement d'outils simples pour réaliser des tâches
+plus ou moins complexe.
+
+Les tubes sont un mécanisme de transfert de données sous forme de flux : les
+données écrites d'un côté peuvent être lues de l'autre. Ils sont crées par le
+noyau et manipulables par **des descripteurs de fichiers**.
+
+Leurs création passe par un appel système :
+
+```C
+#include
+
+int pipe(int pipefd[2]);
+```
+
+`pipefd[2]` est un tableau de deux *fd* qui sera rempli par le noyau avant le
+retour de l'appel :
+
+ - `pipefd[0]` est ouvert en lecture
+ - `pipefd[1]` est ouvert en écriture
+
+On peut faire le parallèle avec *STDIN* (0) et *STDOUT* (1).
+
+En cas de succès, l'appel renvoie 0, sinon -1 et `errno` est positionné,
+
+
+
+Le canal de communication créé est *half-duplex*, il ne va que dans un seul
+sens. Il sont accessibles seulement par les processus qui y sont associés. Il
+"vivent" le temps du processus et disparaissant à sa terminaison.
+
+Ils sont portables et disponible **pour tous les Unix**. Certains proposent
+d'ailleurs des modes full duplex, mais le code résultant est moins portables. Il
+est tout de même possible de créer un mécanisme *full duplex* en créant deux
+tubes.
+
+## Exemple de communication half-duplex
+
+### patron de conception
+
+ 1. créer le pipe : `pipe(fds)`
+ 2. créer un processus fils : `fork()`
+ 3. fermer un canal sur le processus père : `close(fds[0])`
+ 4. fermer un canal sur le processus fils : `close(fds[1])`
+ 5. écrire depuis ls père : `write(fds[1], "data")`
+ 6. lire depuis le fils : `read(fds[0], buffer)`
+
+
+
+### Code
+
+```C
+#include
+#include
+#include
+#define BUFMAX 256
+int main () {
+ char *buffer[BUFMAX];
+ pid_t pid;
+ int n, fds[2];
+ if (pipe(fds) == -1) {
+ perror("Unable to create pipe");
+ }
+ pid = fork();
+ if (pid == -1) {
+ perror("Unable to fork");
+ }
+ else if (pid > 0) { /* parent */
+ if (close(fds[0]) == -1) {
+ perror("Unable to close pipe from parent");
+ }
+ write(fds[1], "I am your father\n", 17);
+ }
+ else { /* child */
+ if (close(fds[1]) == -1) {
+ perror("Unable to close pipe from child");
+ }
+ n = read(fds[0], buffer, BUFMAX);
+ write(STDOUT_FILENO, buffer, n);
+ }
+ exit(EXIT_SUCCESS);
+}
+```
+
+## Communication full_duplex, patron de conception
+
+ 2. création du processus fils : `fork()`
+ 3. fermeture des canaux inutiles sur le père : `close(p2c[0]); close(c2p[1])`
+ 4. fermeture des canaux inutiles sur le fils : `close(p2c[1]); close(c2p[0])`
+ 5. lancer les communications : `write(); read();`
+
+## Cas particuliers
+
+ 1. Il est préférable de fermer les extrémités inutiles d'un tube avant de
+ l'utiliser
+ 2. Une lecture sur un tube déjà fermé retourne 0
+ 2. Une écriture sur un tube fermé retourne -1 et positionne `errno`. Le
+ processus essayent d'écrire sur le pipe reçoit le signal `SIGPIPE`
+
+## Les filtres Unix
+
+Ce sont des programmes qui lise leurs données en entrées depuis *SDTIN* et les
+écrivent depuis *STDERR*. Les filtres les plus utilisé sur les systèmes *Unix*
+sont `sort`, `sed`, `cat`, `awk`, `less` etc.
+
+### Exemple de filtres
+
+Imaginons un programme pour lequel nous souhaitons avoir une pagination. Dans
+l'idéal nous utiliserons la `$PAGER` du système au lieu d'en écrire un (`less`
+par exemple)
+
+#### Patron de conception
+ 1. Créer un tube avec `pipe(fds)`
+ 2. Créer un processus enfant avec `fork()`. Le processus père produira les
+ données et le processus fils exécutera le programme de pagination.
+ 3. Le processus fils duplique la lecture du tube sur la sortie standard *STDIN*
+ 4. Il exécutera le programme de pagination qui lira les donnés depuis son
+ entrée standard
+ 5. Le processus père écrira les données dans le pipe lues par le
+ fils à l'autre extrémité.
+
+#### Duplication de descripteur de fichiers
+
+Il est possible de dupliquer les descripteur de fichiers avec les fonctions
+`dup()` et `dup2()`.
+
+```C
+#include
+
+int dup(int old_fd);
+int dup2(int old_fd, int new_fd);
+```
+
+`dup2()` transforme `new_fd` en une copie de `old_fd`, `newfd` peut être fermé
+si besoin. Si `old_fd` n'est pas un descripteur de fichier valide l'appel échoue
+et `new_fd` n'est pas fermé. Si `old_fd` est un descripteur de fichier valable
+et est égal à `newfd` alors rien ne se passe et `dup2()` renvoie `new_fd`
+
+#### Exemple en C
+
+```C
+#include
+#include
+#include
+#include
+
+#define PAGER "less"
+
+int main () {
+ pid_t pid;
+ int status, fds[2];
+ FILE *fdout;
+ if (pipe(fds) == -1) {
+ perror("Unable to create pipe");
+ }
+ pid = fork();
+ if (pid == -1) {
+ perror("Unable to fork");
+ }
+ else if (pid > 0) { /* parent */
+ if (close(fds[0]) == -1) {
+ perror("Unable to close pipe from parent");
+ }
+ fdout = fdopen(fds[1], "w");
+ if (fdout == NULL) {
+ perror("Unable to open pipe as a stream for writing");
+ }
+ for(int i=1; i<=1000; i++) {
+ fprintf(fdout, "%d\n", i);
+ }
+ fclose(fdout);
+ wait(&status);
+ }
+ else { /* child */
+ if (close(fds[1]) == -1) {
+ perror("Unable to close pipe from child");
+ }
+ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO) {
+ perror("Unable to duplicate stdin file descriptor");
+ }
+ close(fds[0]);
+ execlp(PAGER, PAGER, NULL);
+ }
+ exit(EXIT_SUCCESS);
+}
+```
+
+## Bibliographie
+
+[Présentation][f_pres] support de cours
+
+[f_pres]:files/presentation.pdf