git-branch -D: make it work even when on a yet-to-be-born branch
[gitweb.git] / csum-file.c
index 9f9553ae035e762d12dc7d885432abd920af6e5b..b7174c6c056c5a8f2a800ecbcb3cdf304c0bfc3f 100644 (file)
 #include "cache.h"
 #include "csum-file.h"
 
-static int sha1flush(struct sha1file *f, unsigned int count)
+static void sha1flush(struct sha1file *f, unsigned int count)
 {
        void *buf = f->buffer;
 
        for (;;) {
-               int ret = write(f->fd, buf, count);
+               int ret = xwrite(f->fd, buf, count);
                if (ret > 0) {
-                       buf += ret;
+                       buf = (char *) buf + ret;
                        count -= ret;
                        if (count)
                                continue;
-                       return 0;
+                       return;
                }
                if (!ret)
                        die("sha1 file '%s' write error. Out of diskspace", f->name);
-               if (errno == EAGAIN || errno == EINTR)
-                       continue;
                die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
        }
 }
@@ -40,11 +38,12 @@ int sha1close(struct sha1file *f, unsigned char *result, int update)
        }
        SHA1_Final(f->buffer, &f->ctx);
        if (result)
-               memcpy(result, f->buffer, 20);
+               hashcpy(result, f->buffer);
        if (update)
                sha1flush(f, 20);
        if (close(f->fd))
                die("%s: sha1 file error on close (%s)", f->name, strerror(errno));
+       free(f);
        return 0;
 }
 
@@ -58,6 +57,7 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
                memcpy(f->buffer + offset, buf, nr);
                count -= nr;
                offset += nr;
+               buf = (char *) buf + nr;
                left -= nr;
                if (!left) {
                        SHA1_Update(&f->ctx, f->buffer, offset);
@@ -85,7 +85,7 @@ struct sha1file *sha1create(const char *fmt, ...)
                die("you wascally wabbit, you");
        f->namelen = len;
 
-       fd = open(f->name, O_CREAT | O_EXCL | O_WRONLY, 0644);
+       fd = open(f->name, O_CREAT | O_EXCL | O_WRONLY, 0666);
        if (fd < 0)
                die("unable to open %s (%s)", f->name, strerror(errno));
        f->fd = fd;
@@ -95,6 +95,26 @@ struct sha1file *sha1create(const char *fmt, ...)
        return f;
 }
 
+struct sha1file *sha1fd(int fd, const char *name)
+{
+       struct sha1file *f;
+       unsigned len;
+
+       f = xmalloc(sizeof(*f));
+
+       len = strlen(name);
+       if (len >= PATH_MAX)
+               die("you wascally wabbit, you");
+       f->namelen = len;
+       memcpy(f->name, name, len+1);
+
+       f->fd = fd;
+       f->error = 0;
+       f->offset = 0;
+       SHA1_Init(&f->ctx);
+       return f;
+}
+
 int sha1write_compressed(struct sha1file *f, void *in, unsigned int size)
 {
        z_stream stream;
@@ -102,7 +122,7 @@ int sha1write_compressed(struct sha1file *f, void *in, unsigned int size)
        void *out;
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, Z_DEFAULT_COMPRESSION);
+       deflateInit(&stream, zlib_compression_level);
        maxsize = deflateBound(&stream, size);
        out = xmalloc(maxsize);