add struct sha1posn, sha1mark(), sha1undo() to csum-file.[ch]
---
csum-file.c | 38 ++++++++++++++++++++++++++++++++++++++
csum-file.h | 6 ++++++
2 files changed, 44 insertions(+), 0 deletions(-)
--
Dana L. How danahow@gmail.com +1 650 804 5991 cell
From 1df9e443ce11365f955b83e70365670ff9ada8d6 Mon Sep 17 00:00:00 2001
From: Dana How <how@deathvalley.cswitch.com>
Date: Thu, 5 Apr 2007 13:13:42 -0700
Subject: [PATCH 04/13] support rollback on writes to checksummed files
add struct sha1posn, sha1mark(), sha1undo() to csum-file.[ch]
---
csum-file.c | 38 ++++++++++++++++++++++++++++++++++++++
csum-file.h | 6 ++++++
2 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/csum-file.c b/csum-file.c
index e1ff769..e2bef75 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -72,6 +72,44 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
return 0;
}
+/*
+ * Save current position/state in output file
+ * (needs to be fast -- no system calls!)
+ */
+void sha1mark(struct sha1file *f, struct sha1posn *p)
+{
+ p->offset = f->offset;
+ p->ctx = f->ctx; /* larger than I'd like */
+}
+
+/*
+ * Restore previous position/state in output file
+ * (can be slow)
+ */
+void sha1undo(struct sha1file *f, struct sha1posn *p, long new, long old)
+{
+ if (new - old == (long)f->offset - (long)p->offset) {
+ f->ctx = p->ctx;
+ f->offset = p->offset;
+ return;
+ }
+ if (lseek(f->fd, (off_t)old - (off_t)p->offset, SEEK_SET) == (off_t)-1)
+ die("sha1 file '%s' undo seekback error (%s)", f->name, strerror(errno));
+ f->ctx = p->ctx;
+ while (p->offset) {
+ int ret = xread(f->fd, f->buffer, p->offset);
+ if (!ret)
+ die("sha1 file '%s' undo readback error. No data", f->name);
+ if (ret < 0)
+ die("sha1 file '%s' undo readback error (%s)", f->name, strerror(errno));
+ SHA1_Update(&f->ctx, f->buffer, ret);
+ p->offset -= ret;
+ }
+ if (ftruncate(f->fd, (off_t)old))
+ die("sha1 file '%s' undo truncate error (%s)", f->name, strerror(errno));
+ f->offset = 0;
+}
+
struct sha1file *sha1create(const char *fmt, ...)
{
struct sha1file *f;
diff --git a/csum-file.h b/csum-file.h
index 3ad1a99..780df17 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -9,11 +9,17 @@ struct sha1file {
char name[PATH_MAX];
unsigned char buffer[8192];
};
+struct sha1posn {
+ unsigned int offset;
+ SHA_CTX ctx;
+};
extern struct sha1file *sha1fd(int fd, const char *name);
extern struct sha1file *sha1create(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern int sha1close(struct sha1file *, unsigned char *, int);
extern int sha1write(struct sha1file *, void *, unsigned int);
extern int sha1write_compressed(struct sha1file *, void *, unsigned int);
+extern void sha1mark(struct sha1file *, struct sha1posn *);
+extern void sha1undo(struct sha1file *, struct sha1posn *, long, long);
#endif
--
1.5.1.rc2.18.g9c88-dirty