repeat.git


repeat

~ repeat a command n times
git clone https://github.com/djnnvx/repeat.git
log | files | refs | archive | README

commit 9bc3f75e2842ed758a9cb877745a0e74c227407b
parent 30e3423700a35701527a6b68eaa5be8cbcf28933
Author: djnn <[email protected]>
Date: Tue, 16 Sep 2025 21:53:04 +0900

feat: improving shell handling a little bit we make this a little bit more usable by simply passing along &args[2] and not wrap in a `sh -c "command"`. This means that we don't get the nice benefits of bash / other shell built-ins, but that's life. That's not really what I need right now, to be honest.

Diffstat:
MMakefile | 35++++++-----------------------------
MREADME.md | 5++---
Mincludes/repeat.h | 6+++---
Msources/lib.c | 27++++++++++-----------------
Msources/main.c | 26++++++++++----------------

5 files changed, 31 insertions(+), 68 deletions(-)

diff --git a/Makefile b/Makefile
@@ -7,14 +7,9 @@ INCLUDES 	 	= -I./includes/
 LINK_FLAG    	=
 
 CFLAGS 			= -Wno-unused-command-line-argument -fPIC
-ifeq ($(MAKECMDGOALS), debug)
-	CFLAGS 			+= -g3 -DDEBUG -Wno-format-security -Wno-visibility -DCLIENTID=DEBUG -Wno-unsafe-buffer-usage
-	CFLAGS 			+= -Wno-unused-macros
-else
-	CFLAGS 		 	+= -Wall -Wextra -Os -Weverything -Wpedantic -Wl,-s -static -Wno-visibility
-	CFLAGS 			+= -flto -m64 -fvisibility=hidden -fvisibility-inlines-hidden -s -Wno-unsafe-buffer-usage
-	CFLAGS 			+= -Wno-padded -Wno-gnu-zero-variadic-macro-arguments -Wno-declaration-after-statement
-endif
+CFLAGS 			+= -g3 -DDEBUG -Wno-format-security -Wno-visibility -DCLIENTID=DEBUG -Wno-unsafe-buffer-usage
+CFLAGS 			+= -Wno-unused-macros
+
 
 
 PATTERN 	 	= .c
@@ -33,13 +28,12 @@ OBJ 	 		= $(patsubst %$(PATTERN), $(OBJECT_DIR)/%$(OBJPATTERN), $(COMBINED))
 
 
 .PHONY: all
-all: directories $(NAME) ## generate PROD binary (you might have to run make fclean before)
-	@strip -s $(NAME)
-	@echo "   [*** BINARY STRIP DONE ***]"
+all: directories $(NAME) ## compile binary
+	@echo "   [*** DONE ***]"
 
 .PHONY: help
 help:
-	@echo "\033[34mtargets:\033[0m"
+	@echo "\033[34mtargets for repeat:\033[0m"
 	@perl -nle'print $& if m{^[a-zA-Z_-\d]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-22s\033[0m %s\n", $$1, $$2}'
 
 .PHONY: install
@@ -47,11 +41,6 @@ install: all ## builds and moves binary to /usr/bin/. (might have to run as root
 	@mv $(NAME) /usr/bin/$(NAME)
 
 
-.PHONY: debug
-debug: directories $(NAME) ## generate DEBUG binary (you might have to run make fclean before)
-	@echo "[ ** DEBUG BINARY COMPILED WITH $(CFLAGS) **]"
-
-
 $(OBJECT_DIR):
 	@mkdir -pv $@
 
@@ -69,16 +58,4 @@ $(NAME): $(OBJ)
 clean:  ## removes object files
 	@$(RM) objects
 
-.PHONY: fclean
-fclean: clean  ## removes all compilation artifacts
-	@$(RM) $(NAME) mazepa_*
-	@echo "[*** CLEAN ***]"
-
-.PHONY: gen-compile-commands
-gen-compile-commands: clean ## generate compile_commands.json
-	@bear -- make debug
-
-.PHONY: re  ## cleans everything and rebuild PROD binary
-re: fclean all
-
 
