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@xxxxxxxxx +1 650 804 5991 cell
From 1df9e443ce11365f955b83e70365670ff9ada8d6 Mon Sep 17 00:00:00 2001 From: Dana How <how@xxxxxxxxxxxxxxxxxxxxxxx> 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