From 5d425048f2713ae58b580e69f9a2ddaed0d3d752 Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Wed, 27 Mar 2024 13:42:54 +0100 Subject: [PATCH] Added: Pipex as ressources, not most readable code tho... --- other/pipex/.clang-format | 9 + other/pipex/.clangd | 20 ++ other/pipex/.envrc | 1 + other/pipex/.gitignore | 60 ++++ other/pipex/.gitmodules | 3 + other/pipex/Makefile | 139 ++++++++ other/pipex/flake.lock | 314 ++++++++++++++++++ other/pipex/flake.nix | 39 +++ other/pipex/generic_files.list | 8 + other/pipex/include/app/main.h | 67 ++++ other/pipex/include/me/os/pipe.h | 26 ++ other/pipex/include/me/os/process.h | 145 ++++++++ .../me/string/inner/inner_split_literals.h | 31 ++ .../pipex/include/me/string/split_literals.h | 21 ++ other/pipex/input.toml | 56 ++++ .../pipex/output/include/me/vec/vec_buf_str.h | 51 +++ .../pipex/output/include/me/vec/vec_process.h | 49 +++ other/pipex/output/include/me/vec/vec_str.h | 46 +++ other/pipex/output/include/me/vec/vec_u8.h | 45 +++ other/pipex/output/src/vec/vec_buf_str.c | 115 +++++++ .../output/src/vec/vec_buf_str_functions2.c | 110 ++++++ other/pipex/output/src/vec/vec_process.c | 115 +++++++ .../output/src/vec/vec_process_functions2.c | 109 ++++++ other/pipex/output/src/vec/vec_str.c | 114 +++++++ .../pipex/output/src/vec/vec_str_functions2.c | 106 ++++++ other/pipex/output/src/vec/vec_u8.c | 114 +++++++ .../pipex/output/src/vec/vec_u8_functions2.c | 106 ++++++ other/pipex/source_files.list | 9 + other/pipex/src/app/main.c | 119 +++++++ other/pipex/src/app/main2.c | 47 +++ other/pipex/src/app/main3.c | 48 +++ other/pipex/src/lib/os/pipe.c | 24 ++ other/pipex/src/lib/os/process.c | 141 ++++++++ other/pipex/src/lib/os/process_inner.c | 33 ++ other/pipex/src/lib/os/process_inner2.c | 92 +++++ .../lib/string/inner/split_literals_escaped.c | 118 +++++++ other/pipex/src/lib/string/split_literals.c | 100 ++++++ other/pipex/subject.txt | 225 +++++++++++++ 38 files changed, 2975 insertions(+) create mode 100644 other/pipex/.clang-format create mode 100644 other/pipex/.clangd create mode 100644 other/pipex/.envrc create mode 100644 other/pipex/.gitignore create mode 100644 other/pipex/.gitmodules create mode 100644 other/pipex/Makefile create mode 100644 other/pipex/flake.lock create mode 100644 other/pipex/flake.nix create mode 100644 other/pipex/generic_files.list create mode 100644 other/pipex/include/app/main.h create mode 100644 other/pipex/include/me/os/pipe.h create mode 100644 other/pipex/include/me/os/process.h create mode 100644 other/pipex/include/me/string/inner/inner_split_literals.h create mode 100644 other/pipex/include/me/string/split_literals.h create mode 100644 other/pipex/input.toml create mode 100644 other/pipex/output/include/me/vec/vec_buf_str.h create mode 100644 other/pipex/output/include/me/vec/vec_process.h create mode 100644 other/pipex/output/include/me/vec/vec_str.h create mode 100644 other/pipex/output/include/me/vec/vec_u8.h create mode 100644 other/pipex/output/src/vec/vec_buf_str.c create mode 100644 other/pipex/output/src/vec/vec_buf_str_functions2.c create mode 100644 other/pipex/output/src/vec/vec_process.c create mode 100644 other/pipex/output/src/vec/vec_process_functions2.c create mode 100644 other/pipex/output/src/vec/vec_str.c create mode 100644 other/pipex/output/src/vec/vec_str_functions2.c create mode 100644 other/pipex/output/src/vec/vec_u8.c create mode 100644 other/pipex/output/src/vec/vec_u8_functions2.c create mode 100644 other/pipex/source_files.list create mode 100644 other/pipex/src/app/main.c create mode 100644 other/pipex/src/app/main2.c create mode 100644 other/pipex/src/app/main3.c create mode 100644 other/pipex/src/lib/os/pipe.c create mode 100644 other/pipex/src/lib/os/process.c create mode 100644 other/pipex/src/lib/os/process_inner.c create mode 100644 other/pipex/src/lib/os/process_inner2.c create mode 100644 other/pipex/src/lib/string/inner/split_literals_escaped.c create mode 100644 other/pipex/src/lib/string/split_literals.c create mode 100644 other/pipex/subject.txt diff --git a/other/pipex/.clang-format b/other/pipex/.clang-format new file mode 100644 index 00000000..6b13f20e --- /dev/null +++ b/other/pipex/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Microsoft +IndentWidth: 4 +ColumnLimit: 80 +UseTab: Always +SortIncludes: CaseInsensitive +IndentPPDirectives: AfterHash +PPIndentWidth: 1 +AllowShortIfStatementsOnASingleLine: false +AlignConsecutiveDeclarations: true diff --git a/other/pipex/.clangd b/other/pipex/.clangd new file mode 100644 index 00000000..cde24ec5 --- /dev/null +++ b/other/pipex/.clangd @@ -0,0 +1,20 @@ +CompileFlags: # Tweak the parse settings + Add: + - "-I/usr/include/" + - "-I/home/maix/school/pipex/mlx/" + - "-I/home/maix/school/pipex/mecstd/include/" + - "-I/home/maix/school/pipex/mecstd/vendor/" + - "-I/home/maix/school/pipex/mecstd/output/include/" + - "-I/home/maix/school/pipex/mecstd/generic_sources/header/" + - "-I/home/maix/school/pipex/include/" + - "-I/home/maix/school/pipex/output/include/" + - "-I/home/maix/school/pipex/generic_sources/header/" + - "-I/home/maiboyer/Documents/ring-1/pipex/vendor/" + - "-I/home/maiboyer/Documents/ring-1/pipex/mecstd/include/" + - "-I/home/maiboyer/Documents/ring-1/pipex/mecstd/vendor/" + - "-I/home/maiboyer/Documents/ring-1/pipex/mecstd/output/include/" + - "-I/home/maiboyer/Documents/ring-1/pipex/mecstd/generic_sources/header/" + - "-I/home/maiboyer/Documents/ring-1/pipex/include/" + - "-I/home/maiboyer/Documents/ring-1/pipex/output/include/" + - "-I/home/maiboyer/Documents/ring-1/pipex/generic_sources/header/" + diff --git a/other/pipex/.envrc b/other/pipex/.envrc new file mode 100644 index 00000000..3550a30f --- /dev/null +++ b/other/pipex/.envrc @@ -0,0 +1 @@ +use flake diff --git a/other/pipex/.gitignore b/other/pipex/.gitignore new file mode 100644 index 00000000..88cb22bc --- /dev/null +++ b/other/pipex/.gitignore @@ -0,0 +1,60 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +./generic +.direnv +test +so_long +vgcore.* +a.out +pipex diff --git a/other/pipex/.gitmodules b/other/pipex/.gitmodules new file mode 100644 index 00000000..92ca1ba3 --- /dev/null +++ b/other/pipex/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mecstd"] + path = mecstd + url = git@github.com:Maix0/mecstd.git diff --git a/other/pipex/Makefile b/other/pipex/Makefile new file mode 100644 index 00000000..5bfcc459 --- /dev/null +++ b/other/pipex/Makefile @@ -0,0 +1,139 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: maiboyer +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2023/11/03 13:20:01 by maiboyer #+# #+# # +# Updated: 2024/01/06 18:59:45 by maiboyer ### ########.fr # +# # +# **************************************************************************** # + +define_module = $(addprefix $(1)/, $(2)) + +BUILD_DIR = build +SRC_DIR = src +INCLUDE_DIR = include output/include +LIBS_DIR = . +GENERIC_DIR = output/src +GENERIC_INCLUDE = output/include + +BONUS_FLAGS = +NAME = pipex +LIB_NAME ?= +TARGET = $(NAME) +CC = clang +CFLAGS = -Wall -Wextra -Werror -g2 -lme -L$(BUILD_DIR) -Wno-unused-command-line-argument -MMD -Wno-unused-parameter -Wno-unused-variable +BONUS_FILES = +LIBS_NAME = mecstd +SUBJECT_URL = 'https://cdn.intra.42.fr/pdf/pdf/105445/en.subject.pdf' + +GENERIC_FILES = $(shell cat generic_files.list) +SRC_FILES = $(shell cat source_files.list) + +BONUS = $(addsuffix .c,$(addprefix $(SRC_DIR)/,$(BONUS_FILES))) +SRC = $(addsuffix .c,$(addprefix $(SRC_DIR)/,$(SRC_FILES))) \ + $(addsuffix .c,$(addprefix $(GENERIC_DIR)/,$(GENERIC_FILES))) +BONUS_OBJ = $(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(BONUS_FILES))) +OBJ = $(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(SRC_FILES))) \ + $(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(GENERIC_FILES))) +DEPS = $(addsuffix .d,$(addprefix $(BUILD_DIR)/,$(SRC_FILES))) \ + $(addsuffix .d,$(addprefix $(BUILD_DIR)/,$(GENERIC_FILES))) +LIBS = $(addprefix $(LIBS_DIR)/,$(LIBS_NAME)) +INCLUDES = $(addprefix -I,$(foreach P,$(INCLUDE_DIR) $(GENERIC_INCLUDE) $(LIBS) $(addsuffix /include,$(LIBS)) vendor $(addsuffix /vendor,$(LIBS)),$(realpath $(P)))) +COL_GRAY = \\e[90m +COL_WHITE = \\e[37m +COL_GREEN = \\e[32m +COL_BOLD = \\e[1m +COL_RESET = \\e[0m + +.PHONY: all +.PHONY: libs_build +.PHONY: bonus +.PHONY: clean +.PHONY: fclean +.PHONY: re +.PHONY: format +.PHONY: subject +.PHONY: submit +.PHONY: so + +all: $(NAME) + +bonus: fclean +bonus: BONUS_FLAGS = -DBONUS=1 +bonus: all + +get_lib: + @printf $(LIB_NAME)/$(NAME) + +$(NAME): $(OBJ) libs_build + @printf \\n$(COL_GRAY)Building\ Output\ $(COL_WHITE)$(COL_BOLD)%-28s$(COL_RESET)\ \ + $(NAME) + @$(CC) $(INCLUDES) $(OBJ) $(CFLAGS) $(BONUS_FLAGS) -o $(NAME) + @#ar rcs $(BUILD_DIR)/$(NAME) $(OBJ) + @printf $(COL_GREEN)done$(COL_RESET)\\n + +libs_build: + @- $(foreach LIB,$(LIBS),\ + mkdir -p $(BUILD_DIR); \ + printf \\n; \ + printf $(COL_GRAY)Building\ library\ $(COL_RESET); \ + printf $(COL_WHITE)$(COL_BOLD)%-25s$(COL_RESET)\\n $(LIB); \ + make LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory all; \ + printf \\n; \ + ) + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c + @mkdir -p $(dir $@) + @printf $(COL_GRAY)Building\ $(COL_BOLD)$(COL_WHITE)%-50s\ $(LIB_NAME)$< + @$(CC) $(CFLAGS) $(WERROR) $(BONUS_FLAGS) $(INCLUDES) -c $< -o $@ + @printf $(COL_RESET)$(COL_GREEN)done$(COL_RESET)\\n + +$(BUILD_DIR)/%.o: $(GENERIC_DIR)/%.c + @mkdir -p $(dir $@) + @printf $(COL_GRAY)Building\ $(COL_BOLD)$(COL_WHITE)%-50s\ $(LIB_NAME)$< + @$(CC) $(CFLAGS) $(WERROR) $(BONUS_FLAGS) $(INCLUDES) -c $< -o $@ + @printf $(COL_RESET)$(COL_GREEN)done$(COL_RESET)\\n + +clean: + @- $(foreach LIB,$(LIBS), \ + make clean LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory || true;\ + ) + @- $(if $(LIB_NAME),,\ + printf $(COL_WHITE)Clearing\ Artefacts\ ; \ + printf $(COL_GRAY)\%-25s$(COL_RESET)\ \($(BUILD_DIR)\); \ + rm -rf $(BUILD_DIR); \ + printf $(COL_GREEN)done$(COL_RESET)\\n; \ + ) + @echo >/dev/null + +fclean: clean + @- $(foreach LIB,$(LIBS), \ + make fclean LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory || true;\ + ) + @printf $(COL_WHITE)Clearing\ Output\ $(COL_GRAY)%-28s$(COL_RESET)\ \ + \($(LIB_NAME)$(NAME)\) + @rm -f $(BUILD_DIR)$(NAME) + @printf $(COL_GREEN)done$(COL_RESET)\\n + +re: fclean all + +format: + @zsh -c "c_formatter_42 **/*.c **/*.h" + +subject: subject.txt + @bat --plain subject.txt + +subject.txt: + @curl $(SUBJECT_URL) | pdftotext -layout -nopgbrk - subject.txt + +fuck_raphael: + @echo "Oh que oui~~~\net jte nioc" + +generate_filelist: + @/usr/bin/env zsh -c "tree -iFf --noreport output | rg '^output/src/(.*)\.c\$$' --replace '\$$1' | sort -u" > ./generic_files.list + @/usr/bin/env zsh -c "tree -iFf --noreport src | rg '^src/(.*)\.c\$$' --replace '\$$1' | sort -u" > ./source_files.list + +-include $(DEPS) diff --git a/other/pipex/flake.lock b/other/pipex/flake.lock new file mode 100644 index 00000000..55d690df --- /dev/null +++ b/other/pipex/flake.lock @@ -0,0 +1,314 @@ +{ + "nodes": { + "c_formatter_42": { + "inputs": { + "c_formatter_42_src": "c_formatter_42_src", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1700259489, + "narHash": "sha256-Ye2zwphDUY/eDjyFCPFt0r9RyqMr4ZQprCE4bydNdpw=", + "owner": "maix0", + "repo": "c_formatter_42-flake", + "rev": "3d4f6a40bd1edf9fdb4959051edc172473d9544d", + "type": "github" + }, + "original": { + "owner": "maix0", + "repo": "c_formatter_42-flake", + "type": "github" + } + }, + "c_formatter_42_src": { + "flake": false, + "locked": { + "lastModified": 1696506114, + "narHash": "sha256-jUScF2lAHhjTWOWZsIAocE6FN8+HG+kLdpbYsEA1SZs=", + "owner": "dawnbeen", + "repo": "c_formatter_42", + "rev": "ef91ff383966885374695c327fa6015f9cfbc364", + "type": "github" + }, + "original": { + "owner": "dawnbeen", + "repo": "c_formatter_42", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "generic_c": { + "inputs": { + "flake-utils": "flake-utils_3", + "naersk": "naersk", + "nixpkgs": "nixpkgs_3", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1702388541, + "narHash": "sha256-ExzIrROCDRXVnvbOs81aL9DKHm1OxlzVXQPpUTrB75c=", + "owner": "maix0", + "repo": "generic_c", + "rev": "52b5de885c015d3b84ca26c02c3684ca0e9b426d", + "type": "github" + }, + "original": { + "owner": "maix0", + "repo": "generic_c", + "type": "github" + } + }, + "naersk": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1698420672, + "narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=", + "owner": "nix-community", + "repo": "naersk", + "rev": "aeb58d5e8faead8980a807c840232697982d47b9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "naersk", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1700108881, + "narHash": "sha256-+Lqybl8kj0+nD/IlAWPPG/RDTa47gff9nbei0u7BntE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7414e9ee0b3e9903c24d3379f577a417f0aae5f1", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1704008649, + "narHash": "sha256-rGPSWjXTXTurQN9beuHdyJhB8O761w1Zc5BqSSmHvoM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d44d59d2b5bd694cd9d996fd8c51d03e3e9ba7f7", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1702272962, + "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1681358109, + "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1704008649, + "narHash": "sha256-rGPSWjXTXTurQN9beuHdyJhB8O761w1Zc5BqSSmHvoM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d44d59d2b5bd694cd9d996fd8c51d03e3e9ba7f7", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "c_formatter_42": "c_formatter_42", + "flake-utils": "flake-utils_2", + "generic_c": "generic_c", + "nixpkgs": "nixpkgs_5" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1702347444, + "narHash": "sha256-ueDw7aQf4Xyk69XnDD0YNWDlFdlOgJGPeWFa7uu/cfw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "bc13176f27cf3be724d18924b4f6aa47686ca2e3", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/other/pipex/flake.nix b/other/pipex/flake.nix new file mode 100644 index 00000000..24419eca --- /dev/null +++ b/other/pipex/flake.nix @@ -0,0 +1,39 @@ +{ + description = "Flake utils demo"; + + inputs = { + flake-utils.url = "github:numtide/flake-utils"; + generic_c.url = "github:maix0/generic_c"; + c_formatter_42.url = "github:maix0/c_formatter_42-flake"; + }; + outputs = { + self, + nixpkgs, + flake-utils, + generic_c, + c_formatter_42, + }: + flake-utils.lib.eachDefaultSystem ( + system: let + pkgs = nixpkgs.legacyPackages.${system}; + in { + devShell = pkgs.mkShell { + packages = [ + pkgs.xorg.libXext + pkgs.xorg.libX11 + pkgs.clang + pkgs.clang-tools + pkgs.norminette + generic_c.packages.${system}.default + c_formatter_42.packages.${system}.default + pkgs.poppler_utils + pkgs.minilibx + pkgs.valgrind + pkgs.libbsd + pkgs.tree + pkgs.fastmod + ]; + }; + } + ); +} diff --git a/other/pipex/generic_files.list b/other/pipex/generic_files.list new file mode 100644 index 00000000..51883396 --- /dev/null +++ b/other/pipex/generic_files.list @@ -0,0 +1,8 @@ +vec/vec_buf_str +vec/vec_buf_str_functions2 +vec/vec_process +vec/vec_process_functions2 +vec/vec_str +vec/vec_str_functions2 +vec/vec_u8 +vec/vec_u8_functions2 diff --git a/other/pipex/include/app/main.h b/other/pipex/include/app/main.h new file mode 100644 index 00000000..77345084 --- /dev/null +++ b/other/pipex/include/app/main.h @@ -0,0 +1,67 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/06 18:51:07 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:52:58 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MAIN_H +# define MAIN_H + +# include "me/fs/open.h" +# include "me/fs/read.h" +# include "me/fs/write.h" +# include "me/gnl/gnl.h" +# include "me/mem/mem_find_bytes.h" +# include "me/mem/mem_move.h" +# include "me/os/pipe.h" +# include "me/os/process.h" +# include "me/printf/printf.h" +# include "me/string/split_literals.h" +# include "me/string/str_clone.h" +# include "me/string/str_len.h" +# include "me/string/str_n_compare.h" +# include "me/string/str_n_find_str.h" +# include "me/vec/vec_process.h" +# include "me/vec/vec_str.h" +# include +# include +# include + +# ifndef BONUS +# define BONUS 0 +# endif + +typedef struct s_pipex_args +{ + t_usize argc; + t_str *argv; + bool here_doc; + t_str here_doc_limiter; + t_file here_doc_fd; + t_vec_str env; + t_file in; + t_file out; + t_vec_process processes; + t_usize min; + t_usize max; +} t_pipex_args; + +void set_here_doc(t_pipex_args *s); +void open_read_file(t_pipex_args *s); +void clone_vec_str_iter_fn(t_usize idx, t_str *s, void *out); +t_vec_str clone_vec_str(t_vec_str *v); +void vec_process_free_ptr(void *s); +t_error spawn_helper(t_pipex_args *s, t_usize idx, t_redirection in, + t_redirection out); +void cleanup(t_pipex_args *s, bool error); +void process_cleanup(t_process elem); +void do_here_doc_thing(t_pipex_args *s); +int main2(t_pipex_args *s); + +#endif /* MAIN_H */ diff --git a/other/pipex/include/me/os/pipe.h b/other/pipex/include/me/os/pipe.h new file mode 100644 index 00000000..14cf3239 --- /dev/null +++ b/other/pipex/include/me/os/pipe.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pipe.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 17:57:29 by maiboyer #+# #+# */ +/* Updated: 2024/01/04 17:59:30 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PIPE_H +# define PIPE_H + +# include "me/types.h" + +typedef struct s_pipe +{ + t_file read; + t_file write; +} t_pipe; + +t_error create_pipe(t_pipe *out); + +#endif /* PIPE_H */ diff --git a/other/pipex/include/me/os/process.h b/other/pipex/include/me/os/process.h new file mode 100644 index 00000000..cccb65c8 --- /dev/null +++ b/other/pipex/include/me/os/process.h @@ -0,0 +1,145 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/03 15:43:08 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:39:58 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PROCESS_H +# define PROCESS_H + +# include "me/types.h" +# include "me/vec/vec_str.h" +# include "me/vec/vec_u8.h" + +typedef t_i32 t_pid; +typedef t_i32 t_exit_code; + +enum e_redirection +{ + R_INHERITED = 0, + R_PIPED = 1, + R_FD = 2, +}; + +union u_redirection +{ + struct s_fd + { + t_file value; + } fd; + struct s_piped + { + } piped; + struct s_inherited + { + } inherited; +}; + +typedef struct s_redirection +{ + enum e_redirection tag; + union u_redirection vals; +} t_redirection; + +static inline t_redirection piped(void) +{ + return ((t_redirection){ + .tag = R_PIPED, + }); +} + +static inline t_redirection inherited(void) +{ + return ((t_redirection){ + .tag = R_INHERITED, + }); +} + +static inline t_redirection fd(t_file fd) +{ + return ((t_redirection){.tag = R_FD, \ + .vals = (union u_redirection){.fd = {.value = fd},}}); +} + +enum e_wrapped_fd_tag +{ + READ_ONLY, + WRITE_ONLY, + READ_WRITE, + INVALID, +}; + +union u_wrapped_fd +{ + struct s_read_only + { + t_file fd; + } ro; + struct s_write_only + { + t_file fd; + } wo; + struct s_read_write + { + t_file fd; + } rw; +}; + +typedef struct s_wrapped_fd +{ + enum e_wrapped_fd_tag tag; + union u_wrapped_fd vals; +} t_wrapped_fd; + +static inline t_wrapped_fd ro(t_file fd) +{ + return ((t_wrapped_fd){.tag = READ_ONLY, + .vals = (union u_wrapped_fd){ + .ro = {.fd = fd}, + }}); +} + +static inline t_wrapped_fd wo(t_file fd) +{ + return ((t_wrapped_fd){.tag = WRITE_ONLY, + .vals = (union u_wrapped_fd){.wo = {.fd = fd}}}); +} + +typedef struct s_spawn_info +{ + t_redirection stdin; + t_redirection stdout; + t_redirection stderr; + t_vec_str arguments; + t_vec_str environement; + t_str binary_path; + void (*forked_free)(void *); + void *forked_free_args; +} t_spawn_info; + +typedef struct s_process +{ + t_wrapped_fd stdin; + t_wrapped_fd stdout; + t_wrapped_fd stderr; + t_pid pid; +} t_process; + +typedef struct s_process_output +{ + t_pid pid; + t_vec_u8 stdout; + t_vec_u8 stderr; + t_exit_code exit_code; +} t_process_output; + +t_error spawn_process(t_spawn_info info, + t_process *process); + +#endif /* PROCESS_H */ diff --git a/other/pipex/include/me/string/inner/inner_split_literals.h b/other/pipex/include/me/string/inner/inner_split_literals.h new file mode 100644 index 00000000..67d1912d --- /dev/null +++ b/other/pipex/include/me/string/inner/inner_split_literals.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* inner_split_literals.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 14:33:41 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:42:41 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef INNER_SPLIT_LITERALS_H +# define INNER_SPLIT_LITERALS_H + +# include "me/string/split_literals.h" +# include "me/types.h" + +typedef struct s_booleans +{ + bool error; + bool lit_sq; + bool lit_dq; + bool esc; + bool append; +} t_booleans; + +char unescape(t_const_str s, t_usize *current_index, bool *did_escape, + t_error *error); + +#endif /* INNER_SPLIT_LITERALS_H */ diff --git a/other/pipex/include/me/string/split_literals.h b/other/pipex/include/me/string/split_literals.h new file mode 100644 index 00000000..b8194c99 --- /dev/null +++ b/other/pipex/include/me/string/split_literals.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* split_literals.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 14:31:04 by maiboyer #+# #+# */ +/* Updated: 2024/01/04 14:32:40 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SPLIT_LITERALS_H +# define SPLIT_LITERALS_H + +# include "me/types.h" +# include "me/vec/vec_str.h" + +t_error split_literals(t_const_str s, t_vec_str *out); + +#endif /* SPLIT_LITERALS_H */ diff --git a/other/pipex/input.toml b/other/pipex/input.toml new file mode 100644 index 00000000..5936aba9 --- /dev/null +++ b/other/pipex/input.toml @@ -0,0 +1,56 @@ +[definition.vec] +headers = ["mecstd/generic_sources/header/vec_C__PREFIX__.h__TEMPLATE__"] +sources = [ + "mecstd/generic_sources/src/vec_C__PREFIX__.c__TEMPLATE__", + "mecstd/generic_sources/src/vec_C__PREFIX___functions2.c__TEMPLATE__", +] +replace.C__TYPENAME__ = "type" +replace.C__TYPEHEADER__ = "header_include" +replace.C__PREFIX__ = "prefix" +replace.C__PREFIXUP__ = "prefix" + + +[definition.hashmap] +headers = ["mecstd/generic_sources/header/hashmap_C__PREFIX__.h__TEMPLATE__"] +sources = [ + "mecstd/generic_sources/src/hashmap_C__PREFIX__.c__TEMPLATE__", + "mecstd/generic_sources/src/hashmap_C__PREFIX___utils.c__TEMPLATE__", +] +replace.C__VALTYPE__ = "type" +replace.C__KEYTYPE__ = "type" +replace.C__TYPEHEADER__ = "header_include" +replace.C__PREFIX__ = "prefix" +replace.C__PREFIXUP__ = "prefix" + + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_u8" +replace.C__TYPEHEADER__ = '' +replace.C__PREFIX__ = "u8" +replace.C__PREFIXUP__ = "U8" + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_buffer_str" +replace.C__TYPEHEADER__ = '#include "me/buffered_str/buf_str.h"' +replace.C__PREFIX__ = "buf_str" +replace.C__PREFIXUP__ = "BUF_STR" + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_str" +replace.C__TYPEHEADER__ = '' +replace.C__PREFIX__ = "str" +replace.C__PREFIXUP__ = "STR" + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_process" +replace.C__TYPEHEADER__ = '#include "me/os/process.h"' +replace.C__PREFIX__ = "process" +replace.C__PREFIXUP__ = "PROCESS" diff --git a/other/pipex/output/include/me/vec/vec_buf_str.h b/other/pipex/output/include/me/vec/vec_buf_str.h new file mode 100644 index 00000000..9e424e66 --- /dev/null +++ b/other/pipex/output/include/me/vec/vec_buf_str.h @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_buf_str.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_BUF_STR_H +# define VEC_BUF_STR_H + +# include "me/buffered_str/buf_str.h" +# include "me/types.h" + +typedef void (*t_free_buf_str_item)(t_buffer_str); + +typedef struct s_vec_buf_str +{ + t_free_buf_str_item free_func; + t_usize len; + t_usize capacity; + t_buffer_str *buffer; +} t_vec_buf_str; + +t_vec_buf_str vec_buf_str_new(t_usize capacity, + t_free_buf_str_item free_function); +t_error vec_buf_str_push(t_vec_buf_str *vec, + t_buffer_str element); +t_error vec_buf_str_pop(t_vec_buf_str *vec, + t_buffer_str *value); +void vec_buf_str_free(t_vec_buf_str vec); +t_error vec_buf_str_reserve(t_vec_buf_str *vec, + t_usize wanted_capacity); +t_error vec_buf_str_find(t_vec_buf_str *vec, + bool (*fn)(const t_buffer_str *), t_usize *index); +t_error vec_buf_str_find_starting(t_vec_buf_str *vec, + bool (*fn)(const t_buffer_str *), + t_usize starting_index, t_usize *index); +t_error vec_buf_str_all(t_vec_buf_str *vec, + bool (*fn)(const t_buffer_str *), bool *result); +t_error vec_buf_str_any(t_vec_buf_str *vec, + bool (*fn)(const t_buffer_str *), bool *result); +void vec_buf_str_iter(t_vec_buf_str *vec, + void (*fn)(t_usize index, t_buffer_str *value, + void *state), void *state); + +#endif diff --git a/other/pipex/output/include/me/vec/vec_process.h b/other/pipex/output/include/me/vec/vec_process.h new file mode 100644 index 00000000..d423b064 --- /dev/null +++ b/other/pipex/output/include/me/vec/vec_process.h @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_process.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_PROCESS_H +# define VEC_PROCESS_H + +# include "me/os/process.h" +# include "me/types.h" + +typedef void (*t_free_process_item)(t_process); + +typedef struct s_vec_process +{ + t_free_process_item free_func; + t_usize len; + t_usize capacity; + t_process *buffer; +} t_vec_process; + +t_vec_process vec_process_new(t_usize capacity, + t_free_process_item free_function); +t_error vec_process_push(t_vec_process *vec, t_process element); +t_error vec_process_pop(t_vec_process *vec, t_process *value); +void vec_process_free(t_vec_process vec); +t_error vec_process_reserve(t_vec_process *vec, + t_usize wanted_capacity); +t_error vec_process_find(t_vec_process *vec, + bool (*fn)(const t_process *), t_usize *index); +t_error vec_process_find_starting(t_vec_process *vec, + bool (*fn)(const t_process *), + t_usize starting_index, t_usize *index); +t_error vec_process_all(t_vec_process *vec, + bool (*fn)(const t_process *), bool *result); +t_error vec_process_any(t_vec_process *vec, + bool (*fn)(const t_process *), bool *result); +void vec_process_iter(t_vec_process *vec, + void (*fn)(t_usize index, t_process *value, + void *state), void *state); + +#endif diff --git a/other/pipex/output/include/me/vec/vec_str.h b/other/pipex/output/include/me/vec/vec_str.h new file mode 100644 index 00000000..df7bc7c4 --- /dev/null +++ b/other/pipex/output/include/me/vec/vec_str.h @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_str.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_STR_H +# define VEC_STR_H + +# include "me/types.h" + +typedef void (*t_free_str_item)(t_str); + +typedef struct s_vec_str +{ + t_free_str_item free_func; + t_usize len; + t_usize capacity; + t_str *buffer; +} t_vec_str; + +t_vec_str vec_str_new(t_usize capacity, + t_free_str_item free_function); +t_error vec_str_push(t_vec_str *vec, t_str element); +t_error vec_str_pop(t_vec_str *vec, t_str *value); +void vec_str_free(t_vec_str vec); +t_error vec_str_reserve(t_vec_str *vec, t_usize wanted_capacity); +t_error vec_str_find(t_vec_str *vec, bool (*fn)(const t_str *), + t_usize *index); +t_error vec_str_find_starting(t_vec_str *vec, + bool (*fn)(const t_str *), t_usize starting_index, + t_usize *index); +t_error vec_str_all(t_vec_str *vec, bool (*fn)(const t_str *), + bool *result); +t_error vec_str_any(t_vec_str *vec, bool (*fn)(const t_str *), + bool *result); +void vec_str_iter(t_vec_str *vec, void (*fn)(t_usize index, + t_str *value, void *state), void *state); + +#endif diff --git a/other/pipex/output/include/me/vec/vec_u8.h b/other/pipex/output/include/me/vec/vec_u8.h new file mode 100644 index 00000000..e9ded875 --- /dev/null +++ b/other/pipex/output/include/me/vec/vec_u8.h @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_u8.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_U8_H +# define VEC_U8_H + +# include "me/types.h" + +typedef void (*t_free_u8_item)(t_u8); + +typedef struct s_vec_u8 +{ + t_free_u8_item free_func; + t_usize len; + t_usize capacity; + t_u8 *buffer; +} t_vec_u8; + +t_vec_u8 vec_u8_new(t_usize capacity, t_free_u8_item free_function); +t_error vec_u8_push(t_vec_u8 *vec, t_u8 element); +t_error vec_u8_pop(t_vec_u8 *vec, t_u8 *value); +void vec_u8_free(t_vec_u8 vec); +t_error vec_u8_reserve(t_vec_u8 *vec, t_usize wanted_capacity); +t_error vec_u8_find(t_vec_u8 *vec, bool (*fn)(const t_u8 *), + t_usize *index); +t_error vec_u8_find_starting(t_vec_u8 *vec, + bool (*fn)(const t_u8 *), t_usize starting_index, + t_usize *index); +t_error vec_u8_all(t_vec_u8 *vec, bool (*fn)(const t_u8 *), + bool *result); +t_error vec_u8_any(t_vec_u8 *vec, bool (*fn)(const t_u8 *), + bool *result); +void vec_u8_iter(t_vec_u8 *vec, void (*fn)(t_usize index, + t_u8 *value, void *state), void *state); + +#endif diff --git a/other/pipex/output/src/vec/vec_buf_str.c b/other/pipex/output/src/vec/vec_buf_str.c new file mode 100644 index 00000000..281433a1 --- /dev/null +++ b/other/pipex/output/src/vec/vec_buf_str.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_buf_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_buf_str.h" +#include + +t_vec_buf_str vec_buf_str_new(t_usize capacity, + t_free_buf_str_item free_function) +{ + t_vec_buf_str out; + + out = (t_vec_buf_str){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_buffer_str)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_buf_str_push(t_vec_buf_str *vec, t_buffer_str element) +{ + t_buffer_str *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_buffer_str)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_buffer_str)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_buf_str_reserve(t_vec_buf_str *vec, t_usize wanted_capacity) +{ + t_buffer_str *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_buffer_str)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_buffer_str)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_buf_str_pop(t_vec_buf_str *vec, t_buffer_str *value) +{ + t_buffer_str temp_value; + t_buffer_str *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_buffer_str)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_buf_str_free(t_vec_buf_str vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/other/pipex/output/src/vec/vec_buf_str_functions2.c b/other/pipex/output/src/vec/vec_buf_str_functions2.c new file mode 100644 index 00000000..6bee346d --- /dev/null +++ b/other/pipex/output/src/vec/vec_buf_str_functions2.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_buf_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_buf_str.h" +#include + +t_error vec_buf_str_find(t_vec_buf_str *vec, bool (*fn)(const t_buffer_str *), + t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_buf_str_find_starting(t_vec_buf_str *vec, + bool (*fn)(const t_buffer_str *), t_usize starting_index, + t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_buf_str_all(t_vec_buf_str *vec, bool (*fn)(const t_buffer_str *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_buf_str_any(t_vec_buf_str *vec, bool (*fn)(const t_buffer_str *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_buf_str_iter(t_vec_buf_str *vec, void (*fn)(t_usize index, + t_buffer_str *value, void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/other/pipex/output/src/vec/vec_process.c b/other/pipex/output/src/vec/vec_process.c new file mode 100644 index 00000000..ed7e552a --- /dev/null +++ b/other/pipex/output/src/vec/vec_process.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_process.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_process.h" +#include + +t_vec_process vec_process_new(t_usize capacity, + t_free_process_item free_function) +{ + t_vec_process out; + + out = (t_vec_process){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_process)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_process_push(t_vec_process *vec, t_process element) +{ + t_process *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_process)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_process)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_process_reserve(t_vec_process *vec, t_usize wanted_capacity) +{ + t_process *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_process)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_process)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_process_pop(t_vec_process *vec, t_process *value) +{ + t_process temp_value; + t_process *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_process)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_process_free(t_vec_process vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/other/pipex/output/src/vec/vec_process_functions2.c b/other/pipex/output/src/vec/vec_process_functions2.c new file mode 100644 index 00000000..9724c0e3 --- /dev/null +++ b/other/pipex/output/src/vec/vec_process_functions2.c @@ -0,0 +1,109 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_process.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_process.h" +#include + +t_error vec_process_find(t_vec_process *vec, bool (*fn)(const t_process *), + t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_process_find_starting(t_vec_process *vec, + bool (*fn)(const t_process *), t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_process_all(t_vec_process *vec, bool (*fn)(const t_process *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_process_any(t_vec_process *vec, bool (*fn)(const t_process *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_process_iter(t_vec_process *vec, void (*fn)(t_usize index, + t_process *value, void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/other/pipex/output/src/vec/vec_str.c b/other/pipex/output/src/vec/vec_str.c new file mode 100644 index 00000000..ccb091b8 --- /dev/null +++ b/other/pipex/output/src/vec/vec_str.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_str.h" +#include + +t_vec_str vec_str_new(t_usize capacity, t_free_str_item free_function) +{ + t_vec_str out; + + out = (t_vec_str){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_str)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_str_push(t_vec_str *vec, t_str element) +{ + t_str *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_str)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_str)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_str_reserve(t_vec_str *vec, t_usize wanted_capacity) +{ + t_str *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_str)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_str)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_str_pop(t_vec_str *vec, t_str *value) +{ + t_str temp_value; + t_str *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_str)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_str_free(t_vec_str vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/other/pipex/output/src/vec/vec_str_functions2.c b/other/pipex/output/src/vec/vec_str_functions2.c new file mode 100644 index 00000000..c7be5033 --- /dev/null +++ b/other/pipex/output/src/vec/vec_str_functions2.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_str.h" +#include + +t_error vec_str_find(t_vec_str *vec, bool (*fn)(const t_str *), t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_str_find_starting(t_vec_str *vec, bool (*fn)(const t_str *), + t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_str_all(t_vec_str *vec, bool (*fn)(const t_str *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_str_any(t_vec_str *vec, bool (*fn)(const t_str *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_str_iter(t_vec_str *vec, void (*fn)(t_usize index, t_str *value, + void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/other/pipex/output/src/vec/vec_u8.c b/other/pipex/output/src/vec/vec_u8.c new file mode 100644 index 00000000..74ff9a0e --- /dev/null +++ b/other/pipex/output/src/vec/vec_u8.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_u8.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_u8.h" +#include + +t_vec_u8 vec_u8_new(t_usize capacity, t_free_u8_item free_function) +{ + t_vec_u8 out; + + out = (t_vec_u8){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_u8)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_u8_push(t_vec_u8 *vec, t_u8 element) +{ + t_u8 *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_u8)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_u8)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_u8_reserve(t_vec_u8 *vec, t_usize wanted_capacity) +{ + t_u8 *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_u8)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_u8)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_u8_pop(t_vec_u8 *vec, t_u8 *value) +{ + t_u8 temp_value; + t_u8 *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_u8)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_u8_free(t_vec_u8 vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/other/pipex/output/src/vec/vec_u8_functions2.c b/other/pipex/output/src/vec/vec_u8_functions2.c new file mode 100644 index 00000000..3358623c --- /dev/null +++ b/other/pipex/output/src/vec/vec_u8_functions2.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_u8.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_u8.h" +#include + +t_error vec_u8_find(t_vec_u8 *vec, bool (*fn)(const t_u8 *), t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_u8_find_starting(t_vec_u8 *vec, bool (*fn)(const t_u8 *), + t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_u8_all(t_vec_u8 *vec, bool (*fn)(const t_u8 *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_u8_any(t_vec_u8 *vec, bool (*fn)(const t_u8 *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_u8_iter(t_vec_u8 *vec, void (*fn)(t_usize index, t_u8 *value, + void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/other/pipex/source_files.list b/other/pipex/source_files.list new file mode 100644 index 00000000..e5bdb2ca --- /dev/null +++ b/other/pipex/source_files.list @@ -0,0 +1,9 @@ +app/main +app/main2 +app/main3 +lib/os/pipe +lib/os/process +lib/os/process_inner +lib/os/process_inner2 +lib/string/inner/split_literals_escaped +lib/string/split_literals diff --git a/other/pipex/src/app/main.c b/other/pipex/src/app/main.c new file mode 100644 index 00000000..6e5428ff --- /dev/null +++ b/other/pipex/src/app/main.c @@ -0,0 +1,119 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/03 15:35:44 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:52:49 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/main.h" + +void cleanup(t_pipex_args *s, bool error) +{ + if (s->here_doc) + close(s->here_doc_fd); + close(s->in); + close(s->out); + vec_str_free(s->env); + vec_process_free(s->processes); + if (error) + exit(1); + wait(NULL); + exit(0); +} + +void process_cleanup(t_process elem) +{ + close(elem.stdin.vals.wo.fd); + close(elem.stdout.vals.ro.fd); + close(elem.stderr.vals.ro.fd); +} + +void do_here_doc_thing(t_pipex_args *s) +{ + t_buffer_str line; + t_isize f; + t_usize len; + bool error; + + len = str_len(s->here_doc_limiter); + error = false; + while (!error) + { + line = get_next_line(0, &error); + if (error) + (me_eprintf("Error:\nError when reading stdin!\n"), cleanup(s, + true)); + f = str_n_compare(line.buf, s->here_doc_limiter, len); + if (f == 0 && line.len >= len + 1 && (line.buf[len] == '\0' + || line.buf[len] == '\n')) + { + str_free(line); + break ; + } + write(s->here_doc_fd, line.buf, line.len); + str_free(line); + } + cleanup(s, false); +} + +int main2(t_pipex_args *s) +{ + t_usize p_idx; + + if (s->argc < 2 || s->argc < s->min || s->argc > s->max) + (me_eprintf("Error:\nWrong number of arguments!\n"), s->here_doc + && close(s->here_doc_fd), close(s->in), vec_str_free(s->env), + exit(1)); + s->processes = vec_process_new(s->argc, process_cleanup); + p_idx = s->argc - 2 - (t_usize)(s->here_doc); + if (spawn_helper(s, p_idx--, piped(), fd(s->out))) + (me_eprintf("Error:\nFailed to spawn process!\n"), cleanup(s, true)); + while (p_idx > 1 + (t_usize)s->here_doc) + { + if (spawn_helper(s, p_idx--, piped(), + fd(s->processes.buffer[s->processes.len - 1].stdin.vals.wo.fd))) + (me_eprintf("Error:\nFailed to spawn process!\n"), cleanup(s, + true)); + } + if (spawn_helper(s, p_idx, fd(s->in), + fd(s->processes.buffer[s->processes.len - 1].stdin.vals.wo.fd))) + (me_eprintf("Error:\nFailed to spawn process!\n"), cleanup(s, true)); + if (s->here_doc) + do_here_doc_thing(s); + cleanup(s, false); + return (0); +} + +int main(int argc, t_str argv[], t_str env[]) +{ + t_usize env_idx; + t_pipex_args s; + + s.min = 4; + s.max = 4; + s.argv = argv + 1; + s.argc = argc - 1; + s.here_doc = false; + if (s.argc < 3) + (me_eprintf("Error:\nNot enough arguments!"), exit(1)); + s.env = vec_str_new(128, (t_free_str_item)free); + env_idx = 0; + while (env[env_idx]) + vec_str_push(&s.env, str_clone(env[env_idx++])); + if (BONUS) + s.max = ~0; + if (BONUS && str_n_compare(s.argv[0], "here_doc", 9) == 0) + set_here_doc(&s); + else + open_read_file(&s); + if ((s.here_doc && me_open_create(s.argv[s.argc - 1], &s.out)) + || (!s.here_doc && me_open_truncate(s.argv[s.argc - 1], &s.out))) + (me_eprintf("Error:\n Failed to open output file!\n"), s.here_doc + && close(s.here_doc_fd), close(s.in), vec_str_free(s.env), exit(1)); + return (s.here_doc && s.argv++, main2(&s)); +} diff --git a/other/pipex/src/app/main2.c b/other/pipex/src/app/main2.c new file mode 100644 index 00000000..13b2e847 --- /dev/null +++ b/other/pipex/src/app/main2.c @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/06 18:46:52 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:55:12 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/main.h" + +void set_here_doc(t_pipex_args *s) +{ + t_pipe pipe; + + if (create_pipe(&pipe)) + (vec_str_free(s->env), exit(1)); + s->min = 5; + s->here_doc = true; + s->here_doc_limiter = s->argv[1]; + s->here_doc_fd = pipe.write; + s->in = pipe.read; +} + +void open_read_file(t_pipex_args *s) +{ + if (me_open(s->argv[0], true, false, &s->in)) + (me_eprintf("Error:\nInput file not found!\n"), vec_str_free(s->env), + exit(1)); +} + +void clone_vec_str_iter_fn(t_usize idx, t_str *s, void *out) +{ + vec_str_push(out, str_clone(*s)); +} + +t_vec_str clone_vec_str(t_vec_str *v) +{ + t_vec_str val; + + val = vec_str_new(v->len + 2, (t_free_str_item)free); + vec_str_iter(v, &clone_vec_str_iter_fn, &val); + return (val); +} diff --git a/other/pipex/src/app/main3.c b/other/pipex/src/app/main3.c new file mode 100644 index 00000000..6184281d --- /dev/null +++ b/other/pipex/src/app/main3.c @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main3.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/06 18:48:21 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:55:33 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/main.h" + +void vec_process_free_ptr(void *s) +{ + close(((t_pipex_args *)s)->in); + close(((t_pipex_args *)s)->out); + if (((t_pipex_args *)s)->here_doc) + close(((t_pipex_args *)s)->here_doc_fd); + vec_process_free(((t_pipex_args *)s)->processes); +} + +t_error spawn_helper(t_pipex_args *s, t_usize idx, t_redirection in, + t_redirection out) +{ + t_process o; + t_vec_str args; + t_spawn_info info; + + if (split_literals(s->argv[idx], &args)) + return (ERROR); + info = (t_spawn_info){ + .stdin = in, + .stdout = out, + .stderr = inherited(), + .binary_path = str_clone(args.buffer[0]), + .arguments = args, + .environement = clone_vec_str(&s->env), + .forked_free = vec_process_free_ptr, + .forked_free_args = s, + }; + if (spawn_process( + info, + &o)) + return (ERROR); + return (vec_process_push(&s->processes, o)); +} diff --git a/other/pipex/src/lib/os/pipe.c b/other/pipex/src/lib/os/pipe.c new file mode 100644 index 00000000..c046fdf7 --- /dev/null +++ b/other/pipex/src/lib/os/pipe.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pipe.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 17:59:48 by maiboyer #+# #+# */ +/* Updated: 2024/01/04 18:01:42 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/os/pipe.h" + +t_error create_pipe(t_pipe *out) +{ + t_file fds[2]; + + if (pipe(fds)) + return (ERROR); + out->read = fds[0]; + out->write = fds[1]; + return (NO_ERROR); +} diff --git a/other/pipex/src/lib/os/process.c b/other/pipex/src/lib/os/process.c new file mode 100644 index 00000000..55e0d394 --- /dev/null +++ b/other/pipex/src/lib/os/process.c @@ -0,0 +1,141 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/03 16:22:41 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 17:50:47 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/buffered_str/buf_str.h" +#include "me/os/pipe.h" +#include "me/os/process.h" +#include "me/string/str_find_chr.h" +#include "me/string/str_n_compare.h" +#include "me/string/str_split.h" +#include "me/types.h" +#include "me/vec/vec_str.h" +#include +#include +#include + +bool find_path(const t_str *s); +bool find_null(const t_str *s); +bool str_start_with(t_const_str s, t_const_str prefix); +t_error handle_redirections(t_spawn_info *info, t_process *process); + +t_error spawn_process_exec(t_spawn_info info, t_process *process) +{ + bool res; + + if (info.forked_free) + info.forked_free(info.forked_free_args); + dup2(info.stdin.vals.fd.value, 0); + dup2(info.stdout.vals.fd.value, 1); + dup2(info.stderr.vals.fd.value, 2); + close(process->stdin.vals.ro.fd); + close(process->stdout.vals.ro.fd); + close(process->stderr.vals.ro.fd); + close(info.stdin.vals.fd.value); + close(info.stdout.vals.fd.value); + close(info.stderr.vals.fd.value); + if (!vec_str_any(&info.arguments, find_null, &res) && res) + vec_str_push(&info.arguments, NULL); + res = false; + if (!vec_str_any(&info.environement, find_null, &res) && res) + vec_str_push(&info.environement, NULL); + execve(info.binary_path, info.arguments.buffer, info.environement.buffer); + return (NO_ERROR); +} + +t_error in_path(t_spawn_info *info, t_process *process, t_const_str path, + t_buffer_str *s) +{ + t_str *splitted_path; + t_usize sp_index; + + splitted_path = str_split(path + 5, ':'); + if (splitted_path == NULL) + return (str_free(*s), ERROR); + sp_index = 0; + while (splitted_path[sp_index]) + { + ((void)(process), str_clear(s)); + push_str_buffer(s, splitted_path[sp_index]); + push_str_buffer(s, "/"); + push_str_buffer(s, info->binary_path); + sp_index++; + if (access(s->buf, X_OK | R_OK) == 0) + break ; + } + sp_index = 0; + while (splitted_path[sp_index]) + free(splitted_path[sp_index++]); + free(splitted_path); + return (NO_ERROR); +} + +t_error find_binary(t_spawn_info *info, t_process *process) +{ + t_usize p_idx; + t_str *splitted_path; + t_buffer_str s; + + (void)(process); + splitted_path = NULL; + s = alloc_new_buffer(256); + if (str_start_with(info->binary_path, "/") + || str_find_chr(info->binary_path, '/') != NULL) + push_str_buffer(&s, info->binary_path); + else + { + if (vec_str_find(&info->environement, find_path, &p_idx)) + return (str_free(s), ERROR); + if (in_path(info, process, info->environement.buffer[p_idx], &s)) + return (ERROR); + } + if (access(s.buf, X_OK | R_OK) == 0) + { + free(info->binary_path); + info->binary_path = s.buf; + return (NO_ERROR); + } + return (str_free(s), ERROR); +} + +static void cleanup(t_spawn_info info, t_process *process, bool cleanup_process) +{ + if (cleanup_process && process->stdin.tag != INVALID) + close(process->stdin.vals.ro.fd); + if (cleanup_process && process->stdout.tag != INVALID) + close(process->stdout.vals.ro.fd); + if (cleanup_process && process->stderr.tag != INVALID) + close(process->stderr.vals.ro.fd); + close(info.stdin.vals.fd.value); + close(info.stdout.vals.fd.value); + close(info.stderr.vals.fd.value); + vec_str_free(info.arguments); + vec_str_free(info.environement); + free(info.binary_path); +} + +t_error spawn_process(t_spawn_info info, t_process *process) +{ + if (handle_redirections(&info, process)) + return (cleanup(info, process, true), ERROR); + if (find_binary(&info, process)) + return (cleanup(info, process, true), ERROR); + process->pid = fork(); + if (process->pid == 0) + (spawn_process_exec(info, process), exit(1)); + else + { + cleanup(info, process, false); + if (process->pid == -1) + return (printf("pid\n"), ERROR); + } + return (NO_ERROR); +} diff --git a/other/pipex/src/lib/os/process_inner.c b/other/pipex/src/lib/os/process_inner.c new file mode 100644 index 00000000..25fec826 --- /dev/null +++ b/other/pipex/src/lib/os/process_inner.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_inner.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 22:25:44 by maiboyer #+# #+# */ +/* Updated: 2024/01/04 22:26:10 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" + +bool find_null(const t_str *s) +{ + return (s == NULL); +} + +bool str_start_with(t_const_str s, t_const_str prefix) +{ + while (*prefix && *s) + { + if (*prefix++ != *s++) + return (false); + } + return (*prefix == '\0'); +} + +bool find_path(const t_str *s) +{ + return (str_start_with(*s, "PATH=")); +} diff --git a/other/pipex/src/lib/os/process_inner2.c b/other/pipex/src/lib/os/process_inner2.c new file mode 100644 index 00000000..dfaf016d --- /dev/null +++ b/other/pipex/src/lib/os/process_inner2.c @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_inner2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 22:27:00 by maiboyer #+# #+# */ +/* Updated: 2024/01/04 23:01:03 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "me/os/process.h" +#include "me/os/pipe.h" + +void handle_redirections_second(t_spawn_info *info, t_process *process) +{ + (void)(process); + if (info->stdin.tag == R_INHERITED) + { + info->stdin = fd(dup(0)); + process->stdin = ro(dup(0)); + } + if (info->stdout.tag == R_INHERITED) + { + info->stdout = fd(dup(1)); + process->stdout = wo(dup(1)); + } + if (info->stderr.tag == R_INHERITED) + { + info->stderr = fd(dup(2)); + process->stderr = wo(dup(2)); + } +} + +void handle_redirections_fds(t_spawn_info *info, t_process *process) +{ + if (info->stdin.tag == R_FD) + { + info->stdin = fd(dup(info->stdin.vals.fd.value)); + process->stdin = wo(dup(info->stdin.vals.fd.value)); + } + if (info->stdout.tag == R_FD) + { + info->stdout = fd(dup(info->stdout.vals.fd.value)); + process->stdout = ro(dup(info->stdout.vals.fd.value)); + } + if (info->stderr.tag == R_FD) + { + info->stderr = fd(dup(info->stderr.vals.fd.value)); + process->stderr = ro(dup(info->stderr.vals.fd.value)); + } +} + +static inline void redirection_inner(t_spawn_info *info, t_process *process) +{ + process->stderr.tag = INVALID; + process->stdout.tag = INVALID; + process->stdin.tag = INVALID; + handle_redirections_fds(info, process); + handle_redirections_second(info, process); +} + +t_error handle_redirections(t_spawn_info *info, t_process *process) +{ + t_pipe pipe_fd; + + redirection_inner(info, process); + if (info->stdin.tag == R_PIPED) + { + if (create_pipe(&pipe_fd)) + return (ERROR); + process->stdin = wo(pipe_fd.write); + info->stdin = fd(pipe_fd.read); + } + if (info->stdout.tag == R_PIPED) + { + if (create_pipe(&pipe_fd)) + return (ERROR); + process->stdout = ro(pipe_fd.read); + info->stdout = fd(pipe_fd.write); + } + if (info->stderr.tag == R_PIPED) + { + if (create_pipe(&pipe_fd)) + return (ERROR); + process->stderr = ro(pipe_fd.read); + info->stderr = fd(pipe_fd.write); + } + return (NO_ERROR); +} diff --git a/other/pipex/src/lib/string/inner/split_literals_escaped.c b/other/pipex/src/lib/string/inner/split_literals_escaped.c new file mode 100644 index 00000000..fc6c39c0 --- /dev/null +++ b/other/pipex/src/lib/string/inner/split_literals_escaped.c @@ -0,0 +1,118 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* split_literals_escaped.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 14:44:48 by maiboyer #+# #+# */ +/* Updated: 2024/01/05 00:06:48 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/buffered_str/buf_str.h" +#include "me/char/isspace.h" +#include "me/char/tolower.h" +#include "me/string/inner/inner_split_literals.h" +#include "me/string/split_literals.h" +#include "me/vec/vec_str.h" +#include +#include + +static inline char escape_oct(t_const_str s, t_usize *current_index, + bool *did_escape, t_error *error) +{ + char out; + char first; + + first = s[*current_index]; + out = first - '0'; + (*current_index)++; + first = s[(*current_index)]; + if (first >= '0' && first <= '7') + { + out = out * 8 + (first - '0'); + (*current_index)++; + first = s[(*current_index)]; + if (first >= '0' && first <= '7') + { + out = out * 8 + (first - '0'); + (*current_index)++; + first = s[(*current_index)]; + } + } + return (out); +} + +static inline char escape_hex(t_const_str s, t_usize *current_index, + bool *did_escape, t_error *error) +{ + char out; + char first; + + out = 0; + first = me_tolower(s[++(*current_index)]); + if (first >= '0' && first <= '9') + out = first - '0'; + else if (first >= 'a' && first <= 'f') + out = 10 + first - 'a'; + else + { + (*current_index)--; + return ('\0'); + } + first = me_tolower(s[++(*current_index)]); + if (first >= '0' && first <= '9') + out = out * 16 + first - '0'; + else if (first >= 'a' && first <= 'f') + out = out * 16 + 10 + first - 'a'; + return (out); +} + +char unescape_single(char first) +{ + if (first == '\\') + return ('\\'); + if (first == 'a') + return ('\a'); + if (first == 'b') + return ('\b'); + if (first == 't') + return ('\t'); + if (first == 'n') + return ('\n'); + if (first == 'v') + return ('\v'); + if (first == 'f') + return ('\f'); + if (first == 'r') + return ('\r'); + if (first == 'e') + return ('\e'); + if (first == 'E') + return ('\e'); + return ('\0'); +} + +char unescape(t_const_str s, t_usize *current_index, bool *did_escape, + t_error *error) +{ + char first; + char out; + + *did_escape = false; + if (s[(*current_index)] != '\\') + return (s[(*current_index)]); + (*current_index)++; + first = s[(*current_index)]; + *did_escape = true; + if (unescape_single(first)) + return (unescape_single(first)); + if (first >= '0' && first <= '7') + return (escape_oct(s, current_index, did_escape, error)); + if (first == 'x') + return (escape_hex(s, current_index, did_escape, error)); + *did_escape = false; + (*current_index)--; + return ('\\'); +} diff --git a/other/pipex/src/lib/string/split_literals.c b/other/pipex/src/lib/string/split_literals.c new file mode 100644 index 00000000..c2d86405 --- /dev/null +++ b/other/pipex/src/lib/string/split_literals.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* split_literals.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/04 14:28:23 by maiboyer #+# #+# */ +/* Updated: 2024/01/06 18:43:33 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/buffered_str/buf_str.h" +#include "me/char/isspace.h" +#include "me/string/inner/inner_split_literals.h" +#include "me/string/split_literals.h" +#include "me/string/str_clone.h" +#include "me/vec/vec_str.h" +#include +#include + +static inline void flip_and_set_false(bool *flip, bool *false_) +{ + *flip = !(*flip); + *false_ = false; +} + +static inline bool is_word_splitter(char c, t_str prefix) +{ + (void)(prefix); + return (c == ' ' || c == '\n' || c == '\t'); +} + +static inline char set_thingy(t_const_str s, t_usize *idx, bool *esc, + bool *lit_sq) +{ + char c; + bool error; + + if (!lit_sq) + { + (*idx)++; + c = unescape(s, idx, esc, &error); + } + else + { + (*idx)++; + c = s[*idx]; + } + return (c); +} + +static inline void yes(t_const_str s, t_usize *idx, t_buffer_str *temp, + t_usize *len) +{ + t_booleans b; + char c; + + b.lit_sq = false; + b.lit_dq = false; + c = unescape(s, idx, &b.esc, &b.error); + while (c != '\0' && !b.esc && is_word_splitter(c, "\t@")) + c = unescape(s, ((*idx)++, idx), &b.esc, &b.error); + while (c != '\0') + { + if (((!b.lit_sq && !b.lit_dq && !b.esc) && is_word_splitter(c, "."))) + break ; + b.append = true; + if (c == '\'' && !b.esc && !b.lit_dq) + (flip_and_set_false(&b.lit_sq, &b.append), (*len)++); + if (c == '"' && !b.esc && !b.lit_sq) + (flip_and_set_false(&b.lit_dq, &b.append), (*len)++); + if (b.append) + (push_str_char(temp, c), (*len)++); + c = set_thingy(s, idx, &b.esc, &b.lit_sq); + } +} + +t_error split_literals(t_const_str s, t_vec_str *out) +{ + t_usize idx; + t_usize len; + t_buffer_str temp; + + *out = vec_str_new(16, (t_free_str_item)free); + temp = alloc_new_buffer(64); + idx = 0; + while (s[idx]) + { + len = 0; + yes(s, &idx, &temp, &len); + if (len == 0) + continue ; + if (vec_str_push(out, temp.buf)) + return (str_free(temp), vec_str_free(*out), ERROR); + temp = alloc_new_buffer(64); + } + str_free(temp); + return (NO_ERROR); +} diff --git a/other/pipex/subject.txt b/other/pipex/subject.txt new file mode 100644 index 00000000..b83d7478 --- /dev/null +++ b/other/pipex/subject.txt @@ -0,0 +1,225 @@ + Pipex + + + + + Summary: +This project will let you discover in detail a UNIX mechanism that you already know + by using it in your program. + + Version: 3 +Contents +I Foreword 2 + +II Common Instructions 3 + +III Mandatory part 5 + III.1 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 + III.2 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 + +IV Bonus part 7 + +V Submission and peer-evaluation 8 + + + + + 1 +Chapter I + +Foreword + +Cristina: "Go dance salsa somewhere :)" + + + + + 2 +Chapter II + +Common Instructions + + • Your project must be written in C. + + • Your project must be written in accordance with the Norm. If you have bonus + files/functions, they are included in the norm check and you will receive a 0 if there + is a norm error inside. + + • Your functions should not quit unexpectedly (segmentation fault, bus error, double + free, etc) apart from undefined behaviors. If this happens, your project will be + considered non functional and will receive a 0 during the evaluation. + + • All heap allocated memory space must be properly freed when necessary. No leaks + will be tolerated. + + • If the subject requires it, you must submit a Makefile which will compile your + source files to the required output with the flags -Wall, -Wextra and -Werror, use + cc, and your Makefile must not relink. + + • Your Makefile must at least contain the rules $(NAME), all, clean, fclean and + re. + + • To turn in bonuses to your project, you must include a rule bonus to your Makefile, + which will add all the various headers, librairies or functions that are forbidden on + the main part of the project. Bonuses must be in a different file _bonus.{c/h} if + the subject does not specify anything else. Mandatory and bonus part evaluation + is done separately. + + • If your project allows you to use your libft, you must copy its sources and its + associated Makefile in a libft folder with its associated Makefile. Your project’s + Makefile must compile the library by using its Makefile, then compile the project. + + • We encourage you to create test programs for your project even though this work + won’t have to be submitted and won’t be graded. It will give you a chance + to easily test your work and your peers’ work. You will find those tests especially + useful during your defence. Indeed, during defence, you are free to use your tests + and/or the tests of the peer you are evaluating. + + • Submit your work to your assigned git repository. Only the work in the git reposi- + tory will be graded. If Deepthought is assigned to grade your work, it will be done + + + 3 +Pipex + + + after your peer-evaluations. If an error happens in any section of your work during + Deepthought’s grading, the evaluation will stop. + + + + + 4 +Chapter III + +Mandatory part + + Program name pipex + Turn in files Makefile, *.h, *.c + Makefile NAME, all, clean, fclean, re + Arguments file1 cmd1 cmd2 file2 + External functs. + + • open, close, read, write, + malloc, free, perror, + strerror, access, dup, dup2, + execve, exit, fork, pipe, + unlink, wait, waitpid + • ft_printf and any equivalent + YOU coded + + Libft authorized Yes + Description This project is about handling pipes. + + + + Your program will be executed as follows: + + ./pipex file1 cmd1 cmd2 file2 + + + It must take 4 arguments: + + • file1 and file2 are file names. + • cmd1 and cmd2 are shell commands with their parameters. + + + It must behave exactly the same as the shell command below: + + $> < file1 cmd1 | cmd2 > file2 + + + + + 5 +Pipex + + +III.1 Examples + $> ./pipex infile "ls -l" "wc -l" outfile + +Should behave like: < infile ls -l | wc -l > outfile + + + $> ./pipex infile "grep a1" "wc -w" outfile + +Should behave like: < infile grep a1 | wc -w > outfile + + + + +III.2 Requirements +Your project must comply with the following rules: + + • You have to turn in a Makefile which will compile your source files. It must not + relink. + + • You have to handle errors thoroughly. In no way your program should quit unex- + pectedly (segmentation fault, bus error, double free, and so forth). + + • Your program mustn’t have memory leaks. + + • If you have any doubt, handle the errors like the shell command: + < file1 cmd1 | cmd2 > file2 + + + + + 6 +Chapter IV + +Bonus part + +You will get extra points if you: + + • Handle multiple pipes. + + This: + $> ./pipex file1 cmd1 cmd2 cmd3 ... cmdn file2 + + + Should behave like: + < file1 cmd1 | cmd2 | cmd3 ... | cmdn > file2 + + + + + • Support « and » when the first parameter is "here_doc". + + This: + $> ./pipex here_doc LIMITER cmd cmd1 file + + + Should behave like: + cmd << LIMITER | cmd1 >> file + + + + + The bonus part will only be assessed if the mandatory part is + PERFECT. Perfect means the mandatory part has been integrally done + and works without malfunctioning. If you have not passed ALL the + mandatory requirements, your bonus part will not be evaluated at all. + + + + + 7 +Chapter V + +Submission and peer-evaluation + +Turn in your assignment in your Git repository as usual. Only the work inside your +repository will be evaluated during the defense. Don’t hesitate to double check the +names of your files to ensure they are correct. + + + + + file.bfe:VACsSfsWN1cy33ROeASsmsgnY0o0sDMJev7zFHhw + QS8mvM8V5xQQpLc6cDCFXDWTiFzZ2H9skYkiJ/DpQtnM/uZ0 + + + + + 8