|
diff --git a/cgit.c b/cgit.c index 2039ab1..779a464 100644 --- a/ cgit.c+++ b/ cgit.c |
|
@@ -16,8 +16,23 @@ |
16 | #include "scan-tree.h" |
16 | #include "scan-tree.h" |
17 | |
17 | |
18 | const char *cgit_version = CGIT_VERSION; |
18 | const char *cgit_version = CGIT_VERSION; |
19 | |
19 | |
| |
20 | struct cgit_filter *new_filter(const char *cmd, int extra_args) |
| |
21 | { |
| |
22 | struct cgit_filter *f; |
| |
23 | |
| |
24 | if (!cmd) |
| |
25 | return NULL; |
| |
26 | |
| |
27 | f = xmalloc(sizeof(struct cgit_filter)); |
| |
28 | f->cmd = xstrdup(cmd); |
| |
29 | f->argv = xmalloc((2 + extra_args) * sizeof(char *)); |
| |
30 | f->argv[0] = f->cmd; |
| |
31 | f->argv[1] = NULL; |
| |
32 | return f; |
| |
33 | } |
| |
34 | |
20 | void config_cb(const char *name, const char *value) |
35 | void config_cb(const char *name, const char *value) |
21 | { |
36 | { |
22 | if (!strcmp(name, "root-title")) |
37 | if (!strcmp(name, "root-title")) |
23 | ctx.cfg.root_title = xstrdup(value); |
38 | ctx.cfg.root_title = xstrdup(value); |
|
|
diff --git a/cgit.h b/cgit.h index 8c64efe..d0fff1f 100644 --- a/ cgit.h+++ b/ cgit.h |
|
@@ -128,8 +128,17 @@ struct cgit_query { |
128 | char *sort; |
128 | char *sort; |
129 | int showmsg; |
129 | int showmsg; |
130 | }; |
130 | }; |
131 | |
131 | |
| |
132 | struct cgit_filter { |
| |
133 | char *cmd; |
| |
134 | char **argv; |
| |
135 | int old_stdout; |
| |
136 | int pipe_fh[2]; |
| |
137 | int pid; |
| |
138 | int exitstatus; |
| |
139 | }; |
| |
140 | |
132 | struct cgit_config { |
141 | struct cgit_config { |
133 | char *agefile; |
142 | char *agefile; |
134 | char *cache_root; |
143 | char *cache_root; |
135 | char *clone_prefix; |
144 | char *clone_prefix; |
@@ -247,6 +256,9 @@ extern void cgit_parse_url(const char *url); |
247 | extern const char *cgit_repobasename(const char *reponame); |
256 | extern const char *cgit_repobasename(const char *reponame); |
248 | |
257 | |
249 | extern int cgit_parse_snapshots_mask(const char *str); |
258 | extern int cgit_parse_snapshots_mask(const char *str); |
250 | |
259 | |
| |
260 | extern int cgit_open_filter(struct cgit_filter *filter); |
| |
261 | extern int cgit_close_filter(struct cgit_filter *filter); |
| |
262 | |
251 | |
263 | |
252 | #endif /* CGIT_H */ |
264 | #endif /* CGIT_H */ |
|
|
diff --git a/shared.c b/shared.c index cce0af4..288cfa2 100644 --- a/ shared.c+++ b/ shared.c |
|
@@ -354,4 +354,39 @@ int cgit_parse_snapshots_mask(const char *str) |
354 | str += tl; |
354 | str += tl; |
355 | } |
355 | } |
356 | return rv; |
356 | return rv; |
357 | } |
357 | } |
| |
358 | |
| |
359 | int cgit_open_filter(struct cgit_filter *filter) |
| |
360 | { |
| |
361 | |
| |
362 | filter->old_stdout = chk_positive(dup(STDOUT_FILENO), |
| |
363 | "Unable to duplicate STDOUT"); |
| |
364 | chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); |
| |
365 | filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); |
| |
366 | if (filter->pid == 0) { |
| |
367 | close(filter->pipe_fh[1]); |
| |
368 | chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), |
| |
369 | "Unable to use pipe as STDIN"); |
| |
370 | execvp(filter->cmd, filter->argv); |
| |
371 | die("Unable to exec subprocess %s: %s (%d)", filter->cmd, |
| |
372 | strerror(errno), errno); |
| |
373 | } |
| |
374 | close(filter->pipe_fh[0]); |
| |
375 | chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), |
| |
376 | "Unable to use pipe as STDOUT"); |
| |
377 | close(filter->pipe_fh[1]); |
| |
378 | return 0; |
| |
379 | } |
| |
380 | |
| |
381 | int cgit_close_filter(struct cgit_filter *filter) |
| |
382 | { |
| |
383 | chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), |
| |
384 | "Unable to restore STDOUT"); |
| |
385 | close(filter->old_stdout); |
| |
386 | if (filter->pid < 0) |
| |
387 | return 0; |
| |
388 | waitpid(filter->pid, &filter->exitstatus, 0); |
| |
389 | if (WIFEXITED(filter->exitstatus) && !WEXITSTATUS(filter->exitstatus)) |
| |
390 | return 0; |
| |
391 | die("Subprocess %s exited abnormally", filter->cmd); |
| |
392 | } |
|