aboutsummaryrefslogtreecommitdiffstats
path: root/filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter.c')
-rw-r--r--filter.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/filter.c b/filter.c
new file mode 100644
index 0000000..f4ee9ac
--- /dev/null
+++ b/filter.c
@@ -0,0 +1,82 @@
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}