diff --git a/README.md b/README.md
@@ -4,6 +4,7 @@ This is an uber-simple command-line tool to repeat a function n times.
 
 It very much sucks in its current version, don't actually use this for serious work.
 The path, shell, ENV handling is almost non-existent. There is no way to specify if you want your commands to continue even if one fails.
+You also can't use bash-specific built-ins like `echo`.
 
 All it does is execute one function n times. if it fails, it stops. i just needed this for a random script, but why not share it for those
 who need it.
@@ -22,7 +23,5 @@ $ make install
 ## Usage
 
 ```bash
-$ repeat 5 'echo "gimme gimme gimme !"'
+$ repeat 5 printf "hello\n"
 ```
-
-> yes, you need to wrap your command in single-quotes. Yes, it's fucking stupid. But it's what I need.
diff --git a/includes/repeat.h b/includes/repeat.h
@@ -3,7 +3,7 @@
 /*
     djnn.sh ~ repeat
 
-    version 0.1.0
+    version 0.1.1
 
 
     this is an uber-simple CLI function to repeat a command n times.
@@ -11,7 +11,7 @@
 
     Example:
 
-        repeat 5 'echo "gimme gimme gimme !"'
+        repeat 5 printf "hello\n"
 
 */
 
@@ -26,6 +26,6 @@
 
 /* lib.c */
 int parse_positive_int(char const *);
-int execute_command(char *);
+int execute_command(char **);
 
 #endif /* REPEAT_H */
diff --git a/sources/lib.c b/sources/lib.c
@@ -12,28 +12,21 @@ int parse_positive_int(char const *s) {
     return (n > 0) ? n : -1;
 }
 
-int execute_command(char *cmd_args) {
-    int status;
+int execute_command(char **cmd_argv) {
     pid_t pid = fork();
-
     if (pid == -1) {
         perror("repeat: fork failed");
         return -1;
     } else if (pid == 0) {
-        char *sh_path = "/bin/sh";
-        char *sh_args[] = {sh_path, "-c", cmd_args, NULL};
-
-        execve(sh_path, sh_args, NULL);
-        perror("repeat: execve failed");
+        execvp(cmd_argv[0], cmd_argv);
+        perror("repeat: execvp failed");
         _exit(127);
-    } else {
-        waitpid(pid, &status, 0);
-
-        if (WIFEXITED(status)) {
-            return WEXITSTATUS(status);
-        } else if (WIFSIGNALED(status)) {
-            return 128 + WTERMSIG(status);
-        }
     }
-    return -1; /* Should not be reached */
+    int status;
+    waitpid(pid, &status, 0);
+    if (WIFEXITED(status))
+        return WEXITSTATUS(status);
+    if (WIFSIGNALED(status))
+        return 128 + WTERMSIG(status);
+    return -1; /* should never be reached */
 }
diff --git a/sources/main.c b/sources/main.c
@@ -2,25 +2,19 @@
 #include "repeat.h"
 
 int main(int ac, char **av) {
-    int exit_status = 0;
-
-    if (ac != 3) {
-        perror("repeat: expects 3 arguments");
-        perror("Usage: repeat <number> <command>");
-        exit(1);
+    if (ac < 3) {
+        fprintf(stderr, "Usage: repeat <number> <command> [args...]\n");
+        return 1;
     }
-
-    const int nb_executions = parse_positive_int(av[1]);
+    int nb_executions = parse_positive_int(av[1]);
     if (nb_executions < 1) {
-        perror("repeat: expects first argument to be a positive number");
-        exit(1);
+        fprintf(stderr, "First argument must be a positive number\n");
+        return 1;
     }
-
     for (int i = 0; i < nb_executions; ++i) {
-        exit_status = execute_command(av[2]);
-        if (exit_status != 0) {
-            return exit_status;
-        }
+        int status = execute_command(&av[2]);
+        if (status != 0)
+            return status;
     }
-    return exit_status;
+    return 0;
 }