Merged from trunk 7838:7877
authorFabian Groffen <grobian@gentoo.org>
Sat, 29 Sep 2007 20:29:54 +0000 (20:29 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 29 Sep 2007 20:29:54 +0000 (20:29 -0000)
   | 7839     | someone seriously screwed the pooch on whitespacing here so |
   | SpankMan | clean it all up                                             |

   | 7840     | Fix a typo.                                                 |
   | zmedico  |                                                             |

   | 7842     | align the filename and line numbers in the output of the    |
   | SpankMan | stack dump so that it is much easier to read                |

   | 7844     | Display a short notification when an existing               |
   | zmedico  | ${T}/environment sourced since it is easy to ignore and     |
   |          | ignorance of it often leads to mysterious problems and      |
   |          | general confusion. This message should not show in cases    |
   |          | where it is obviously irrelevant, FEATURES=noauto, or       |
   |          | PORTAGE_QUIET=1.                                            |

   | 7846     | Do the stale env check/warning after the digest/manifest    |
   | zmedico  | phase when necessary.                                       |

   | 7848     | Bug #193486 - Use xargs to avoid 'bash: /bin/rm: Argument   |
   | zmedico  | list too long' errors. This patch uses a weird tr '\001'    |
   |          | '\000' workaround since bash doesn't echo null bytes like   |
   |          | one might expect.                                           |

   | 7850     | Bug #193486 - Use echo -n and properly quote the array      |
   | zmedico  | argument.                                                   |

   | 7852     | with help from Donnie and Ulrich, use sed to extract the    |
   | SpankMan | statement that led to the call to die so we can print it    |
   |          | out in our error message                                    |

   | 7853     | Bug #194025 - Lock /var/db/pkg in post_merge() during the   |
   | zmedico  | "Regenerating GNU info directory index" routine.            |

   | 7856     | Ignore ENOTDIR from unmerge unlink calls.                   |
   | zmedico  |                                                             |

   | 7858     | Move a newline to fix formatting.                           |
   | zmedico  |                                                             |

   | 7861     | Simplify update_eclasses() a little.                        |
   | zmedico  |                                                             |

   | 7864     | Move prelink tempfile cleanup to the finally block and      |
   | zmedico  | remove unused locking code.                                 |

   | 7866     | Handle KeyError thrown from aux_get().                      |
   | zmedico  |                                                             |

   | 7869     | Bug #194081 - Add EBUSY to the list of ignored errnos for   |
   | zmedico  | unlink and rmdir calls during unmerge.                      |

   | 7871     | Bug #193548 - When emerge spawns find to search for config  |
   | zmedico  | updates, show the find output if there is an error.         |

   | 7873     | When scanning for config updates, treat a symlink to an     |
   | zmedico  | existing directory as if it's just a normal directory.      |

   | 7875     | Bug #193548 - When scanning for config updates and an error |
   | zmedico  | occurs, send find's stdout to /dev/null so that only an     |
   |          | error message is shown.                                     |

   | 7877     | Bug #194095 - Validate dispatch-conf input in order to      |
   | zmedico  | prevent spurious input characters from being interpreted as |
   |          | user input (which can be quite confusing and gives an "out  |
   |          | of control" feeling).                                       |

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

bin/dispatch-conf
bin/ebuild
bin/ecompress
bin/isolated-functions.sh
man/make.conf.5
pym/emerge/__init__.py
pym/portage/checksum.py
pym/portage/dbapi/vartree.py
pym/portage/eclass_cache.py

index 439af5d45b11f145db8406fffad27d6559d854f3..3701f587ae5433c027685c020c731d664e163d51 100755 (executable)
@@ -202,8 +202,10 @@ class dispatch:
                # Interactively process remaining
                #
 
-               for conf in confs:
-                       count = count + 1
+        valid_input = "qhtnmlezu"
+
+        for conf in confs:
+            count = count + 1
 
                        newconf = conf['new']
                        mrgconf = re.sub(r'\._cfg', '._mrg', newconf)
@@ -222,58 +224,67 @@ class dispatch:
                                print '>> (%i of %i) -- %s' % (count, len(confs), conf ['current'])
                                print '>> q quit, h help, n next, e edit-new, z zap-new, u use-new\n   m merge, t toggle-merge, l look-merge: ',
 
-                               c = getch ()
-
-                               if c == 'q':
-                                       sys.exit (0)
-                               if c == 'h':
-                                       self.do_help ()
-                                       continue
-                               elif c == 't':
-                                       if newconf == mrgconf:
-                                               newconf = conf['new']
-                                       elif os.path.exists(mrgconf):
-                                               newconf = mrgconf
-                                       continue
-                               elif c == 'n':
-                                       break
-                               elif c == 'm':
-                                       merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
-                                       print
-                                       ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
-                                       if ret:
-                                               print "Failure running 'merge' command"
-                                               continue
-                                       shutil.copyfile(merged, mrgconf)
-                                       os.remove(merged)
-                                       mystat = os.lstat(conf['new'])
-                                       os.chmod(mrgconf, mystat[ST_MODE])
-                                       os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
-                                       newconf = mrgconf
-                                       continue
-                               elif c == 'l':
-                                       show_new_diff = 1
-                                       continue
-                               elif c == 'e':
-                                       if not os.environ.has_key('EDITOR'):
-                                               os.environ['EDITOR']='nano'
-                                       os.system(os.environ['EDITOR'] + ' ' + newconf)
-                                       continue
-                               elif c == 'z':
-                                       os.unlink(conf['new'])
-                                       if os.path.exists(mrgconf):
-                                               os.unlink(mrgconf)
-                                       break
-                               elif c == 'u':
-                                       self.replace(newconf, conf ['current'])
-                                       self.post_process(conf['current'])
-                                       if newconf == mrgconf:
-                                               os.unlink(conf['new'])
-                                       elif os.path.exists(mrgconf):
-                                               os.unlink(mrgconf)
-                                       break
-                               else:
-                                       continue
+                # In some cases getch() will return some spurious characters
+                # that do not represent valid input. If we don't validate the
+                # input then the spurious characters can cause us to jump
+                # back into the above "diff" command immediatly after the user
+                # has exited it (which can be quite confusing and gives an
+                # "out of control" feeling).
+                while True:
+                    c = getch()
+                    if c in valid_input:
+                        break
+
+                if c == 'q':
+                    sys.exit (0)
+                if c == 'h':
+                    self.do_help ()
+                    continue
+                elif c == 't':
+                    if newconf == mrgconf:
+                        newconf = conf['new']
+                    elif os.path.exists(mrgconf):
+                        newconf = mrgconf
+                    continue
+                elif c == 'n':
+                    break
+                elif c == 'm':
+                    merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
+                    print
+                    ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
+                    if ret:
+                        print "Failure running 'merge' command"
+                        continue
+                    shutil.copyfile(merged, mrgconf)
+                    os.remove(merged)
+                    mystat = os.lstat(conf['new'])
+                    os.chmod(mrgconf, mystat[ST_MODE])
+                    os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
+                    newconf = mrgconf
+                    continue
+                elif c == 'l':
+                    show_new_diff = 1
+                    continue
+                elif c == 'e':
+                    if not os.environ.has_key('EDITOR'):
+                        os.environ['EDITOR']='nano'
+                    os.system(os.environ['EDITOR'] + ' ' + newconf)
+                    continue
+                elif c == 'z':
+                    os.unlink(conf['new'])
+                    if os.path.exists(mrgconf):
+                        os.unlink(mrgconf)
+                    break
+                elif c == 'u':
+                    self.replace(newconf, conf ['current'])
+                    self.post_process(conf['current'])
+                    if newconf == mrgconf:
+                        os.unlink(conf['new'])
+                    elif os.path.exists(mrgconf):
+                        os.unlink(mrgconf)
+                    break
+                else:
+                    raise AssertionError("Invalid Input: %s" % c)
 
                if auto_zapped:
                        print
index d29333ef13665c231e643cade3e224d51eeea38d..2dd02fe7cda0c92886e03d40061325aef011972f 100755 (executable)
@@ -138,8 +138,36 @@ if "test" in pargs and "test" not in tmpsettings.features:
        tmpsettings["FEATURES"] = " ".join(tmpsettings.features)
        tmpsettings.backup_changes("FEATURES")
 
+build_dir_phases = set(["setup", "unpack", "compile",
+       "test", "install", "package", "rpm"])
+
+def stale_env_warning():
+       if "clean" not in pargs and \
+               "noauto" not in tmpsettings.features and \
+               tmpsettings.get("PORTAGE_QUIET") != "1" and \
+               build_dir_phases.intersection(pargs):
+               portage.doebuild_environment(ebuild, "setup", portage.root,
+                       tmpsettings, debug, 1, portage.portdb)
+               env_filename = os.path.join(tmpsettings["T"], "environment")
+               if os.path.exists(env_filename):
+                       msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
+                               "Run 'clean' to start with a fresh environment.") % \
+                               (tmpsettings["PF"], )
+                       from textwrap import wrap
+                       msg = wrap(msg, 70)
+                       for x in msg:
+                               portage.writemsg(">>> %s\n" % x)
+
+checked_for_stale_env = False
+
 for arg in pargs:
        try:
+               if not checked_for_stale_env and arg not in ("digest","manifest"):
+                       # This has to go after manifest generation since otherwise
+                       # aux_get() might fail due to invalid ebuild digests.
+                       stale_env_warning()
+                       checked_for_stale_env = True
+
                if arg == "digest" and force:
                        discard_digests(ebuild, tmpsettings, portage.portdb)
                a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
index aeb16eab8986e665e21fa4119157a836af20d29d..13d6bd09d959213a1a9047773be99c5cbd127962 100755 (executable)
@@ -67,7 +67,8 @@ case $1 in
                # delete it so that the compressor doesn't whine (bzip2 will
                # complain and skip, gzip will prompt for input)
                suffix=$(ecompress --suffix)
-               [[ -n ${suffix} ]] && rm -f "${@/%/${suffix}}"
+               [[ -n ${suffix} ]] && echo -n "${@/%/${suffix}$'\001'}" | \
+                       tr '\001' '\000' | ${XARGS} -0 rm -f
                # Finally, let's actually do some real work
                exec "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
                ;;
index 15fc1758057f9acf835cb65ac1bc4287a40722f3..c1636b2153653fa587a1ace091c1dc06286f3ff8 100755 (executable)
@@ -12,72 +12,102 @@ alias restore_IFS='if [ "${old_IFS:-unset}" != "unset" ]; then IFS="${old_IFS}";
 
 shopt -s extdebug
 
-# usage- first arg is the number of funcs on the stack to ignore.
-# defaults to 1 (ignoring dump_trace)
+# dump_trace([number of funcs on stack to skip],
+#            [whitespacing for filenames],
+#            [whitespacing for line numbers])
 dump_trace() {
-        local funcname="" sourcefile="" lineno="" n e s="yes"
-
-        declare -i strip=1
-
-        if [[ -n $1 ]]; then
-                strip=$(( $1 ))
-        fi
-
-        eerror "Call stack:"
-        for (( n = ${#FUNCNAME[@]} - 1, p = ${#BASH_ARGV[@]} ; n > $strip ; n-- )) ; do
-                funcname=${FUNCNAME[${n} - 1]}
-                sourcefile=$(basename ${BASH_SOURCE[${n}]})
-                lineno=${BASH_LINENO[${n} - 1]}
-                # Display function arguments
-                args=
-                if [[ -n "${BASH_ARGV[@]}" ]]; then
-                        for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
-                                newarg=${BASH_ARGV[$(( p - j - 1 ))]}
-                                args="${args:+${args} }'${newarg}'"
-                        done
-                        (( p -= ${BASH_ARGC[${n} - 1]} ))
-                fi
-                eerror "  ${sourcefile}, line ${lineno}:   Called ${funcname}${args:+ ${args}}"
-        done
+       local funcname="" sourcefile="" lineno="" n e s="yes"
+       declare -i strip=${1:-1}
+       local filespacing=$2 linespacing=$3
+
+       eerror "Call stack:"
+       for (( n = ${#FUNCNAME[@]} - 1, p = ${#BASH_ARGV[@]} ; n > ${strip} ; n-- )) ; do
+               funcname=${FUNCNAME[${n} - 1]}
+               sourcefile=$(basename ${BASH_SOURCE[${n}]})
+               lineno=${BASH_LINENO[${n} - 1]}
+               # Display function arguments
+               args=
+               if [[ -n "${BASH_ARGV[@]}" ]]; then
+                       for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
+                               newarg=${BASH_ARGV[$(( p - j - 1 ))]}
+                               args="${args:+${args} }'${newarg}'"
+                       done
+                       (( p -= ${BASH_ARGC[${n} - 1]} ))
+               fi
+               eerror "  $(printf "%${filespacing}s" "${sourcefile}"), line $(printf "%${linespacing}s" "${lineno}"):  Called ${funcname}${args:+ ${args}}"
+       done
 }
 
 diefunc() {
-        local funcname="$1" lineno="$2" exitcode="$3"
-        shift 3
-        eerror
-        eerror "ERROR: $CATEGORY/$PF failed."
-        dump_trace 2
-        eerror "  ${BASH_SOURCE[1]##*/}, line ${BASH_LINENO[0]}:   Called die"
-        eerror
-        eerror "${*:-(no error message)}"
-        eerror "If you need support, post the topmost build error, and the call stack if relevant."
-        [ -n "${PORTAGE_LOG_FILE}" ] && \
-            eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
-        if [ -n "${EBUILD_OVERLAY_ECLASSES}" ] ; then
-            eerror "This ebuild used the following eclasses from overlays:"
-            local x
-            for x in ${EBUILD_OVERLAY_ECLASSES} ; do
-                 eerror "  ${x}"
-            done
-        fi
-        if [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
-            local overlay=${EBUILD%/*}
-            overlay=${overlay%/*}
-            overlay=${overlay%/*}
-            eerror "This ebuild is from an overlay: '${overlay}/'"
-        fi
-        eerror
-
-        if [ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]; then
-                local x
-                for x in $EBUILD_DEATH_HOOKS; do
-                        ${x} "$@" >&2 1>&2
-                done
-        fi
-
-        # subshell die support
-        kill -s SIGTERM ${EBUILD_MASTER_PID}
-        exit 1
+       local funcname="$1" lineno="$2" exitcode="$3"
+       shift 3
+
+       local n filespacing=0 linespacing=0
+       # setup spacing to make output easier to read
+       for ((n = ${#FUNCNAME[@]} - 1; n >= 0; --n)); do
+               sourcefile=${BASH_SOURCE[${n}]} sourcefile=${sourcefile##*/}
+               lineno=${BASH_LINENO[${n}]}
+               ((filespacing < ${#sourcefile})) && filespacing=${#sourcefile}
+               ((linespacing < ${#lineno}))     && linespacing=${#lineno}
+       done
+
+       eerror
+       eerror "ERROR: $CATEGORY/$PF failed."
+       dump_trace 2 ${filespacing} ${linespacing}
+       eerror "  $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"):  Called die"
+       eerror "The specific snippet of code:"
+       # This scans the file that called die and prints out the logic that
+       # ended in the call to die.  This really only handles lines that end
+       # with '|| die' and any preceding lines with line continuations (\).
+       # This tends to be the most common usage though, so let's do it.
+       # Due to the usage of appending to the hold space (even when empty),
+       # we always end up with the first line being a blank (thus the 2nd sed).
+       sed -n \
+               -e "# When we get to the line that failed, append it to the
+                   # hold space, move the hold space to the pattern space,
+                   # then print out the pattern space and quit immediately
+                   ${BASH_LINENO[0]}{H;g;p;q}" \
+               -e '# If this line ends with a line continuation, append it
+                   # to the hold space
+                   /\\$/H' \
+               -e '# If this line does not end with a line continuation,
+                   # erase the line and set the hold buffer to it (thus
+                   # erasing the hold buffer in the process)
+                   /[^\]$/{s:^.*$::;h}' \
+               ${BASH_SOURCE[1]} \
+               | sed -e '1d' -e 's:^:RETAIN-LEADING-SPACE:' \
+               | while read -r n ; do eerror "  ${n#RETAIN-LEADING-SPACE}" ; done
+       eerror " The die message:"
+       eerror "  ${*:-(no error message)}"
+       eerror
+       eerror "If you need support, post the topmost build error, and the call stack if relevant."
+       [[ -n ${PORTAGE_LOG_FILE} ]] \
+               && eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
+       if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
+               eerror "This ebuild used the following eclasses from overlays:"
+               local x
+               for x in ${EBUILD_OVERLAY_ECLASSES} ; do
+                       eerror "  ${x}"
+               done
+       fi
+       if [[ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ]] ; then
+               local overlay=${EBUILD%/*}
+               overlay=${overlay%/*}
+               overlay=${overlay%/*}
+               eerror "This ebuild is from an overlay: '${overlay}/'"
+       fi
+       eerror
+
+       if [[ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]] ; then
+               local x
+               for x in $EBUILD_DEATH_HOOKS; do
+                       ${x} "$@" >&2 1>&2
+               done
+       fi
+
+       # subshell die support
+       kill -s SIGTERM ${EBUILD_MASTER_PID}
+       exit 1
 }
 
 quiet_mode() {
@@ -289,8 +319,9 @@ set_colors() {
        # Adjust COLS so that eend works properly on a standard BSD console.
        [ "${TERM}" = "cons25" ] && COLS=$((${COLS} - 1))
 
-       ENDCOL=$'\e[A\e['${COLS}'C'    # Now, ${ENDCOL} will move us to the end of the
-                                      # column;  irregardless of character width
+       # Now, ${ENDCOL} will move us to the end of the
+       # column;  irregardless of character width
+       ENDCOL=$'\e[A\e['${COLS}'C'
        if [ -n "${PORTAGE_COLORMAP}" ] ; then
                eval ${PORTAGE_COLORMAP}
        else
index 02bc326f10ea1337fb240cd232c159651c58e689..ee7493bd1ce20c77b84ab7e82fb6f7da016fd025 100644 (file)
@@ -138,7 +138,7 @@ SRC_URI digests are correct.  This feature also affects digest generation via
 \fIdigest\fR feature is enabled). Existing digests for files that do not exist
 in ${DISTDIR} will be automatically assumed even when \fIassume\-digests\fR is
 not enabled. If a file exists in ${DISTDIR} but it's size does not match the
-existing digest, the digest will be regenerated regardless of the whether or
+existing digest, the digest will be regenerated regardless of whether or
 not \fIassume\-digests\fR is enabled. The \fBebuild\fR(1) \fBdigest\fR command
 has a \fB\-\-force\fR option that can be used to force regeneration of digests.
 .TP
index eff84886fac9c82afe12cd53e4348f2a30eb5d04..66c7c480cf48b9e201e00b619ae081c354c1ec0a 100644 (file)
@@ -1924,6 +1924,7 @@ class depgraph(object):
                                                        print "For more information, see MASKED PACKAGES section in the emerge man page or "
                                                        print "refer to the Gentoo Handbook."
                                                else:
+                                                       print
                                                        alleb = bindb.match(x)
                                                        if alleb:
                                                                chost = pkgsettings["CHOST"]
@@ -1933,7 +1934,7 @@ class depgraph(object):
                                                                        if chost != pkg_chost:
                                                                                mreasons.append("CHOST: %s" % pkg_chost)
                                                                        print "- "+p+" (masked by: "+", ".join(mreasons)+")"
-                                                       print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
+                                                       print "!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
                                                        print "!!! Either add a suitable binary package or compile from an ebuild."
                                        else:
                                                print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
@@ -4504,9 +4505,17 @@ def post_emerge(trees, mtimedb, retval):
        else:
                mod_echo.finalize()
 
-       if "noinfo" not in settings.features:
-               chk_updated_info_files(normalize_path(target_root + EPREFIX), infodirs, info_mtimes, retval)
-       chk_updated_cfg_files(normalize_path(target_root + EPREFIX), config_protect)
+       vdb_path = os.path.join(target_root, portage.VDB_PATH)
+       portage.util.ensure_dirs(vdb_path)
+       vdb_lock = portage.locks.lockdir(vdb_path)
+       try:
+               if "noinfo" not in settings.features:
+                       chk_updated_info_files(target_root + EPREFIX, infodirs, info_mtimes, retval)
+               mtimedb.commit()
+       finally:
+               portage.locks.unlockdir(vdb_lock)
+
+       chk_updated_cfg_files(target_root + EPREFIX, config_protect)
        
        display_news_notification(trees)
        
@@ -4519,8 +4528,7 @@ def post_emerge(trees, mtimedb, retval):
                                print colorize("WARN", " * ") + " - %s" % f
                print "Use " + colorize("GOOD", "revdep-rebuild") + " to rebuild packages using these libraries"
                print "and then remerge the packages listed above."
-       
-       mtimedb.commit()
+
        sys.exit(retval)
 
 
@@ -4534,15 +4542,27 @@ def chk_updated_cfg_files(target_root, config_protect):
                                mymode = os.lstat(x).st_mode
                        except OSError:
                                continue
+                       if stat.S_ISLNK(mymode):
+                               # We want to treat it like a directory if it
+                               # is a symlink to an existing directory.
+                               try:
+                                       real_mode = os.stat(x).st_mode
+                                       if stat.S_ISDIR(real_mode):
+                                               mymode = real_mode
+                               except OSError:
+                                       pass
                        if stat.S_ISDIR(mymode):
                                mycommand = "find '%s' -iname '._cfg????_*'" % x
                        else:
                                mycommand = "find '%s' -maxdepth 1 -iname '._cfg????_%s'" % \
                                        os.path.split(x.rstrip(os.path.sep))
-                       a = commands.getstatusoutput(mycommand + \
-                               " ! -iname '.*~' ! -iname '.*.bak' -print0")
+                       mycommand += " ! -iname '.*~' ! -iname '.*.bak' -print0"
+                       a = commands.getstatusoutput(mycommand)
                        if a[0] != 0:
-                               print >> sys.stderr, " " + bad("*")+ " error scanning '%s'" % x
+                               sys.stderr.write(" %s error scanning '%s': " % (bad("*"), x))
+                               sys.stderr.flush()
+                               # Show the error message alone, sending stdout to /dev/null.
+                               os.system(mycommand + " 1>/dev/null")
                        else:
                                files = a[1].split('\0')
                                # split always produces an empty string as the last element
index c663b68d9987664601b7f302afe9b27a86569859..77716aefc44623c697508f63ab378f79bc441f85 100644 (file)
@@ -10,7 +10,6 @@ import stat
 import tempfile
 import portage.exception
 import portage.process
-import portage.locks
 import commands
 import md5, sha
 
@@ -200,7 +199,6 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0):
        global prelink_capable
        myfilename      = filename[:]
        prelink_tmpfile = None
-       mylock          = None
        try:
                if calc_prelink and prelink_capable:
                        # Create non-prelinked temporary file to checksum.
@@ -226,6 +224,8 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0):
                        if e.errno == errno.ENOENT:
                                raise portage.exception.FileNotFound(myfilename)
                        raise
+               return myhash, mysize
+       finally:
                if prelink_tmpfile:
                        try:
                                os.unlink(prelink_tmpfile)
@@ -233,10 +233,6 @@ def perform_checksum(filename, hashname="MD5", calc_prelink=0):
                                if e.errno != errno.ENOENT:
                                        raise
                                del e
-               return myhash, mysize
-       finally:
-               if mylock:
-                       portage.locks.unlockfile(mylock)
 
 def perform_multiple_checksums(filename, hashes=["MD5"], calc_prelink=0):
        """
index 064db4d2fb8382f6fe6a8db2171175119a48d7d4..dc1c23f143c22e85d5be688f7082ae2b68027eef 100644 (file)
@@ -1184,7 +1184,13 @@ class dblink(object):
 
                        #process symlinks second-to-last, directories last.
                        mydirs = []
-                       ignored_unlink_errnos = (errno.ENOENT, errno.EISDIR)
+                       ignored_unlink_errnos = (
+                               errno.EBUSY, errno.ENOENT,
+                               errno.ENOTDIR, errno.EISDIR)
+                       ignored_rmdir_errnos = (
+                               errno.EEXIST, errno.ENOTEMPTY,
+                               errno.EBUSY, errno.ENOENT,
+                               errno.ENOTDIR, errno.EISDIR)
                        modprotect = os.path.join(self.vartree.root, "lib/modules/")
 
                        def unlink(file_name, lstatobj):
@@ -1349,9 +1355,7 @@ class dblink(object):
                                                        bsd_chflags.chflags(parent_name, pflags)
                                        show_unmerge("<<<", "", "dir", obj)
                                except EnvironmentError, e:
-                                       if e.errno not in (errno.ENOENT,
-                                               errno.EEXIST, errno.ENOTEMPTY,
-                                               errno.ENOTDIR):
+                                       if e.errno not in ignored_rmdir_errnos:
                                                raise
                                        if e.errno != errno.ENOENT:
                                                show_unmerge("---", "!empty", "dir", obj)
index 8fac8aec4826813fc1e4070b7888329b39563f65..806505757fecce36be01d3142ff3a0c89ef81bf0 100644 (file)
@@ -42,23 +42,20 @@ class cache(object):
                self.eclasses = {}
                self._eclass_locations = {}
                eclass_len = len(".eclass")
+               ignored_listdir_errnos = (errno.ENOENT, errno.ENOTDIR)
                for x in [normalize_path(os.path.join(y,"eclass")) for y in self.porttrees]:
-                       eclass_filenames = []
                        try:
-                               for y in os.listdir(x):
-                                       if y.endswith(".eclass"):
-                                               eclass_filenames.append(y)
+                               eclass_filenames = os.listdir(x)
                        except OSError, e:
-                               if e.errno == errno.ENOENT:
-                                       del e
-                                       continue
-                               elif e.errno == errno.ENOTDIR:
+                               if e.errno in ignored_listdir_errnos:
                                        del e
                                        continue
                                elif e.errno == PermissionDenied.errno:
                                        raise PermissionDenied(x)
                                raise
                        for y in eclass_filenames:
+                               if not y.endswith(".eclass"):
+                                       continue
                                try:
                                        mtime = long(os.stat(os.path.join(x, y)).st_mtime)
                                except OSError: