From: Fabian Groffen Date: Thu, 10 Dec 2009 08:14:14 +0000 (-0000) Subject: Merged from trunk -r14994:15019 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=e136df02403ff6f5a596256fefad6b782b590d59;p=portage.git Merged from trunk -r14994:15019 | 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 | | | 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 --- diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index f6a8c900d..79b4b6386 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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) diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index a7b104fda..ee2cc1b65 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -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: