Have start_command() create a pipe to read the stderr of the child.
[gitweb.git] / convert.c
index 0d5e909c696dac8b900713a992c72cd9cacf94e3..d83c2fcc5e2afb9b9e19d232ce38f7bec91513ce 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -110,7 +110,9 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
                        return 0;
        }
 
-       strbuf_grow(buf, len);
+       /* only grow if not in place */
+       if (strbuf_avail(buf) + buf->len < len)
+               strbuf_grow(buf, len - buf->len);
        dst = buf->buf;
        if (action == CRLF_GUESS) {
                /*
@@ -197,34 +199,18 @@ static int filter_buffer(const char *path, const char *src,
         * Spawn cmd and feed the buffer contents through its stdin.
         */
        struct child_process child_process;
-       int pipe_feed[2];
        int write_err, status;
+       const char *argv[] = { "sh", "-c", cmd, NULL };
 
        memset(&child_process, 0, sizeof(child_process));
+       child_process.argv = argv;
+       child_process.in = -1;
 
-       if (pipe(pipe_feed) < 0) {
-               error("cannot create pipe to run external filter %s", cmd);
-               return 1;
-       }
+       if (start_command(&child_process))
+               return error("cannot fork to run external filter %s", cmd);
 
-       child_process.pid = fork();
-       if (child_process.pid < 0) {
-               error("cannot fork to run external filter %s", cmd);
-               close(pipe_feed[0]);
-               close(pipe_feed[1]);
-               return 1;
-       }
-       if (!child_process.pid) {
-               dup2(pipe_feed[0], 0);
-               close(pipe_feed[0]);
-               close(pipe_feed[1]);
-               execlp("sh", "sh", "-c", cmd, NULL);
-               return 1;
-       }
-       close(pipe_feed[0]);
-
-       write_err = (write_in_full(pipe_feed[1], src, size) < 0);
-       if (close(pipe_feed[1]))
+       write_err = (write_in_full(child_process.in, src, size) < 0);
+       if (close(child_process.in))
                write_err = 1;
        if (write_err)
                error("cannot feed the input to external filter %s", cmd);
@@ -281,20 +267,19 @@ static int apply_filter(const char *path, const char *src, size_t len,
                ret = 0;
        }
        if (close(pipe_feed[0])) {
-               ret = error("read from external filter %s failed", cmd);
+               error("read from external filter %s failed", cmd);
                ret = 0;
        }
        status = finish_command(&child_process);
        if (status) {
-               ret = error("external filter %s failed %d", cmd, -status);
+               error("external filter %s failed %d", cmd, -status);
                ret = 0;
        }
 
        if (ret) {
-               *dst = nbuf;
-       } else {
-               strbuf_release(&nbuf);
+               strbuf_swap(dst, &nbuf);
        }
+       strbuf_release(&nbuf);
        return ret;
 }
 
@@ -422,7 +407,9 @@ static int ident_to_git(const char *path, const char *src, size_t len,
        if (!ident || !count_ident(src, len))
                return 0;
 
-       strbuf_grow(buf, len);
+       /* only grow if not in place */
+       if (strbuf_avail(buf) + buf->len < len)
+               strbuf_grow(buf, len - buf->len);
        dst = buf->buf;
        for (;;) {
                dollar = memchr(src, '$', len);