Use the asyncronous function infrastructure to run the content filter.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Johannes Sixt 2007-10-19 21:48:06 +02:00 committed by Shawn O. Pearce
parent 7683b6e81f
commit 546bb58232

View File

@ -192,15 +192,21 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
return 1; return 1;
} }
static int filter_buffer(int fd, const char *src, struct filter_params {
unsigned long size, const char *cmd) const char *src;
unsigned long size;
const char *cmd;
};
static int filter_buffer(int fd, void *data)
{ {
/* /*
* Spawn cmd and feed the buffer contents through its stdin. * Spawn cmd and feed the buffer contents through its stdin.
*/ */
struct child_process child_process; struct child_process child_process;
struct filter_params *params = (struct filter_params *)data;
int write_err, status; int write_err, status;
const char *argv[] = { "sh", "-c", cmd, NULL }; const char *argv[] = { "sh", "-c", params->cmd, NULL };
memset(&child_process, 0, sizeof(child_process)); memset(&child_process, 0, sizeof(child_process));
child_process.argv = argv; child_process.argv = argv;
@ -208,17 +214,17 @@ static int filter_buffer(int fd, const char *src,
child_process.out = fd; child_process.out = fd;
if (start_command(&child_process)) if (start_command(&child_process))
return error("cannot fork to run external filter %s", cmd); return error("cannot fork to run external filter %s", params->cmd);
write_err = (write_in_full(child_process.in, src, size) < 0); write_err = (write_in_full(child_process.in, params->src, params->size) < 0);
if (close(child_process.in)) if (close(child_process.in))
write_err = 1; write_err = 1;
if (write_err) if (write_err)
error("cannot feed the input to external filter %s", cmd); error("cannot feed the input to external filter %s", params->cmd);
status = finish_command(&child_process); status = finish_command(&child_process);
if (status) if (status)
error("external filter %s failed %d", cmd, -status); error("external filter %s failed %d", params->cmd, -status);
return (write_err || status); return (write_err || status);
} }
@ -231,47 +237,36 @@ static int apply_filter(const char *path, const char *src, size_t len,
* *
* (child --> cmd) --> us * (child --> cmd) --> us
*/ */
int pipe_feed[2]; int ret = 1;
int status, ret = 1;
struct child_process child_process;
struct strbuf nbuf; struct strbuf nbuf;
struct async async;
struct filter_params params;
if (!cmd) if (!cmd)
return 0; return 0;
memset(&child_process, 0, sizeof(child_process)); memset(&async, 0, sizeof(async));
async.proc = filter_buffer;
if (pipe(pipe_feed) < 0) { async.data = &params;
error("cannot create pipe to run external filter %s", cmd); params.src = src;
return 0; params.size = len;
} params.cmd = cmd;
fflush(NULL); fflush(NULL);
child_process.pid = fork(); if (start_async(&async))
if (child_process.pid < 0) { return 0; /* error was already reported */
error("cannot fork to run external filter %s", cmd);
close(pipe_feed[0]);
close(pipe_feed[1]);
return 0;
}
if (!child_process.pid) {
close(pipe_feed[0]);
exit(filter_buffer(pipe_feed[1], src, len, cmd));
}
close(pipe_feed[1]);
strbuf_init(&nbuf, 0); strbuf_init(&nbuf, 0);
if (strbuf_read(&nbuf, pipe_feed[0], len) < 0) { if (strbuf_read(&nbuf, async.out, len) < 0) {
error("read from external filter %s failed", cmd); error("read from external filter %s failed", cmd);
ret = 0; ret = 0;
} }
if (close(pipe_feed[0])) { if (close(async.out)) {
error("read from external filter %s failed", cmd); error("read from external filter %s failed", cmd);
ret = 0; ret = 0;
} }
status = finish_command(&child_process); if (finish_async(&async)) {
if (status) { error("external filter %s failed", cmd);
error("external filter %s failed %d", cmd, -status);
ret = 0; ret = 0;
} }