diff-ni: fix the diff with standard input
authorJunio C Hamano <junkio@cox.net>
Sun, 4 Mar 2007 08:17:27 +0000 (00:17 -0800)
committerJunio C Hamano <junkio@cox.net>
Sun, 4 Mar 2007 08:17:27 +0000 (00:17 -0800)
The earlier commit to read from stdin was full of problems, and
this corrects them.

 - The mode bits should have been set to satisify S_ISREG(); we
   forgot to the S_IFREG bits and hardcoded 0644;
 - We did not give escape hatch to name a path whose name is
   really "-".  Allow users to say "./-" for that;
 - Use of xread() was not prepared to see short read (e.g. reading
   from tty) nor handing read errors.

Signed-off-by: Junio C Hamano <junkio@cox.net>
diff-lib.c
diff.c

index 226f09c72b5d95f90cb5513767b7cd85bb4ac69e..470ad656a8766ff866e76bfde0ea4535743e0d5b 100644 (file)
@@ -38,7 +38,7 @@ static int queue_diff(struct diff_options *o,
 
        if (name1) {
                if (!strcmp(name1, "-"))
-                       mode1 = 0644;
+                       mode1 = ntohl(create_ce_mode(0666));
                else if (stat(name1, &st))
                        return error("Could not access '%s'", name1);
                else
@@ -46,7 +46,7 @@ static int queue_diff(struct diff_options *o,
        }
        if (name2) {
                if (!strcmp(name2, "-"))
-                       mode2 = 0644;
+                       mode2 = ntohl(create_ce_mode(0666));
                else if (stat(name2, &st))
                        return error("Could not access '%s'", name2);
                else
@@ -260,9 +260,15 @@ int setup_diff_no_index(struct rev_info *revs,
 
                revs->diffopt.paths = xcalloc(2, sizeof(char*));
                for (i = 0; i < 2; i++) {
-                       const char *p;
-                       p = prefix_filename(prefix, len, argv[argc - 2 + i]);
-                       revs->diffopt.paths[i] = xstrdup(p);
+                       const char *p = argv[argc - 2 + i];
+                       /*
+                        * stdin should be spelled as '-'; if you have
+                        * path that is '-', spell it as ./-.
+                        */
+                       p = (strcmp(p, "-")
+                            ? xstrdup(prefix_filename(prefix, len, p))
+                            : p);
+                       revs->diffopt.paths[i] = p;
                }
        }
        else
diff --git a/diff.c b/diff.c
index 81be6adca3541cd8785e80f6a8f6db61ad11b272..9e276e5848525920cf145626fbb068eb7ae241d8 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1364,6 +1364,32 @@ static struct sha1_size_cache *locate_size_cache(unsigned char *sha1,
        return e;
 }
 
+static int populate_from_stdin(struct diff_filespec *s)
+{
+#define INCREMENT 1024
+       char *buf;
+       unsigned long size;
+       int got;
+
+       size = 0;
+       buf = NULL;
+       while (1) {
+               buf = xrealloc(buf, size + INCREMENT);
+               got = xread(0, buf + size, INCREMENT);
+               if (!got)
+                       break; /* EOF */
+               if (got < 0)
+                       return error("error while reading from stdin %s",
+                                    strerror(errno));
+               size += got;
+       }
+       s->should_munmap = 0;
+       s->data = buf;
+       s->size = size;
+       s->should_free = 1;
+       return 0;
+}
+
 /*
  * While doing rename detection and pickaxe operation, we may need to
  * grab the data for the blob (or file) for our own in-core comparison.
@@ -1389,22 +1415,9 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
                char *buf;
                unsigned long size;
 
-               if (!strcmp(s->path, "-")) {
-#define INCREMENT 1024
-                       int i = INCREMENT;
-                       size = 0;
-                       buf = NULL;
-                       while (i == INCREMENT) {
-                               buf = xrealloc(buf, size + INCREMENT);
-                               i = xread(0, buf + size, INCREMENT);
-                               size += i;
-                       }
-                       s->should_munmap = 0;
-                       s->data = buf;
-                       s->size = size;
-                       s->should_free = 1;
-                       return 0;
-               }
+               if (!strcmp(s->path, "-"))
+                       return populate_from_stdin(s);
+
                if (lstat(s->path, &st) < 0) {
                        if (errno == ENOENT) {
                        err_empty: