Merged from trunk -r14994:15019
authorFabian Groffen <grobian@gentoo.org>
Thu, 10 Dec 2009 08:14:14 +0000 (08:14 -0000)
committerFabian Groffen <grobian@gentoo.org>
Thu, 10 Dec 2009 08:14:14 +0000 (08:14 -0000)
   | 14995   | In movefile(), always use stat_obj[stat.ST_MTIME] for the    |
   | zmedico | integral timestamp which is returned, since the              |
   |         | stat_obj.st_mtime float attribute rounds *up* if the         |
   |         | nanosecond part of the timestamp is 999999881 ns or greater. |

   | 14996   | Detect cases when long(stat_obj.st_mtime) !=                 |
   | zmedico | stat_obj[stat.ST_MTIME] due to rounding up, and truncate     |
   |         | digits as necessary to preserve the integral seconds portion |
   |         | of the mtime.                                                |

   | 14997   | Handle permission problems when trying to cache the remote   |
   | zmedico | Packages file from a binhost. Thanks to Jeremy Olexa         |
   |         | <darkside@g.o> for reporting.                                |

   | 15014   | Don't enable EAPI 4_pre1 yet.                                |
   | zmedico |                                                              |

   | 15015   | Remove extra comman in comment.                              |
   | zmedico |                                                              |

   | 15019   | Fix introspection code in fetch() so that it works correctly |
   | zmedico | when myuris is an OrderedDict instance. This fixes broken    |
   |         | fetching for some packages.                                  |

svn path=/main/branches/prefix/; revision=15023

pym/portage/__init__.py
pym/portage/dbapi/bintree.py

index f6a8c900ddffd3e89d6ec842550ff11c14828b14..79b4b63862272cbad365422b3080892d093f7f12 100644 (file)
@@ -4540,7 +4540,8 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                locations = mymirrors
 
        file_uri_tuples = []
-       if isinstance(myuris, dict):
+       # Check for 'items' attribute since OrderedDict is not a dict.
+       if hasattr(myuris, 'items'):
                for myfile, uri_set in myuris.items():
                        for myuri in uri_set:
                                file_uri_tuples.append((myfile, myuri))
@@ -6084,7 +6085,7 @@ def _spawn_misc_sh(mysettings, commands, phase=None, **kwargs):
 
        return rval
 
-_testing_eapis = frozenset(["4_pre1"])
+_testing_eapis = frozenset()
 _deprecated_eapis = frozenset(["3_pre1", "2_pre3", "2_pre2", "2_pre1"])
 
 def _eapi_is_deprecated(eapi):
@@ -7657,9 +7658,12 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None,
                        print("!!!",e)
                        return None
 
+       # Always use stat_obj[stat.ST_MTIME] for the integral timestamp which
+       # is returned, since the stat_obj.st_mtime float attribute rounds *up*
+       # if the nanosecond part of the timestamp is 999999881 ns or greater.
        try:
                if hardlinked:
-                       newmtime = long(os.stat(dest).st_mtime)
+                       newmtime = os.stat(dest)[stat.ST_MTIME]
                else:
                        # Note: It is not possible to preserve nanosecond precision
                        # (supported in POSIX.1-2008 via utimensat) with the IEEE 754
@@ -7671,13 +7675,31 @@ 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))
-                               newmtime = long(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.
                # Instead of failing, use stat to return the mtime if possible.
                try:
-                       newmtime = long(os.stat(dest).st_mtime)
+                       newmtime = os.stat(dest)[stat.ST_MTIME]
                except OSError as e:
                        writemsg(_("!!! Failed to stat in movefile()\n"), noiselevel=-1)
                        writemsg("!!! %s\n" % dest, noiselevel=-1)
index a7b104fda39e18115449cdd35f3083524be07e1e..ee2cc1b65c7a9b6260cddcd5e42a1a1551174cf2 100644 (file)
@@ -742,10 +742,17 @@ class binarytree(object):
                        if pkgindex is rmt_idx:
                                pkgindex.modified = False # don't update the header
                                from portage.util import atomic_ofstream, ensure_dirs
-                               ensure_dirs(os.path.dirname(pkgindex_file))
-                               f = atomic_ofstream(pkgindex_file)
-                               pkgindex.write(f)
-                               f.close()
+                               try:
+                                       ensure_dirs(os.path.dirname(pkgindex_file))
+                                       f = atomic_ofstream(pkgindex_file)
+                                       pkgindex.write(f)
+                                       f.close()
+                               except PortageException:
+                                       if os.access(os.path.join(
+                                               self.settings["ROOT"], CACHE_PATH), os.W_OK):
+                                               raise
+                                       # The current user doesn't have permission to cache the
+                                       # file, but that's alright.
                        if pkgindex:
                                self._remotepkgs = {}
                                for d in pkgindex.packages: