From fce09cb7e56fa39daaecce4ee320fffe2960d162 Mon Sep 17 00:00:00 2001 From: owsla Date: Tue, 10 Jun 2008 12:55:59 +0000 Subject: Do not use inode numbers on Windows and gracefully handle attempts to rename over existing files on Windows. (Patch from Josh Nisly) git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@886 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109 --- rdiff-backup/CHANGELOG | 3 +++ rdiff-backup/rdiff_backup/cmodule.c | 9 ++++++++- rdiff-backup/rdiff_backup/rpath.py | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/rdiff-backup/CHANGELOG b/rdiff-backup/CHANGELOG index e1306ad..b1b3b24 100644 --- a/rdiff-backup/CHANGELOG +++ b/rdiff-backup/CHANGELOG @@ -1,6 +1,9 @@ New in v1.1.16 (????/??/??) --------------------------- +Do not use inode numbers on Windows and gracefully handle attempts to +rename over existing files on Windows. (Patch from Josh Nisly) + Finally fix 'No such file or directory' bug when attempting to regress after a failed backup. (Patch from Josh Nisly) diff --git a/rdiff-backup/rdiff_backup/cmodule.c b/rdiff-backup/rdiff_backup/cmodule.c index 28c5292..36915a6 100644 --- a/rdiff-backup/rdiff_backup/cmodule.c +++ b/rdiff-backup/rdiff_backup/cmodule.c @@ -66,6 +66,8 @@ /* The following section is by Jeffrey A. Marshall and compensates for * a bug in Mac OS X's S_ISFIFO and S_ISSOCK macros. + * Note: Starting in Mac OS X 10.3, the buggy macros were changed to be + * the same as the ones below. */ #ifdef __APPLE__ /* S_ISFIFO/S_ISSOCK macros from on mac osx are bogus */ @@ -116,13 +118,18 @@ static PyObject *c_make_file_dict(self, args) return NULL; } } +#if defined(MS_WINDOWS) + size = PyLong_FromLongLong((PY_LONG_LONG)sbuf.st_size); + inode = PyLong_FromLongLong((PY_LONG_LONG)-1); +#else #ifdef HAVE_LARGEFILE_SUPPORT size = PyLong_FromLongLong((PY_LONG_LONG)sbuf.st_size); inode = PyLong_FromLongLong((PY_LONG_LONG)sbuf.st_ino); #else size = PyInt_FromLong(sbuf.st_size); inode = PyInt_FromLong((long)sbuf.st_ino); -#endif +#endif /* HAVE_LARGEFILE_SUPPORT */ +#endif /* defined(MS_WINDOWS) */ mode = (long)sbuf.st_mode; perms = mode & 07777; #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py index b33bf14..b0fe10b 100644 --- a/rdiff-backup/rdiff_backup/rpath.py +++ b/rdiff-backup/rdiff_backup/rpath.py @@ -244,12 +244,22 @@ def rename(rp_source, rp_dest): log.Log(lambda: "Renaming %s to %s" % (rp_source.path, rp_dest.path), 7) if not rp_source.lstat(): rp_dest.delete() else: - if rp_dest.lstat() and rp_source.getinode() == rp_dest.getinode(): + if rp_dest.lstat() and rp_source.getinode() == rp_dest.getinode() and \ + rp_source.getinode() != -1: log.Log("Warning: Attempt to rename over same inode: %s to %s" % (rp_source.path, rp_dest.path), 2) # You can't rename one hard linked file over another rp_source.delete() - else: rp_source.conn.os.rename(rp_source.path, rp_dest.path) + else: + try: + rp_source.conn.os.rename(rp_source.path, rp_dest.path) + except OSError, error: + if error.errno != errno.EEXIST: raise + + # On Windows, files can't be renamed on top of an existing file + rp_source.conn.os.unlink(rp_dest.path) + rp_source.conn.os.rename(rp_source.path, rp_dest.path) + rp_dest.data = rp_source.data rp_source.data = {'type': None} -- cgit v1.2.1