+ /* Save old contents if we can */
+ if (p->u.write.off != -1) {
+ ssize_t ret;
+ p->u.write.old_filelen = lseek(fd, 0, SEEK_END);
+
+ /* Write past end of file? Nothing to save.*/
+ if (p->u.write.old_filelen <= p->u.write.off)
+ p->u.write.saved_len = 0;
+ /* Write which goes over end of file? Partial save. */
+ else if (p->u.write.off + count > p->u.write.old_filelen)
+ p->u.write.saved_len = p->u.write.old_filelen
+ - p->u.write.off;
+ /* Full save. */
+ else
+ p->u.write.saved_len = count;
+
+ p->u.write.saved_contents = malloc(p->u.write.saved_len);
+ lseek(fd, p->u.write.off, SEEK_SET);
+ ret = read(fd, p->u.write.saved_contents, p->u.write.saved_len);
+ if (ret != p->u.write.saved_len)
+ err(1, "Expected %i bytes, got %i",
+ (int)p->u.write.saved_len, (int)ret);
+ lseek(fd, p->u.write.off, SEEK_SET);
+ set_cleanup(p, cleanup_write, struct write_call);
+ }