all repos — cgit @ da218fcd9eb554a8405ca72e84bcc0feb371194f

a hyperfast web frontend for git written in c

filter.c (view raw)

 1/* filter.c: filter framework functions
 2 *
 3 * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
 4 *
 5 * Licensed under GNU General Public License v2
 6 *   (see COPYING for full license text)
 7 */
 8
 9#include "cgit.h"
10#include <sys/types.h>
11#include <sys/wait.h>
12#include <unistd.h>
13#include <string.h>
14#include <stdlib.h>
15
16int cgit_open_filter(struct cgit_filter *filter)
17{
18	filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
19		"Unable to duplicate STDOUT");
20	chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
21	filter->pid = chk_non_negative(fork(), "Unable to create subprocess");
22	if (filter->pid == 0) {
23		close(filter->pipe_fh[1]);
24		chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO),
25			"Unable to use pipe as STDIN");
26		execvp(filter->cmd, filter->argv);
27		die_errno("Unable to exec subprocess %s", filter->cmd);
28	}
29	close(filter->pipe_fh[0]);
30	chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO),
31		"Unable to use pipe as STDOUT");
32	close(filter->pipe_fh[1]);
33	return 0;
34}
35
36
37int cgit_close_filter(struct cgit_filter *filter)
38{
39	int exit_status;
40
41	chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
42		"Unable to restore STDOUT");
43	close(filter->old_stdout);
44	if (filter->pid < 0)
45		return 0;
46	waitpid(filter->pid, &exit_status, 0);
47	if (WIFEXITED(exit_status) && !WEXITSTATUS(exit_status))
48		return 0;
49	die("Subprocess %s exited abnormally", filter->cmd);
50}
51
52struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
53{
54	struct cgit_filter *f;
55	int args_size = 0;
56	int extra_args;
57
58	if (!cmd || !cmd[0])
59		return NULL;
60
61	switch (filtertype) {
62		case SOURCE:
63		case ABOUT:
64			extra_args = 1;
65			break;
66
67		case COMMIT:
68		default:
69			extra_args = 0;
70			break;
71	}
72	
73	f = xmalloc(sizeof(struct cgit_filter));
74	memset(f, 0, sizeof(struct cgit_filter));
75
76	f->cmd = xstrdup(cmd);
77	args_size = (2 + extra_args) * sizeof(char *);
78	f->argv = xmalloc(args_size);
79	memset(f->argv, 0, args_size);
80	f->argv[0] = f->cmd;
81	return f;
82}