This avoids poking into the filter data structure at various points in
the code. We rely on the fact that the number of arguments is fixed
based on the filter type (set in cgit_new_filter) and that the call
sites all know which filter type they're using.
Signed-off-by: John Keeping <john@keeping.me.uk>
struct cgit_filter {
char *cmd;
char **argv;
struct cgit_filter {
char *cmd;
char **argv;
int old_stdout;
int pipe_fh[2];
int pid;
int old_stdout;
int pipe_fh[2];
int pid;
extern int cgit_parse_snapshots_mask(const char *str);
extern int cgit_parse_snapshots_mask(const char *str);
-extern int cgit_open_filter(struct cgit_filter *filter);
+extern int cgit_open_filter(struct cgit_filter *filter, ...);
extern int cgit_close_filter(struct cgit_filter *filter);
extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype);
extern int cgit_close_filter(struct cgit_filter *filter);
extern struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype);
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
-int cgit_open_filter(struct cgit_filter *filter)
+int cgit_open_filter(struct cgit_filter *filter, ...)
+ int i;
+ va_list ap;
+
+ va_start(ap, filter);
+ for (i = 0; i < filter->extra_args; i++)
+ filter->argv[i+1] = va_arg(ap, char *);
+ va_end(ap);
+
filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
"Unable to duplicate STDOUT");
chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
filter->old_stdout = chk_positive(dup(STDOUT_FILENO),
"Unable to duplicate STDOUT");
chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess");
int cgit_close_filter(struct cgit_filter *filter)
{
int cgit_close_filter(struct cgit_filter *filter)
{
chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
"Unable to restore STDOUT");
close(filter->old_stdout);
if (filter->pid < 0)
chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO),
"Unable to restore STDOUT");
close(filter->old_stdout);
if (filter->pid < 0)
waitpid(filter->pid, &exit_status, 0);
if (WIFEXITED(exit_status) && !WEXITSTATUS(exit_status))
waitpid(filter->pid, &exit_status, 0);
if (WIFEXITED(exit_status) && !WEXITSTATUS(exit_status))
die("Subprocess %s exited abnormally", filter->cmd);
die("Subprocess %s exited abnormally", filter->cmd);
+
+done:
+ for (i = 0; i < filter->extra_args; i++)
+ filter->argv[i+1] = NULL;
+ return 0;
+
}
struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
{
struct cgit_filter *f;
int args_size = 0;
}
struct cgit_filter *cgit_new_filter(const char *cmd, filter_type filtertype)
{
struct cgit_filter *f;
int args_size = 0;
if (!cmd || !cmd[0])
return NULL;
if (!cmd || !cmd[0])
return NULL;
+ f = xmalloc(sizeof(struct cgit_filter));
+ memset(f, 0, sizeof(struct cgit_filter));
+
switch (filtertype) {
case SOURCE:
case ABOUT:
switch (filtertype) {
case SOURCE:
case ABOUT:
break;
case COMMIT:
default:
break;
case COMMIT:
default:
-
- f = xmalloc(sizeof(struct cgit_filter));
- memset(f, 0, sizeof(struct cgit_filter));
- args_size = (2 + extra_args) * sizeof(char *);
+ args_size = (2 + f->extra_args) * sizeof(char *);
f->argv = xmalloc(args_size);
memset(f->argv, 0, args_size);
f->argv[0] = f->cmd;
f->argv = xmalloc(args_size);
memset(f->argv, 0, args_size);
f->argv[0] = f->cmd;
{
if (!ctx.cfg.root_readme)
return;
{
if (!ctx.cfg.root_readme)
return;
- if (ctx.cfg.about_filter) {
- ctx.cfg.about_filter->argv[1] = ctx.cfg.root_readme;
- cgit_open_filter(ctx.cfg.about_filter);
- }
+ if (ctx.cfg.about_filter)
+ cgit_open_filter(ctx.cfg.about_filter, ctx.cfg.root_readme);
html_include(ctx.cfg.root_readme);
html_include(ctx.cfg.root_readme);
- if (ctx.cfg.about_filter) {
+ if (ctx.cfg.about_filter)
cgit_close_filter(ctx.cfg.about_filter);
cgit_close_filter(ctx.cfg.about_filter);
- ctx.cfg.about_filter->argv[1] = NULL;
- }
* filesystem, while applying the about-filter.
*/
html("<div id='summary'>");
* filesystem, while applying the about-filter.
*/
html("<div id='summary'>");
- if (ctx.repo->about_filter) {
- ctx.repo->about_filter->argv[1] = filename;
- cgit_open_filter(ctx.repo->about_filter);
- }
+ if (ctx.repo->about_filter)
+ cgit_open_filter(ctx.repo->about_filter, filename);
+
if (ref)
cgit_print_file(filename, ref, 1);
else
html_include(filename);
if (ref)
cgit_print_file(filename, ref, 1);
else
html_include(filename);
- if (ctx.repo->about_filter) {
+
+ if (ctx.repo->about_filter)
cgit_close_filter(ctx.repo->about_filter);
cgit_close_filter(ctx.repo->about_filter);
- ctx.repo->about_filter->argv[1] = NULL;
- }
html("</div>");
if (free_filename)
free(filename);
html("</div>");
if (free_filename)
free(filename);
}
if (ctx.repo->source_filter) {
}
if (ctx.repo->source_filter) {
+ char *filter_arg = xstrdup(name);
html("<td class='lines'><pre><code>");
html("<td class='lines'><pre><code>");
- ctx.repo->source_filter->argv[1] = xstrdup(name);
- cgit_open_filter(ctx.repo->source_filter);
+ cgit_open_filter(ctx.repo->source_filter, filter_arg);
html_raw(buf, size);
cgit_close_filter(ctx.repo->source_filter);
html_raw(buf, size);
cgit_close_filter(ctx.repo->source_filter);
- free(ctx.repo->source_filter->argv[1]);
- ctx.repo->source_filter->argv[1] = NULL;
html("</code></pre></td></tr></table>\n");
return;
}
html("</code></pre></td></tr></table>\n");
return;
}