75 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C
		
	
	
| #include "cache.h"
 | |
| #include "run-command.h"
 | |
| #include <sys/wait.h>
 | |
| #include "exec_cmd.h"
 | |
| 
 | |
| int run_command_v_opt(int argc, const char **argv, int flags)
 | |
| {
 | |
| 	pid_t pid = fork();
 | |
| 
 | |
| 	if (pid < 0)
 | |
| 		return -ERR_RUN_COMMAND_FORK;
 | |
| 	if (!pid) {
 | |
| 		if (flags & RUN_COMMAND_NO_STDIO) {
 | |
| 			int fd = open("/dev/null", O_RDWR);
 | |
| 			dup2(fd, 0);
 | |
| 			dup2(fd, 1);
 | |
| 			close(fd);
 | |
| 		}
 | |
| 		if (flags & RUN_GIT_CMD) {
 | |
| 			execv_git_cmd(argv);
 | |
| 		} else {
 | |
| 			execvp(argv[0], (char *const*) argv);
 | |
| 		}
 | |
| 		die("exec %s failed.", argv[0]);
 | |
| 	}
 | |
| 	for (;;) {
 | |
| 		int status, code;
 | |
| 		int retval = waitpid(pid, &status, 0);
 | |
| 
 | |
| 		if (retval < 0) {
 | |
| 			if (errno == EINTR)
 | |
| 				continue;
 | |
| 			error("waitpid failed (%s)", strerror(retval));
 | |
| 			return -ERR_RUN_COMMAND_WAITPID;
 | |
| 		}
 | |
| 		if (retval != pid)
 | |
| 			return -ERR_RUN_COMMAND_WAITPID_WRONG_PID;
 | |
| 		if (WIFSIGNALED(status))
 | |
| 			return -ERR_RUN_COMMAND_WAITPID_SIGNAL;
 | |
| 
 | |
| 		if (!WIFEXITED(status))
 | |
| 			return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
 | |
| 		code = WEXITSTATUS(status);
 | |
| 		if (code)
 | |
| 			return -code;
 | |
| 		return 0;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int run_command_v(int argc, const char **argv)
 | |
| {
 | |
| 	return run_command_v_opt(argc, argv, 0);
 | |
| }
 | |
| 
 | |
| int run_command(const char *cmd, ...)
 | |
| {
 | |
| 	int argc;
 | |
| 	const char *argv[MAX_RUN_COMMAND_ARGS];
 | |
| 	const char *arg;
 | |
| 	va_list param;
 | |
| 
 | |
| 	va_start(param, cmd);
 | |
| 	argv[0] = (char*) cmd;
 | |
| 	argc = 1;
 | |
| 	while (argc < MAX_RUN_COMMAND_ARGS) {
 | |
| 		arg = argv[argc++] = va_arg(param, char *);
 | |
| 		if (!arg)
 | |
| 			break;
 | |
| 	}
 | |
| 	va_end(param);
 | |
| 	if (MAX_RUN_COMMAND_ARGS <= argc)
 | |
| 		return error("too many args to run %s", cmd);
 | |
| 	return run_command_v_opt(argc, argv, 0);
 | |
| }
 |