{"id":19947332,"url":"https://github.com/clementvidon/multipipe_tutor","last_synced_at":"2025-08-21T11:22:18.093Z","repository":{"id":119380453,"uuid":"578275177","full_name":"clementvidon/Multipipe_tutor","owner":"clementvidon","description":"C multi-pipe implementation, dissection and explanation. ","archived":false,"fork":false,"pushed_at":"2022-12-21T20:16:22.000Z","size":56,"stargazers_count":28,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-09T08:08:00.495Z","etag":null,"topics":["42","42born2code","42cursus","42network","42paris","42projects","42school","interprocess-communication","microshell","minishell","multiprocessing","pipe","pipex","pipex-42","pipex42","tutorial"],"latest_commit_sha":null,"homepage":"https://clemedon.github.io/Multipipe_tutor/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clementvidon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-14T17:05:45.000Z","updated_at":"2024-10-09T04:22:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"6435db70-0562-4760-ad2d-88d1e8f5937b","html_url":"https://github.com/clementvidon/Multipipe_tutor","commit_stats":null,"previous_names":["clementvidon/multipipe_tutor"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clementvidon%2FMultipipe_tutor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clementvidon%2FMultipipe_tutor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clementvidon%2FMultipipe_tutor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clementvidon%2FMultipipe_tutor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clementvidon","download_url":"https://codeload.github.com/clementvidon/Multipipe_tutor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224370254,"owners_count":17299968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["42","42born2code","42cursus","42network","42paris","42projects","42school","interprocess-communication","microshell","minishell","multiprocessing","pipe","pipex","pipex-42","pipex42","tutorial"],"created_at":"2024-11-13T00:35:33.386Z","updated_at":"2024-11-13T00:35:33.953Z","avatar_url":"https://github.com/clementvidon.png","language":"C","readme":"\u003ch1 align=\"center\"\u003e\n    Multipipe_tutor\n\u003c/h1\u003e\n\n\u003ch3 align=\"center\"\u003e\n    \u003ca href=\"#summary\"\u003eSummary\u003c/a\u003e\n    \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"#pipe\"\u003ePipe\u003c/a\u003e\n    \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"#multipipe\"\u003eMultipipe\u003c/a\u003e\n    \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"#sources\"\u003eSources\u003c/a\u003e\n    \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\n\u003c/h3\u003e\n\n# Summary\n\nThis small project aims to guarantee me a quick and clear reunderstanding of my\nimplementation of the multi-pipe when the notion will be as rusty as a distant\nmemory the day I need it.\n\nFor this purpose we will **dissect** the `prg1 | prg2 | prg3` **command execution**\nusing a [**C multi-pipe implementation**](https://github.com/clemedon/Multipipe_tutor/tree/main/src).\n\n*For reasons of readability the code does not include the protections.*\n\n[**→ GitHub Page ←**](https://clemedon.github.io/Multipipe_tutor/)\u003cbr\u003e\n[**→ GitHub Repo ←**](https://github.com/clemedon/Multipipe_tutor/)\n\n# Pipe\n\n- A pipe is a **unidirectional** data channel that can be used for **interprocess\n  communication**.\n\n- It is made of **two descriptors**: `pipefd[0]` that refers to the **read end** of\n  the pipe and `pipefd[1]` that refers to the **write end** of the pipe.\n\n- **Data written to the write end of the pipe is buffered** by the kernel until it\n  is read from the read end of the pipe.\n\n```\nFig.0 Interprocess communication with a single pipe.\n\n               ₍₂₎\n    IN→ 1=====xxxx0\n          ⁽³⁾↓\n    ⁽¹⁾ 1xxxx=====0 →OUT\n\n\n(0) The main process (futur parent) creates a pipe and forks itself which\nduplicates its pipe's set of file descriptors pipefd[1] and pipefd[0] into the\nnewly created (child) process.\n\n(1) The parent process closes its pipefd[1] to prevent its process from writing\nin the pipe.\n\n(2) Simultaneously, the child process closes its pipefd[0] to prevent its\nprocess from reading in the pipe.\n\n(3) In the end we have a parent that can read and a child that can write, both\nsharing the same pipe.  If the child write in the pipe, the data stream will\nfind its way out in the read end of the parent process ⇒ interprocess\ncommunication.\n```\n\n# Multipipe\n\n- Alternating several pipes and processes we can create an interprocess\n  communication chain, **passing the output of one program as the input of\n  another program** and so on.\n\n```\nFig.1 Overall idea of following multi-pipe example.\n\n    Stdin → PRG1  PRG2  PRG3 → Stdout  \u003cthree programs execution\n               \\  /  \\  /              \u003cinterprocess communication\n                P1    P2               \u003ctwo pipes\n\nPRG = Program (one per command)\nP   = Pipe    (one pipe for two communicating programs)\n```\n\n##  Example\n\nThe following example dissects a `prg1 | prg2 | prg3` command line execution.\n\n```bash\n$ git clone git@github.com:clemedon/Multipipe_tutor.git\n$ cd Multipipe_tutor/src\n$ make\n$ ./multipipe /bin/echo five \"|\" /bin/wc -c \"|\" /bin/cat -e\n```\n\nDon't forget to frame `|` symbol with quotes or it will be interpreted by the\nshell.\n\nNote that the **first child** doesn't need `prevpipe` because there is **no\nprevious pipe** to connect. Thus we must initialize `prevpipe` to any valid fd\nso as not to get an error from the `close` and `dup2` calls on an invalid fd.\n`prevpipe` is the variable that we use to pass the previous pipe read end to the\nnext program Stdin.\n\n**Index**\n* [**Instructions**](#instructions)\u003cbr\u003e\n* [**Illustrations**](#illustrations)\n\n### Instructions\n\n```\nmain()\n\n    - initialize prevpipe to any valid file descriptor.\n    - start the while loop that iterate over each of the 3 commands (PRG).\n\n\nPRG1 in ft_pipe()\n\n    - create a pipe     P1[2]       Size 2 array that contains P1[0] and P1[1]\n    - fork itself                   Which clones P1\n\n  Child\n\n    - close              P1[0]      Unused\n    - redirect Stdout to P1[1]      Fill the pipe with PRG1 output\n    - close              P1[1]      Not needed anymore\n    - redirect Stdin  to prevpipe   Here Stdin (cf. prevpipe init)\n    - close              prevpipe   Not needed anymore\n    - exec\n\n  Parent\n\n    - close              P1[1]      Unused\n    - prevpipe         = P1[0]      Save prevpipe for PRG2 Stdin\n\n\nPRG2 in ft_pipe()\n\n    - create a pipe     P2[2]       Size 2 array that contains P2[0] and P2[1]\n    - fork itself                   Which clones P2\n\n  Child\n\n    - close              P2[0]      Unused\n    - redirect Stdout to P2[1]      Fill the pipe with PRG2 output\n    - close              P2[1]      Not needed anymore\n    - redirect Stdin  to prevpipe   Here P1[0] (the previous P[0])\n    - close              prevpipe   Not needed anymore\n    - exec\n\n  Parent\n\n    - close              P2[1]      Unused\n    - prevpipe         = P2[0]      Save prevpipe for PRG3 Stdin\n\n\nPRG3 in ft_last()\n\n    - fork itself\n\n  Child\n\n    - redirect Stdin  to prevpipe   Here P2[0] (the previous P[0])\n    - close              prevpipe   Not needed anymore\n    - exec\n\n  Parent\n\n    - close              prevpipe   Unused\n    - wait for children\n```\n[**Return to Index ↑**](#example)\n\n### Illustrations\n\nThe path taken by the **stream of data** during the whole execution is paved by\nthe **`(A)`** to **`(J)`** symbols.\n\n```\nPRG1 in ft_pipe()\n\nP1 in the child process.\n\n                      P1[1]           P1[0]\n                      ―――――――――――――――――――――\n   (A) Stdin → PRG1 → OPEN → (B)     CLOSED\n                      ―――――――――――――――――――――\n\nP1 in the parent process.\n\n                      P1[1]           P1[0]\n                      ―――――――――――――――――――――\n                      CLOSED     (C) → OPEN → prevpipe (D)\n                      ―――――――――――――――――――――\n\nPRG2 in ft_pipe()\n\nP2 in the child process.\n\n                      P2[1]           P2[0]\n                      ―――――――――――――――――――――\n(E) prevpipe → PRG2 → OPEN → (F)     CLOSED\n                      ―――――――――――――――――――――\n\nP2 in the parent process.\n\n                      P2[1]           P2[0]\n                      ―――――――――――――――――――――\n                      CLOSED     (G) → OPEN → prevpipe (H)\n                      ―――――――――――――――――――――\nPRG3 in ft_last()\n\nLast program execution.\n\n(I) prevpipe → PRG3 → Stdout (J)\n```\n\n[**Return to Index ↑**](#example)\n\n# Sources\n\n- **`$ man 2 pipe`**\n- [**GPT Chat**](https://chat.openai.com/chat)\n\n# Contact\n\n```\ncvidon   42\nclemedon icloud\n```\n\n\u003csub\u003e\u003ci\u003eCopyright 2022 Clément Vidon.  All Rights Reserved.\u003c/i\u003e\u003c/sub\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclementvidon%2Fmultipipe_tutor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclementvidon%2Fmultipipe_tutor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclementvidon%2Fmultipipe_tutor/lists"}