Update all functions that are going to be moved into a reusable module so that they only work with the reusable data structures. Move code that is specific to the filter out into the filter specific functions. Signed-off-by: Ben Peart <benpeart@xxxxxxxxxxxxx> --- convert.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/convert.c b/convert.c index f569026511..747c0c363b 100644 --- a/convert.c +++ b/convert.c @@ -576,14 +576,15 @@ static void stop_multi_file_filter(struct child_process *process) finish_command(process); } -static int start_multi_file_filter_fn(struct cmd2process *entry) +static int start_multi_file_filter_fn(struct subprocess_entry *subprocess) { int err; + struct cmd2process *entry = (struct cmd2process *)subprocess; struct string_list cap_list = STRING_LIST_INIT_NODUP; char *cap_buf; const char *cap_name; - struct child_process *process = &entry->subprocess.process; - const char *cmd = entry->subprocess.cmd; + struct child_process *process = &subprocess->process; + const char *cmd = subprocess->cmd; sigchain_push(SIGPIPE, SIG_IGN); @@ -638,17 +639,21 @@ static int start_multi_file_filter_fn(struct cmd2process *entry) return err; } -static struct cmd2process *start_multi_file_filter(const char *cmd) +typedef int(*subprocess_start_fn)(struct subprocess_entry *entry); +int start_multi_file_filter(struct subprocess_entry *entry, const char *cmd, + subprocess_start_fn startfn) { int err; - struct cmd2process *entry; struct child_process *process; const char *argv[] = { cmd, NULL }; - entry = xmalloc(sizeof(*entry)); - entry->subprocess.cmd = cmd; - entry->supported_capabilities = 0; - process = &entry->subprocess.process; + if (!cmd_process_map_initialized) { + cmd_process_map_initialized = 1; + hashmap_init(&cmd_process_map, (hashmap_cmp_fn)cmd2process_cmp, 0); + } + + entry->cmd = cmd; + process = &entry->process; child_process_init(process); process->argv = argv; @@ -658,22 +663,23 @@ static struct cmd2process *start_multi_file_filter(const char *cmd) process->clean_on_exit = 1; process->clean_on_exit_handler = stop_multi_file_filter; - if (start_command(process)) { + err = start_command(process); + if (err) { error("cannot fork to run external filter '%s'", cmd); - return NULL; + return err; } hashmap_entry_init(entry, strhash(cmd)); - err = start_multi_file_filter_fn(entry); + err = startfn(entry); if (err) { error("initialization for external filter '%s' failed", cmd); - kill_multi_file_filter(&entry->subprocess); - return NULL; + kill_multi_file_filter(entry); + return err; } hashmap_add(&cmd_process_map, entry); - return entry; + return 0; } static int apply_multi_file_filter(const char *path, const char *src, size_t len, @@ -692,9 +698,13 @@ static int apply_multi_file_filter(const char *path, const char *src, size_t len fflush(NULL); if (!entry) { - entry = start_multi_file_filter(cmd); - if (!entry) + entry = xmalloc(sizeof(*entry)); + entry->supported_capabilities = 0; + + if (start_multi_file_filter(&entry->subprocess, cmd, start_multi_file_filter_fn)) { + free(entry); return 0; + } } process = &entry->subprocess.process; @@ -767,7 +777,7 @@ static int apply_multi_file_filter(const char *path, const char *src, size_t len * Force shutdown and restart if another blob requires filtering. */ error("external filter '%s' failed", cmd); - kill_multi_file_filter(&entry->subprocess); + kill_multi_file_filter((struct subprocess_entry *)entry); } } else { strbuf_swap(dst, &nbuf); -- 2.12.1.gvfs.1.18.ge47db72