SuSE freeze fixed!
Gustavo Niemeyer
gustavo at niemeyer.net
Mon Dec 5 17:22:47 PST 2005
Here's the problem:
https://lists.dulug.duke.edu/pipermail/rpm-devel/2005-January/000264.html
Here's the fix for rpm:
http://gate.crashing.org/~fray/rpm/
and attached is the workaround for smart.
Thanks goes to Mauricio Teixeira, for hunting the problem with
so much will, to Jeff Johnson, for fixing the problem ages ago
and giving hints about the failure reason, and to fray for
providing urls/patches for rpm.
I'm sorry for taking so long to fix it. The reason was that I
was lacking time, and was unable to find resources to install
a SuSE system and debug the problem myself (yes, I accept a
SuSE notebook/desktop donation ;-).
Please, let me know if it works for all of you, so that I can
release a new version with that fix and the other ones in the
repository.
Cheers!
--
Gustavo Niemeyer
http://niemeyer.net
-------------- next part --------------
Index: smart/backends/rpm/pm.py
===================================================================
--- smart/backends/rpm/pm.py (revision 630)
+++ smart/backends/rpm/pm.py (working copy)
@@ -25,6 +25,7 @@
from smart.const import INSTALL, REMOVE, BLOCKSIZE
from smart.pm import PackageManager
from smart import *
+import tempfile
import sys, os
import codecs
import locale
@@ -203,86 +204,56 @@
self.fd = None
self.rpmout = None
self.rpmoutbuffer = ""
- self.rpmoutlock = thread.allocate_lock()
self.lasttopic = None
self.topic = None
def grabOutput(self, flag):
- self.rpmoutlock.acquire()
- try:
- if flag:
- if not self.rpmout:
- # Grab rpm output, but not the python one.
- self.stdout = sys.stdout
- self.stderr = sys.stderr
- writer = codecs.getwriter(ENCODING)
- reader = codecs.getreader(ENCODING)
- sys.stdout = writer(os.fdopen(os.dup(1), "w"))
- sys.stderr = writer(os.fdopen(os.dup(2), "w"))
- pipe = os.pipe()
- os.dup2(pipe[1], 1)
- os.dup2(pipe[1], 2)
- os.close(pipe[1])
- self.rpmout = reader(os.fdopen(pipe[0], "r"))
- setCloseOnExec(self.rpmout.fileno())
- flags = fcntl.fcntl(self.rpmout.fileno(), fcntl.F_GETFL, 0)
- flags |= os.O_NONBLOCK
- fcntl.fcntl(self.rpmout.fileno(), fcntl.F_SETFL, flags)
- thread.start_new(self._rpmoutthread, ())
- else:
- if self.rpmout:
- self.rpmoutlock.release()
- try:
- self._rpmout()
- finally:
- self.rpmoutlock.acquire()
- os.dup2(sys.stdout.fileno(), 1)
- os.dup2(sys.stderr.fileno(), 2)
- sys.stdout = self.stdout
- sys.stderr = self.stderr
- del self.stdout
- del self.stderr
- self.rpmout.close()
- self.rpmout = None
- finally:
- self.rpmoutlock.release()
-
- def _rpmoutthread(self):
- try:
- while self.rpmout:
- time.sleep(1)
- self._rpmout(True)
- except:
- import traceback
- traceback.print_exc()
-
- def _rpmout(self, tobuffer=False):
- self.rpmoutlock.acquire()
- try:
+ if flag:
+ if not self.rpmout:
+ # Grab rpm output, but not the python one.
+ self.stdout = sys.stdout
+ self.stderr = sys.stderr
+ writer = codecs.getwriter(ENCODING)
+ reader = codecs.getreader(ENCODING)
+ sys.stdout = writer(os.fdopen(os.dup(1), "w"))
+ sys.stderr = writer(os.fdopen(os.dup(2), "w"))
+ fd, rpmoutpath = tempfile.mkstemp("-smart-rpm-out.txt")
+ os.dup2(fd, 1)
+ os.dup2(fd, 2)
+ os.close(fd)
+ self.rpmout = reader(open(rpmoutpath))
+ os.unlink(rpmoutpath)
+ else:
if self.rpmout:
- try:
- output = self.rpmout.read(BLOCKSIZE)
- except (OSError, IOError), e:
- if e[0] != errno.EWOULDBLOCK:
- raise
- output = ""
- if output or not tobuffer and self.rpmoutbuffer:
- if tobuffer:
- self.rpmoutbuffer += output
- else:
- output = self.rpmoutbuffer+output
- self.rpmoutbuffer = ""
- if self.topic and self.topic != self.lasttopic:
- self.lasttopic = self.topic
- iface.info(self.topic)
- iface.info(output)
- finally:
- self.rpmoutlock.release()
+ self._process_rpmout()
+ os.dup2(sys.stdout.fileno(), 1)
+ os.dup2(sys.stderr.fileno(), 2)
+ sys.stdout = self.stdout
+ sys.stderr = self.stderr
+ del self.stdout
+ del self.stderr
+ self.rpmout.close()
+ self.rpmout = None
+ self.rpmoutbuffer = ""
+ def _process_rpmout(self, tobuffer=False):
+ if self.rpmout:
+ output = self.rpmout.read()
+ if output or not tobuffer and self.rpmoutbuffer:
+ if tobuffer:
+ self.rpmoutbuffer += output
+ else:
+ output = self.rpmoutbuffer+output
+ self.rpmoutbuffer = ""
+ if self.topic and self.topic != self.lasttopic:
+ self.lasttopic = self.topic
+ iface.info(self.topic)
+ iface.info(output)
+
def __call__(self, what, amount, total, infopath, data):
if self.rpmout:
- self._rpmout()
+ self._process_rpmout()
if what == rpm.RPMCALLBACK_INST_OPEN_FILE:
info, path = infopath
More information about the Smart
mailing list