shared.c: use execvp() to execute filter commands
This reintroduces the use of execvp(), since the filter commands doesn't always contain an absolute path (i.e. snapshot compression filters). Signed-off-by: Lars Hjemli <hjemli@gmail.com>
This commit is contained in:
		
							
								
								
									
										66
									
								
								shared.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								shared.c
									
									
									
									
									
								
							| @@ -383,7 +383,7 @@ typedef struct { | ||||
| 	char * value; | ||||
| } cgit_env_var; | ||||
|  | ||||
| static char * prepare_env(struct cgit_repo * repo) { | ||||
| static void prepare_env(struct cgit_repo * repo) { | ||||
| 	cgit_env_var env_vars[] = { | ||||
| 		{ .name = "CGIT_REPO_URL", .value = repo->url }, | ||||
| 		{ .name = "CGIT_REPO_NAME", .value = repo->name }, | ||||
| @@ -394,52 +394,14 @@ static char * prepare_env(struct cgit_repo * repo) { | ||||
| 		{ .name = "CGIT_REPO_CLONE_URL", .value = repo->clone_url } | ||||
| 	}; | ||||
| 	int env_var_count = ARRAY_SIZE(env_vars); | ||||
| 	long values_space = (env_var_count * (PATH_MAX + 64)); | ||||
| 	cgit_env_var *p, *q; | ||||
| 	static char *warn = "cgit warning: failed to set env: %s=%s\n"; | ||||
|  | ||||
| 	void * buffer; | ||||
| 	char ** vars; | ||||
| 	char * values; | ||||
| 	int vars_index = 0; | ||||
| 	unsigned int chars_printed; | ||||
|  | ||||
| 	/* Allocate buffer for environment variables: first in the buffer is an | ||||
| 	 * array of pointers to argument strings, terminated with a NULL pointer. | ||||
| 	 * After that the argument strings are placed after each other */ | ||||
| 	buffer = malloc(((env_var_count + 1) * sizeof(char *)) + values_space); | ||||
| 	if (!buffer) | ||||
| 		return NULL; | ||||
|  | ||||
| 	vars = buffer; | ||||
| 	values = (char *) &vars[env_var_count + 1]; | ||||
|  | ||||
| 	/* loop over all defined environment variables and their values */ | ||||
| 	while (vars_index < env_var_count) { | ||||
| 		char * name = env_vars[vars_index].name; | ||||
| 		char * value = env_vars[vars_index].value; | ||||
|  | ||||
| 		if (!value) | ||||
| 			value = ""; | ||||
|  | ||||
| 		chars_printed = snprintf(values, (values_space - 1), "%s=%s", name, | ||||
| 				value); | ||||
| 		if (chars_printed > (values_space - 1)) { | ||||
| 			/* Buffer space exhausted: stop adding variables. | ||||
| 			 * Not all environment variables are defined, but the best we can | ||||
| 			 * do is to provide the ones that _are_ defined */ | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		values[chars_printed] = '\0'; | ||||
| 		*&vars[vars_index] = values; | ||||
| 		values += (chars_printed + 1); | ||||
| 		values_space -= (chars_printed + 1); | ||||
| 		vars_index++; | ||||
| 	} | ||||
|  | ||||
| 	/* terminate the array with pointers */ | ||||
| 	*&vars[vars_index] = NULL; | ||||
|  | ||||
| 	return (char *) buffer; | ||||
| 	p = env_vars; | ||||
| 	q = p + env_var_count; | ||||
| 	for (; p < q; p++) | ||||
| 		if (setenv(p->name, p->value, 1)) | ||||
| 			fprintf(stderr, warn, p->name, p->value); | ||||
| } | ||||
|  | ||||
| int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) | ||||
| @@ -450,20 +412,12 @@ int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) | ||||
| 	chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); | ||||
| 	filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); | ||||
| 	if (filter->pid == 0) { | ||||
| 		char * env = NULL; | ||||
|  | ||||
| 		close(filter->pipe_fh[1]); | ||||
| 		chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), | ||||
| 			"Unable to use pipe as STDIN"); | ||||
|  | ||||
| 		if (repo) | ||||
| 			env = prepare_env(repo); | ||||
|  | ||||
| 		execve(filter->cmd, filter->argv, (char **)env); | ||||
|  | ||||
| 		if (env) | ||||
| 			free(env); | ||||
|  | ||||
| 			prepare_env(repo); | ||||
| 		execvp(filter->cmd, filter->argv); | ||||
| 		die("Unable to exec subprocess %s: %s (%d)", filter->cmd, | ||||
| 			strerror(errno), errno); | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lars Hjemli
					Lars Hjemli