Add generic filter/plugin infrastructure
The functions cgit_open_filter() and cgit_close_filter() can be used to execute filters on the output stream from cgit. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
This commit is contained in:
		
							
								
								
									
										15
									
								
								cgit.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								cgit.c
									
									
									
									
									
								
							| @@ -17,6 +17,21 @@ | ||||
|  | ||||
| const char *cgit_version = CGIT_VERSION; | ||||
|  | ||||
| struct cgit_filter *new_filter(const char *cmd, int extra_args) | ||||
| { | ||||
| 	struct cgit_filter *f; | ||||
|  | ||||
| 	if (!cmd) | ||||
| 		return NULL; | ||||
|  | ||||
| 	f = xmalloc(sizeof(struct cgit_filter)); | ||||
| 	f->cmd = xstrdup(cmd); | ||||
| 	f->argv = xmalloc((2 + extra_args) * sizeof(char *)); | ||||
| 	f->argv[0] = f->cmd; | ||||
| 	f->argv[1] = NULL; | ||||
| 	return f; | ||||
| } | ||||
|  | ||||
| void config_cb(const char *name, const char *value) | ||||
| { | ||||
| 	if (!strcmp(name, "root-title")) | ||||
|   | ||||
							
								
								
									
										12
									
								
								cgit.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								cgit.h
									
									
									
									
									
								
							| @@ -129,6 +129,15 @@ struct cgit_query { | ||||
| 	int showmsg; | ||||
| }; | ||||
|  | ||||
| struct cgit_filter { | ||||
| 	char *cmd; | ||||
| 	char **argv; | ||||
| 	int old_stdout; | ||||
| 	int pipe_fh[2]; | ||||
| 	int pid; | ||||
| 	int exitstatus; | ||||
| }; | ||||
|  | ||||
| struct cgit_config { | ||||
| 	char *agefile; | ||||
| 	char *cache_root; | ||||
| @@ -248,5 +257,8 @@ extern const char *cgit_repobasename(const char *reponame); | ||||
|  | ||||
| extern int cgit_parse_snapshots_mask(const char *str); | ||||
|  | ||||
| extern int cgit_open_filter(struct cgit_filter *filter); | ||||
| extern int cgit_close_filter(struct cgit_filter *filter); | ||||
|  | ||||
|  | ||||
| #endif /* CGIT_H */ | ||||
|   | ||||
							
								
								
									
										35
									
								
								shared.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								shared.c
									
									
									
									
									
								
							| @@ -355,3 +355,38 @@ int cgit_parse_snapshots_mask(const char *str) | ||||
| 	} | ||||
| 	return rv; | ||||
| } | ||||
|  | ||||
| int cgit_open_filter(struct cgit_filter *filter) | ||||
| { | ||||
|  | ||||
| 	filter->old_stdout = chk_positive(dup(STDOUT_FILENO), | ||||
| 		"Unable to duplicate STDOUT"); | ||||
| 	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) { | ||||
| 		close(filter->pipe_fh[1]); | ||||
| 		chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), | ||||
| 			"Unable to use pipe as STDIN"); | ||||
| 		execvp(filter->cmd, filter->argv); | ||||
| 		die("Unable to exec subprocess %s: %s (%d)", filter->cmd, | ||||
| 			strerror(errno), errno); | ||||
| 	} | ||||
| 	close(filter->pipe_fh[0]); | ||||
| 	chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), | ||||
| 		"Unable to use pipe as STDOUT"); | ||||
| 	close(filter->pipe_fh[1]); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int cgit_close_filter(struct cgit_filter *filter) | ||||
| { | ||||
| 	chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), | ||||
| 		"Unable to restore STDOUT"); | ||||
| 	close(filter->old_stdout); | ||||
| 	if (filter->pid < 0) | ||||
| 		return 0; | ||||
| 	waitpid(filter->pid, &filter->exitstatus, 0); | ||||
| 	if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus)) | ||||
| 		return 0; | ||||
| 	die("Subprocess %s exited abnormally", filter->cmd); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lars Hjemli
					Lars Hjemli