Detect cases when long(stat_obj.st_mtime) != stat_obj[stat.ST_MTIME] due to
authorZac Medico <zmedico@gentoo.org>
Thu, 10 Dec 2009 00:09:53 +0000 (00:09 -0000)
committerZac Medico <zmedico@gentoo.org>
Thu, 10 Dec 2009 00:09:53 +0000 (00:09 -0000)
rounding up, and truncate digits as necessary to preserve the integral seconds
portion of the mtime.

svn path=/main/trunk/; revision=14996

pym/portage/__init__.py

index 2876c6b8c69d6b2950b9473d919466f6adb22d5b..d7917dc5fc33f80acf3f49023b0ac8a08af9380c 100644 (file)
@@ -7640,7 +7640,25 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None,
                                        # If rename succeeded then this is not necessary, since
                                        # rename automatically preserves timestamps with complete
                                        # precision.
-                                       os.utime(dest, (sstat.st_atime, sstat.st_mtime))
+                                       if sstat[stat.ST_MTIME] == long(sstat.st_mtime):
+                                               newmtime = sstat.st_mtime
+                                       else:
+                                               # Prevent mtime from rounding up to the next second.
+                                               int_mtime = sstat[stat.ST_MTIME]
+                                               mtime_str = "%i.9999999" % int_mtime
+                                               min_len = len(str(int_mtime)) + 2
+                                               while True:
+                                                       mtime_str = mtime_str[:-1]
+                                                       newmtime = float(mtime_str)
+                                                       if int_mtime == long(newmtime):
+                                                               break
+                                                       elif len(mtime_str) <= min_len:
+                                                               # This shouldn't happen, but let's make sure
+                                                               # we can never have an infinite loop.
+                                                               newmtime = int_mtime
+                                                               break
+
+                                       os.utime(dest, (newmtime, newmtime))
                                newmtime = sstat[stat.ST_MTIME]
        except OSError:
                # The utime can fail here with EPERM even though the move succeeded.