]> gitweb.ps.run Git - ps-cgit/blob - filter.c
ui-snapshot: set unused cgit_filter fields to zero
[ps-cgit] / filter.c
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
16 int 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
37 int 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
52 struct 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 }