{"id":19483542,"url":"https://github.com/librity/ft_pipex","last_synced_at":"2025-04-15T11:44:26.641Z","repository":{"id":42988573,"uuid":"463345374","full_name":"librity/ft_pipex","owner":"librity","description":"42 São Paulo - pipex","archived":false,"fork":false,"pushed_at":"2022-08-06T19:29:03.000Z","size":1050,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T19:38:57.313Z","etag":null,"topics":["42","42born2code","42cursus","42pipex","42projects","42saopaulo","42school","pipex"],"latest_commit_sha":null,"homepage":"https://www.42sp.org.br/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/librity.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-25T00:31:18.000Z","updated_at":"2025-03-09T10:15:57.000Z","dependencies_parsed_at":"2022-09-06T14:41:56.883Z","dependency_job_id":null,"html_url":"https://github.com/librity/ft_pipex","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fft_pipex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fft_pipex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fft_pipex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librity%2Fft_pipex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/librity","download_url":"https://codeload.github.com/librity/ft_pipex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249064553,"owners_count":21207114,"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","42pipex","42projects","42saopaulo","42school","pipex"],"created_at":"2024-11-10T20:15:30.484Z","updated_at":"2025-04-15T11:44:26.621Z","avatar_url":"https://github.com/librity.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch3 align=\"center\"\u003e42 São Paulo - Pipex\u003c/h3\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n![42 São Paulo](https://img.shields.io/badge/42-SP-1E2952)\n![License](https://img.shields.io/github/license/librity/ft_pipex?color=yellow)\n![Code size in bytes](https://img.shields.io/github/languages/code-size/librity/ft_pipex?color=blue)\n![Lines of code](https://img.shields.io/tokei/lines/github/librity/ft_pipex?color=blueviolet)\n![Top language](https://img.shields.io/github/languages/top/librity/ft_pipex?color=ff69b4)\n![Last commit](https://img.shields.io/github/last-commit/librity/ft_pipex?color=orange)\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![Build](https://github.com/librity/ft_pipex/actions/workflows/build.yml/badge.svg)](https://github.com/librity/ft_pipex/actions/workflows/build.yml)\n[![Norminette v3](https://github.com/librity/ft_pipex/actions/workflows/norminette_v3.yml/badge.svg)](https://github.com/librity/ft_pipex/actions/workflows/norminette_v3.yml)\n[![denisgodoy_pipex-tester](https://github.com/librity/ft_pipex/actions/workflows/denisgodoy_pipex-tester.yml/badge.svg)](https://github.com/librity/ft_pipex/actions/workflows/denisgodoy_pipex-tester.yml)\n[![gsilva-v_pipextester](https://github.com/librity/ft_pipex/actions/workflows/gsilva-v_pipextester.yml/badge.svg)](https://github.com/librity/ft_pipex/actions/workflows/gsilva-v_pipextester.yml)\n[![vfurmane_pipex-tester](https://github.com/librity/ft_pipex/actions/workflows/vfurmane_pipex-tester.yml/badge.svg)](https://github.com/librity/ft_pipex/actions/workflows/vfurmane_pipex-tester.yml)\n[![yoo0lh_pipex_tester_42](https://github.com/librity/ft_pipex/actions/workflows/yoo0lh_pipex_tester_42.yml/badge.svg)](https://github.com/librity/ft_pipex/actions/workflows/yoo0lh_pipex_tester_42.yml)\n\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e A simple implementation of UNIX \u003ccode\u003e|\u003c/code\u003e, \u003ccode\u003e\u003c\u003c/code\u003e, \u003ccode\u003e\u003c\u003c\u003c/code\u003e, \u003ccode\u003e\u003e\u003c/code\u003e and \u003ccode\u003e\u003e\u003e\u003c/code\u003e in pure C.\n  \u003cbr\u003e\n\u003c/p\u003e\n\n---\n\n## 📜 Table of Contents\n\n- [About](#about)\n- [Checklist](#checklist)\n- [Getting Started](#getting_started)\n- [Notes](#notes)\n- [42 São Paulo](#ft_sp)\n- [Resources](#resources)\n\n## 🧐 About \u003ca name = \"about\"\u003e\u003c/a\u003e\n\nIn this projects we implement UNIX pipes and redirections, namely\n`|`, `\u003c`, `\u003c\u003c`, `\u003e` and `\u003e\u003e`.\nThese mechanisms allow us to link commands and files together,\nwhere the output of one serves as the input of the next.\n\nThis _toolbox philosophy_ is one of the reasons why\nUNIX is still popular after 40 years:\nit encourages developers to create programs that do one thing well,\nand that work well with other programs.\nIt's also extremely modular and versatile.\n\nI learned about child processes, filesystem interfaces\nand the internals of `bash`, the target of our emulation.\nSince I did both bonuses I'm pretty confident about\nthe next big challenge in the 42 curriculum: `minishell`.\nIt's basically this with a parser and dynamic environment variables.\n\n## ✅ Checklist \u003ca name = \"checklist\"\u003e\u003c/a\u003e\n\n### Mandatory\n\n- [x] DONT TURN IN LIBS AS SUBMODULES\n- [x] MAKEFILE EXPLICIT SOURCE FILES (`echo M_SOURCES`)\n- [x] Make must compile without relinking\n  - [x] SHOOULDNT RECOMPILE/REARCHIVE OBJECTS WITH MAKE ALL\n    - [x] Add `.keep` to object dirs\n    - [x] Remove `initialize` from `all` /build\n    - [x] Create non-phony rule for each lib archive\n- [x] `.linux` file (42 Workspaces)\n- [x] Test in workspaces\n- [x] Follows `norminette 3.3.51`\n- [x] Turn in `Makefile`, `*.h`, `*.c` , `.linux` , `.gitignore`\n- [x] Makefile rules: `$(NAME)` `all` `clean` `fclean` `re`\n- [x] Program name `pipex`\n- [x] Compiles with `-Wall -Wextra -Werror`\n- [x] Should not quit unexpectedly (segmentation fault, bus error, double\n      free, etc.)\n- [x] All allocated heap memory properly freed, no memory leaks.\n  - [x] Check memory leaks with `valgrind`\n- [x] Allowed functions:\n  - [x] `open`, `close`, `read`, `write`, `malloc`, `free`, `perror`, `strerror`, `access`, `dup`, `dup2`, `execve`, `exit`, `fork`, `pipe`, `unlink`, `wait`, `waitpid`\n  - [x] `libft` allowed\n  - [x] Your `ft_printf` (may be modified)\n    - [x] No `printf` from `stdio.h`\n- [x] Handle arguments `file1 cmd1 cmd2 file2`\n  - [x] Wrong number of arguments exits with help message\n- [x] Behaves exactly like `\u003c file1 cmd1 | cmd2 \u003e file2`\n  1. `\u003c file1 cmd1`: `\u003c file1` read `file1` and pipes it to `cmd1`’s `STDIN`\n  2. `cmd1 | cmd2`: `cmd1`’s `STDOUT` is piped to `cmd2`’s `STDIN`\n  3. `cmd2 \u003e file2`: `cmd2`’s `STDOUT` is piped to `file2`, overwriting the file\n- [x] Handle errors exactly like `\u003c file1 cmd1 | cmd2 \u003e file2`\n- [x] Handle input errors (in order):\n  - [x] `argc != 5` , return `0`\n  - [x] No `infile`, return `0`\n  - [x] No `cmd1` , return `0`\n  - [x] No `cmd2` , return `127`\n  - [x] `cmd1` bad arguments, return `0`\n  - [x] `cmd2` bad arguments, return `1`\n- [x] Pass all testers\n  - [x] [https://github.com/denisgodoy/pipex-tester](https://github.com/denisgodoy/pipex-tester)\n  - [x] [https://github.com/gsilva-v/PipexTester](https://github.com/gsilva-v/PipexTester)\n  - [x] [https://github.com/vfurmane/pipex-tester](https://github.com/vfurmane/pipex-tester)\n  - [x] [https://github.com/Yoo0lh/pipex_tester_42](https://github.com/Yoo0lh/pipex_tester_42)\n\n### Bonus\n\n- [x] Handle multiple pipes:\n  - `\u003c file1 cmd1 | cmd2 | cmd3 ... | cmdn \u003e file2`\n  - `./pipex file1 cmd1 cmd2 cmd3 ... cmdn file2`\n- [x] Support `«` and `»` when the first parameter is \"here_doc\":\n  - `./pipex here_doc LIMITER cmd cmd1 file`\n  - `cmd \u003c\u003c LIMITER | cmd1 \u003e\u003e file`\n\n## 🏁 Getting Started \u003ca name = \"getting_started\"\u003e\u003c/a\u003e\n\n### 🖥️ Installing\n\nClone the repo and build with `make`:\n\n```bash\n$ git clone --recurse-submodules https://github.com/librity/ft_pipex.git\n$ cd ft_pipex\n$ make\n```\n\nIt works exactly like `\u003c infile cmd1 | cmd2 \u003e outfile`:\n\n```bash\n./pipex infile \"ls\" \"wc\" outfile\n\n./pipex infile \"ls -l\" \"wc -l\" outfile\n./pipex infile \"grep a1\" \"wc -w\" outfile\n\n./pipex .gitignore \"tr a b\" \"tr b c\" outfile\n./pipex EOF \"tr a b\" \"tr b c\" outfile\n./pipex .gitignore \"ping 8.8.8.8\" \"grep ms\" outfile\n```\n\n### Bonus\n\nYou can also compile the bonus implementation:\n\n```bash\n$ make bonus\n```\n\nIt handles multiple pipes `\u003c infile cmd1 | cmd2 | cmd3 | ... | cmdn \u003e outfile`:\n\n```bash\n./pipex infile \"grep a\" \"grep d\" \"grep s\" outfile\n./pipex infile \"ls -l\" \"grep a\" \"wc -l\" outfile\n./pipex infile \"cat\" \"tr a b\" \"tr b a\" \"tr a b\" \"tr b a\" outfile\n```\n\nIt also takes a heredoc as input `cmd1 \u003c\u003c LIMITER | cmd2 \u003e\u003e file`:\n\n```bash\n./pipex here_doc l \"grep a\" \"grep d\" \"grep s\" outfile\n./pipex here_doc l \"grep a\" \"wc -l\" outfile\n./pipex here_doc x \"cat\" \"tr a b\" \"tr c d\"  outfile\n```\n\n## 📝 Notes \u003ca name = \"notes\"\u003e\u003c/a\u003e\n\n### `\u003c infile cmd`\n\nRedirect `infile` ’s contents to `cmd` ’s `STDIN`\n\n```bash\npython hello.py \u003c foo.txt      # feed foo.txt to stdin for python\ndiff \u003c(ls -r) \u003c(ls)            # Compare two stdout without files\n```\n\n### `cmd1 | cmd2`\n\nRedirects previous `cmd1`'s `STDOUT` to `cmd2` ’s `STDIN`\n\n```bash\nls -la | wc -l\n```\n\n### `cmd \u003e outfile`\n\nTruncates `outfile` with `cmd` ’s `STDOUT`\n\n```bash\npython hello.py \u003e output.txt   # stdout to (file)\npython hello.py \u003e\u003e output.txt  # stdout to (file), append\npython hello.py 2\u003e error.log   # stderr to (file)\npython hello.py 2\u003e\u00261           # stderr to stdout\npython hello.py 2\u003e/dev/null    # stderr to (null)\npython hello.py \u0026\u003e/dev/null    # stdout and stderr to (null)\n```\n\n### `perror`\n\n- [https://www.man7.org/linux/man-pages/man3/perror.3.html](https://www.man7.org/linux/man-pages/man3/perror.3.html)\n\n### `errno`\n\n- [https://www.man7.org/linux/man-pages/man3/errno.3.html](https://www.man7.org/linux/man-pages/man3/errno.3.html)\n\n```bash\n# GET ALL ERRNO CODES\n$ sudo apt install moreutils\n$ errno -l\n```\n\n### **`strerror`**\n\n- [https://linux.die.net/man/3/strerror](https://linux.die.net/man/3/strerror)\n- [https://www.geeksforgeeks.org/error-handling-c-programs/](https://www.geeksforgeeks.org/error-handling-c-programs/)\n\n### `open`\n\n- [https://www.man7.org/linux/man-pages/man2/open.2.html](https://www.man7.org/linux/man-pages/man2/open.2.html)\n- [https://jameshfisher.com/2017/02/24/what-is-mode_t/](https://jameshfisher.com/2017/02/24/what-is-mode_t/)\n\n### `close`\n\n- [https://www.man7.org/linux/man-pages/man2/close.2.html](https://www.man7.org/linux/man-pages/man2/close.2.html)\n\n### **`access`**\n\nChecks if the calling process can access a specific file\n\n- [https://www.man7.org/linux/man-pages/man2/access.2.html](https://www.man7.org/linux/man-pages/man2/access.2.html)\n\n### **`dup` \u0026 `dup2`**\n\nAdjust file descriptors so they reference the same file.\n\n- [https://www.man7.org/linux/man-pages/man2/dup.2.html](https://www.man7.org/linux/man-pages/man2/dup.2.html)\n- [https://www.geeksforgeeks.org/dup-dup2-linux-system-call/](https://www.geeksforgeeks.org/dup-dup2-linux-system-call/)\n\n### **`execve`**\n\nReplaces the current process with a system call.\n\n- [https://jameshfisher.com/2017/02/05/how-do-i-use-execve-in-c/](https://jameshfisher.com/2017/02/05/how-do-i-use-execve-in-c/)\n- [https://stackoverflow.com/questions/29615540/using-execve-in-c](https://stackoverflow.com/questions/29615540/using-execve-in-c)\n- [https://www.tutorialspoint.com/unix_system_calls/execve.htm](https://www.tutorialspoint.com/unix_system_calls/execve.htm)\n- [https://www.man7.org/linux/man-pages/man2/execve.2.html](https://www.man7.org/linux/man-pages/man2/execve.2.html)\n- [https://stackoverflow.com/questions/5429141/what-happens-to-malloced-memory-after-exec-changes-the-program-image/5429592#5429592](https://stackoverflow.com/questions/5429141/what-happens-to-malloced-memory-after-exec-changes-the-program-image/5429592#5429592)\n\n### **`fork`**\n\nForks the parent process, creating a child process.\nThe child process is almost identical to its parent,\nwith a copy of its memory space at the time of fork.\n\n- [https://www.man7.org/linux/man-pages/man2/fork.2.html](https://www.man7.org/linux/man-pages/man2/fork.2.html)\n- [https://www.youtube.com/watch?v=cex9XrZCU14\u0026list=PLfqABt5AS4FkW5mOn2Tn9ZZLLDwA3kZUY](https://www.youtube.com/watch?v=cex9XrZCU14\u0026list=PLfqABt5AS4FkW5mOn2Tn9ZZLLDwA3kZUY)\n\n### **`pipe`**\n\nCreates a pipe: a data channel through which processes can communicate.\nEmitting processes can write to`pipefd[1]`,\nand receiving ones can read from `pipefd[0]`.\n\n- [https://www.man7.org/linux/man-pages/man2/pipe.2.html](https://www.man7.org/linux/man-pages/man2/pipe.2.html)\n- [https://man7.org/linux/man-pages/man7/pipe.7.html](https://man7.org/linux/man-pages/man7/pipe.7.html)\n- [https://www.programacaoprogressiva.net/2014/09/Pipes-em-C-Comunicao-entre-Processos-IPC-Interprocess-Communication.html](https://www.programacaoprogressiva.net/2014/09/Pipes-em-C-Comunicao-entre-Processos-IPC-Interprocess-Communication.html)\n\n### **`unlink`**\n\n- [https://linux.die.net/man/2/unlink](https://linux.die.net/man/2/unlink)\n\n### **`wait` \u0026 `waitpid`**\n\nWait for a process to change state.\n\n- [https://man7.org/linux/man-pages/man2/wait.2.html](https://man7.org/linux/man-pages/man2/wait.2.html)\n- [https://www.man7.org/linux/man-pages/man3/waitpid.3p.html](https://www.man7.org/linux/man-pages/man3/waitpid.3p.html)\n\n### `char **envp`\n\nA string array with all the environment variables of the parent shell.\n\n- [https://www.geeksforgeeks.org/c-program-print-environment-variables/](https://www.geeksforgeeks.org/c-program-print-environment-variables/)\n- [https://www.geeksforgeeks.org/command-line-arguments-in-c-cpp/](https://www.geeksforgeeks.org/command-line-arguments-in-c-cpp/)\n- [https://stackoverflow.com/questions/54723587/what-does-envp-stand-for](https://stackoverflow.com/questions/54723587/what-does-envp-stand-for)\n\n### Processes vs Threads\n\n- Threads are lighter: easier to create and destroy\n- Processes don’t share memory\n\n### `lalloc` - Listed Memory Allocation\n\nA linked list in the control structure with all the allocated memory pointers.\nThe interface function `ft_lalloc` allocates memory and adds the pointer to the list.\nThe interface function `ft_free_lalloc` frees all pointers and the list.\n\n## 🛸 42 São Paulo \u003ca name = \"ft_sp\"\u003e\u003c/a\u003e\n\nPart of the larger [42 Network](https://www.42.fr/42-network/),\n[42 São Paulo](https://www.42sp.org.br/) is a software engineering school\nthat offers a healthy alternative to traditional education:\n\n- It doesn't have any teachers and classes.\n- Students learn by cooperating\n  and correcting each other's work (peer-to-peer learning).\n- Its focus is as much on social skills as it is on technical skills.\n- It's completely free to anyone that passes its selection process -\n  [**The Piscine**](https://42.fr/en/admissions/42-piscine/)\n\nIt's an amazing school, and I'm grateful for the opportunity.\n\n## 📚 Resources \u003ca name = \"resources\"\u003e\u003c/a\u003e\n\n### Bash Pipes\n\n- [https://wikiless.org/wiki/Pipeline\\_(Unix)?lang=en](\u003chttps://wikiless.org/wiki/Pipeline_(Unix)?lang=en\u003e)\n- [https://wikiless.org/wiki/Unix_philosophy?lang=en](https://wikiless.org/wiki/Unix_philosophy?lang=en)\n- [https://devhints.io/bash](https://devhints.io/bash)\n- [https://stackoverflow.com/questions/9834086/what-is-a-simple-explanation-for-how-pipes-work-in-bash](https://stackoverflow.com/questions/9834086/what-is-a-simple-explanation-for-how-pipes-work-in-bash)\n- [https://stackoverflow.com/questions/21287848/function-to-find-the-maximum-number-of-pipes](https://stackoverflow.com/questions/21287848/function-to-find-the-maximum-number-of-pipes)\n- [https://linuxconfig.org/introduction-to-named-pipes-on-bash-shell](https://linuxconfig.org/introduction-to-named-pipes-on-bash-shell)\n- [https://linuxhint.com/bash_pipe_tutorial/](https://linuxhint.com/bash_pipe_tutorial/)\n- [https://www.delftstack.com/howto/linux/pipes-in-bash/](https://www.delftstack.com/howto/linux/pipes-in-bash/)\n- [https://devdocs.io/bash/](https://devdocs.io/bash/)\n\n### Pipe Order\n\n- [https://www.gnu.org/software/bash/manual/html_node/Pipelines.html](https://www.gnu.org/software/bash/manual/html_node/Pipelines.html)\n- [https://www.gnu.org/software/bash/manual/html_node/Lists.html](https://www.gnu.org/software/bash/manual/html_node/Lists.html)\n- [https://stackoverflow.com/questions/66511243/bash-pipe-execution-order](https://stackoverflow.com/questions/66511243/bash-pipe-execution-order)\n- [https://unix.stackexchange.com/questions/37508/in-what-order-do-piped-commands-run](https://unix.stackexchange.com/questions/37508/in-what-order-do-piped-commands-run)\n- [https://linuxhint.com/bash_pipe_tutorial/](https://linuxhint.com/bash_pipe_tutorial/)\n\n### `nm -un`\n\n- [https://www.howtoforge.com/linux-nm-command/](https://www.howtoforge.com/linux-nm-command/)\n- [https://www.tutorialspoint.com/unix_commands/nm.htm](https://www.tutorialspoint.com/unix_commands/nm.htm)\n\n### CS 61\n\n- [https://cs61.seas.harvard.edu/site/2021/](https://cs61.seas.harvard.edu/site/2021/)\n- [https://cs61.seas.harvard.edu/site/2021/ProcessControl/](https://cs61.seas.harvard.edu/site/2021/ProcessControl/)\n- [https://cs61.seas.harvard.edu/site/2021/Section11/](https://cs61.seas.harvard.edu/site/2021/Section11/)\n\n### File Descriptors\n\n- [https://www.youtube.com/watch?v=6SA6S9Ca5-U](https://www.youtube.com/watch?v=6SA6S9Ca5-U)\n\n### FORBIDDEN! `execlp`\n\nA more convenient version of `execve`.\n\n- [https://linux.die.net/man/3/execlp](https://linux.die.net/man/3/execlp)\n\n### Valgrind Child Leaks\n\n- [https://stackoverflow.com/questions/16847385/valgrind-to-detect-memory-leak-in-child-process](https://stackoverflow.com/questions/16847385/valgrind-to-detect-memory-leak-in-child-process)\n\n### Testers\n\n- [https://github.com/denisgodoy/pipex-tester](https://github.com/denisgodoy/pipex-tester)\n- [https://github.com/vfurmane/pipex-tester](https://github.com/vfurmane/pipex-tester)\n- [https://github.com/Yoo0lh/pipex_tester_42](https://github.com/Yoo0lh/pipex_tester_42)\n- [https://github.com/HEADLIGHTER/pipexfasttest](https://github.com/HEADLIGHTER/pipexfasttest)\n- [https://github.com/gmarcha/pipexMedic](https://github.com/gmarcha/pipexMedic)\n- [https://github.com/gsilva-v/PipexTester](https://github.com/gsilva-v/PipexTester)\n- [https://github.com/mariadaan/PIPEXaminator](https://github.com/mariadaan/PIPEXaminator)\n\n### Parsing Tokens\n\n- [https://towardsdatascience.com/why-are-there-so-many-tokenization-methods-for-transformers-a340e493b3a8](https://towardsdatascience.com/why-are-there-so-many-tokenization-methods-for-transformers-a340e493b3a8)\n- [https://nlp.stanford.edu/IR-book/html/htmledition/tokenization-1.html](https://nlp.stanford.edu/IR-book/html/htmledition/tokenization-1.html)\n\n### C Quirks\n\n- [https://stackoverflow.com/questions/2407605/c-warning-missing-sentinel-in-function-call](https://stackoverflow.com/questions/2407605/c-warning-missing-sentinel-in-function-call)\n\n### Should I `free` before exiting?\n\n- [https://stackoverflow.com/questions/36584062/should-i-free-memory-before-exit](https://stackoverflow.com/questions/36584062/should-i-free-memory-before-exit)\n- [https://newbedev.com/should-i-free-memory-before-exit](https://newbedev.com/should-i-free-memory-before-exit)\n- [https://cboard.cprogramming.com/c-programming/75239-freeing-memory-before-exit.html](https://cboard.cprogramming.com/c-programming/75239-freeing-memory-before-exit.html)\n- [http://c-faq.com/malloc/freeb4exit.html](http://c-faq.com/malloc/freeb4exit.html)\n- [https://www.linuxquestions.org/questions/programming-9/to-free-or-not-to-free-before-an-exit-458107/](https://www.linuxquestions.org/questions/programming-9/to-free-or-not-to-free-before-an-exit-458107/)\n- [https://stackoverflow.com/questions/654754/what-really-happens-when-you-dont-free-after-malloc-before-program-termination](https://stackoverflow.com/questions/654754/what-really-happens-when-you-dont-free-after-malloc-before-program-termination)\n- [https://stackoverflow.com/questions/2975831/is-leaked-memory-freed-up-when-the-program-exits](https://stackoverflow.com/questions/2975831/is-leaked-memory-freed-up-when-the-program-exits)\n\n### Git `submodule`\n\n- `git clone --recurse-submodule REMOTE_REPO`\n- `git submodule add REMOTE_REPO`\n- `git submodule foreach git pull`\n- `git submodule update --init --recursive`\n- [https://stackoverflow.com/questions/33714063/how-to-update-submodules-in-git](https://stackoverflow.com/questions/33714063/how-to-update-submodules-in-git)\n- [https://stackoverflow.com/questions/59271919/how-to-clone-public-submodule-in-github-actions](https://stackoverflow.com/questions/59271919/how-to-clone-public-submodule-in-github-actions)\n- [https://stackoverflow.com/questions/50254184/git-submodule-and-fetch](https://stackoverflow.com/questions/50254184/git-submodule-and-fetch)\n- [https://www.w3docs.com/snippets/git/how-to-add-a-submodule-in-git.html](https://www.w3docs.com/snippets/git/how-to-add-a-submodule-in-git.html)\n- [https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule#1260982](https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule#1260982)\n- [https://stackoverflow.com/questions/2006172/git-how-to-reset-a-remote-git-repository-to-remove-all-commits](https://stackoverflow.com/questions/2006172/git-how-to-reset-a-remote-git-repository-to-remove-all-commits)\n\n### Bash Quirks\n\n- [https://linuxize.com/post/bash-shebang/](https://linuxize.com/post/bash-shebang/)\n- [https://stackoverflow.com/questions/18219262/evaluating-variables-in-a-string](https://stackoverflow.com/questions/18219262/evaluating-variables-in-a-string)\n- [https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux](https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux)\n- [https://stackoverflow.com/questions/1951742/how-can-i-symlink-a-file-in-linux](https://stackoverflow.com/questions/1951742/how-can-i-symlink-a-file-in-linux)\n- [https://stackoverflow.com/questions/9452935/unix-create-path-of-folders-and-file](https://stackoverflow.com/questions/9452935/unix-create-path-of-folders-and-file)\n\n### Videos\n\n- [https://www.youtube.com/watch?v=6xbLgZpOBi8](https://www.youtube.com/watch?v=6xbLgZpOBi8)\n- [https://www.youtube.com/playlist?list=PLFAC320731F539902](https://www.youtube.com/playlist?list=PLFAC320731F539902)\n- [https://www.youtube.com/results?search_query=c+pipe+fork+wait](https://www.youtube.com/results?search_query=c+pipe+fork+wait)\n- [https://www.youtube.com/playlist?list=PLfqABt5AS4FkW5mOn2Tn9ZZLLDwA3kZUY](https://www.youtube.com/playlist?list=PLfqABt5AS4FkW5mOn2Tn9ZZLLDwA3kZUY)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrity%2Fft_pipex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibrity%2Fft_pipex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrity%2Fft_pipex/lists"}