]>
git.cameronkatri.com Git - cgit.git/blob - filter.c
1 /* filter.c: filter framework functions
3 * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text)
10 #include <sys/types.h>
16 static int open_exec_filter(struct cgit_filter
*base
, va_list ap
)
18 struct cgit_exec_filter
*filter
= (struct cgit_exec_filter
*) base
;
21 for (i
= 0; i
< filter
->extra_args
; i
++)
22 filter
->argv
[i
+1] = va_arg(ap
, char *);
24 filter
->old_stdout
= chk_positive(dup(STDOUT_FILENO
),
25 "Unable to duplicate STDOUT");
26 chk_zero(pipe(filter
->pipe_fh
), "Unable to create pipe to subprocess");
27 filter
->pid
= chk_non_negative(fork(), "Unable to create subprocess");
28 if (filter
->pid
== 0) {
29 close(filter
->pipe_fh
[1]);
30 chk_non_negative(dup2(filter
->pipe_fh
[0], STDIN_FILENO
),
31 "Unable to use pipe as STDIN");
32 execvp(filter
->cmd
, filter
->argv
);
33 die_errno("Unable to exec subprocess %s", filter
->cmd
);
35 close(filter
->pipe_fh
[0]);
36 chk_non_negative(dup2(filter
->pipe_fh
[1], STDOUT_FILENO
),
37 "Unable to use pipe as STDOUT");
38 close(filter
->pipe_fh
[1]);
42 static int close_exec_filter(struct cgit_filter
*base
)
44 struct cgit_exec_filter
*filter
= (struct cgit_exec_filter
*) base
;
47 chk_non_negative(dup2(filter
->old_stdout
, STDOUT_FILENO
),
48 "Unable to restore STDOUT");
49 close(filter
->old_stdout
);
52 waitpid(filter
->pid
, &exit_status
, 0);
53 if (WIFEXITED(exit_status
) && !WEXITSTATUS(exit_status
))
55 die("Subprocess %s exited abnormally", filter
->cmd
);
58 for (i
= 0; i
< filter
->extra_args
; i
++)
59 filter
->argv
[i
+1] = NULL
;
64 static void fprintf_exec_filter(struct cgit_filter
*base
, FILE *f
, const char *prefix
)
66 struct cgit_exec_filter
*filter
= (struct cgit_exec_filter
*) base
;
67 fprintf(f
, "%s%s\n", prefix
, filter
->cmd
);
70 int cgit_open_filter(struct cgit_filter
*filter
, ...)
75 result
= filter
->open(filter
, ap
);
80 int cgit_close_filter(struct cgit_filter
*filter
)
82 return filter
->close(filter
);
85 void cgit_fprintf_filter(struct cgit_filter
*filter
, FILE *f
, const char *prefix
)
87 filter
->fprintf(filter
, f
, prefix
);
90 void cgit_exec_filter_init(struct cgit_exec_filter
*filter
, char *cmd
, char **argv
)
92 memset(filter
, 0, sizeof(*filter
));
93 filter
->base
.open
= open_exec_filter
;
94 filter
->base
.close
= close_exec_filter
;
95 filter
->base
.fprintf
= fprintf_exec_filter
;
100 static struct cgit_filter
*new_exec_filter(const char *cmd
, filter_type filtertype
)
102 struct cgit_exec_filter
*f
;
105 f
= xmalloc(sizeof(*f
));
106 /* We leave argv for now and assign it below. */
107 cgit_exec_filter_init(f
, xstrdup(cmd
), NULL
);
109 switch (filtertype
) {
121 args_size
= (2 + f
->extra_args
) * sizeof(char *);
122 f
->argv
= xmalloc(args_size
);
123 memset(f
->argv
, 0, args_size
);
128 struct cgit_filter
*cgit_new_filter(const char *cmd
, filter_type filtertype
)
133 return new_exec_filter(cmd
, filtertype
);