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:
parent
7683b6e81f
commit
546bb58232
61
convert.c
61
convert.c
@ -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 = ¶ms;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user