From a9394222c323143c0fea03848a3f1daf79017a00 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Nov 2012 12:11:41 +0100 Subject: [PATCH] properly open and close processes --- dsl.py | 19 +++++++++++++------ gui.py | 7 ++++++- zenity_dialogue.py | 7 +++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/dsl.py b/dsl.py index 890ea70..d13d0a0 100755 --- a/dsl.py +++ b/dsl.py @@ -78,13 +78,24 @@ def loadConfigFile(file): # add some convencience get functions return result +# helper function: execute a process, return output as iterator, throw exception if there was an error +# you *must* iterate to the end if you use this! +def processOutputGen(*args): + p = subprocess.Popen(args, stdout=subprocess.PIPE) + for line in p.stdout: + yield line + p.wait() # wait for process to exit (it closed stdout, so it can't block anymore) + if p.returncode != 0: + raise Exception("Error executing "+str(args)) +def processOutputIt(*args): + return list(processOutputGen(*args)) # list() iterates over the generator + # Run xrandr and return a dict of output names mapped to lists of available resolutions, each being a (width, height) pair. # An empty list indicates that the connector is disabled. def getXrandrInformation(): - p = subprocess.Popen(["xrandr", "-q"], stdout=subprocess.PIPE) connectors = {} # map of connector names to a list of resolutions connector = None # current connector - for line in p.stdout: + for line in processOutputGen("xrandr", "-q"): # screen? m = re.search(r'^Screen [0-9]+: ', line) if m is not None: # ignore this line @@ -107,10 +118,6 @@ def getXrandrInformation(): # not fatal as my xrandr shows strange stuff when a display is enabled, but not connected #raise Exception("Unknown line in xrandr output:\n"+line) print "Warning: Unknown xrandr line %s" % line - # be sure to always proprly finish up with the xrandr - p.communicate() - # if everything succeededso far, check return code - if p.returncode != 0: raise Exception("Querying xrandr for data failed.") return connectors # convert a (width, height) pair into a string accepted by xrandr as argument for --mode diff --git a/gui.py b/gui.py index b3929cb..6dabe0f 100644 --- a/gui.py +++ b/gui.py @@ -39,7 +39,12 @@ def qtAvailable(): return False def zenityAvailable(): - return True # FIXME + try: + from dsl import processOutputIt + processOutputIt("zenity", "--version") + return True + except Exception: + return False # actual frontends if qtAvailable(): diff --git a/zenity_dialogue.py b/zenity_dialogue.py index 69365e8..60d7827 100644 --- a/zenity_dialogue.py +++ b/zenity_dialogue.py @@ -15,14 +15,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -import subprocess -from dsl import RelativeScreenPosition, ScreenSetup, res2user +from dsl import RelativeScreenPosition, ScreenSetup, res2user, processOutputIt def userChoose (title, choices, returns, fallback): assert len(choices) == len(returns) - p = subprocess.Popen(["zenity", "--list", "--text="+title, "--column="]+choices, stdout=subprocess.PIPE) + args = ["zenity", "--list", "--text="+title, "--column="]+choices switch = dict (zip (choices,returns)) - for line in p.stdout: # FIXME use p.communicate()[0] instead to get entire stdout and ensure the process terminates. also check p.returncode. + for line in processOutputIt(*args): return switch.get(line.strip(), fallback) return fallback -- 2.30.2