diff options
| author | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2023-10-08 19:26:29 +0200 | 
|---|---|---|
| committer | Tristan Riehs <tristan.riehs@bordeaux-inp.fr> | 2023-10-08 19:26:29 +0200 | 
| commit | 763d49da434c25b62763ebba67ea340a9c143cfe (patch) | |
| tree | 9aabd702421792d02012fe34c19cf86c5199ffb8 | |
| parent | 7f7acbf4ca9f8c25e8d10402d8302bc38d3c854e (diff) | |
better error handling
| -rw-r--r-- | rpt.c | 53 | 
1 files changed, 35 insertions, 18 deletions
| @@ -1,5 +1,6 @@  #define _GNU_SOURCE		/* getopt_long */ +#include <errno.h>  #include <getopt.h>  #include <stdio.h>  #include <stdlib.h> @@ -49,37 +50,53 @@ continue_on_error(int status)  	(void) status;  } +void +exec_child(char **argv) +{ +	int status; + +	status = execvp(argv[0], argv); + +	if (status < 0) +	{ +		perror("rpt[child process]"); +		exit(4); +	} + +	exit(4); +} + +void +wait_child(pid_t pid, void (*handle_error_f)(int status)) +{ +	int exit_status = 0; + +	waitpid(pid, &exit_status, 0); + +	handle_error_f(exit_status); +} +  /* Invoke the executable *ARGV COUNT times, passing it the rest of ARG as     arguments. Call HANDLE_ERROR_F between each process. */  void -repeat_cmd(char **argv, long count, void (*handle_error_f)(int)) +repeat_cmd(char **argv, long count, void (*handle_error_f)(int status))  {  	pid_t pid; -	int status;  	for(long i = 0; i < count; ++i)  	{  		pid = fork(); -		if (pid == 0) +		if (pid < 0)  		{ -			/* child */ -			status = execvp(argv[0], argv); - -			if (status < 0) -				exit(1); - -			exit(2); +			perror("rpt"); +			exit(4);  		} -		else -		{ -			/* parent */ -			int exit_status = 0; - -			waitpid(pid, &exit_status, 0); -			handle_error_f(exit_status); -		} +		if (pid == 0) +			exec_child(argv); +		else +			wait_child(pid, handle_error_f);  	}  } | 
