[orca] Fix for bug #628275 and bug #628256
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Fix for bug #628275 and bug #628256
- Date: Mon, 30 Aug 2010 17:27:38 +0000 (UTC)
commit eb691b9571b7499129fb779440eadaadef0b4ac3
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date: Sun Aug 29 19:24:36 2010 -0400
Fix for bug #628275 and bug #628256
Bug #628256 - orca.die() should call sys.exit() rather than os._exit()
Bug #628275 - Orca should be more forgiving when invalid options and
arguments are specified
src/orca/orca.in | 2 +-
src/orca/orca.py | 310 +++++++++++++++++++++++++++++++++---------------------
2 files changed, 191 insertions(+), 121 deletions(-)
---
diff --git a/src/orca/orca.in b/src/orca/orca.in
index fe8ca69..1c6b934 100644
--- a/src/orca/orca.in
+++ b/src/orca/orca.in
@@ -105,7 +105,7 @@ waitForCleanup()
done
}
-trap cleanup HUP QUIT TERM INT ABRT EXIT
+trap cleanup HUP QUIT TERM INT ABRT
# Runs orca.
#
diff --git a/src/orca/orca.py b/src/orca/orca.py
index f151de4..94153b8 100644
--- a/src/orca/orca.py
+++ b/src/orca/orca.py
@@ -1670,14 +1670,17 @@ def start(registry):
registry.start(gil=settings.useGILIdleHandler)
def die(exitCode=1):
-
- # We know what we are doing here, so tell pylint not to flag
- # the _exit method call as a warning. The disable-msg is
- # localized to just this method.
- #
- # pylint: disable-msg=W0212
-
- os._exit(exitCode)
+ shutdown()
+ sys.exit(exitCode)
+
+ if exitCode > 1:
+ pid = os.getpid()
+ if exitCode == 50:
+ # Something is hung and we wish to abort.
+ sig = 9
+ else:
+ sig = 15
+ os.kill(pid, sig)
def timeout(signum=None, frame=None):
debug.println(debug.LEVEL_SEVERE,
@@ -1727,14 +1730,14 @@ def shutdown(script=None, inputEvent=None):
if settings.enableMagnifier or settings.enableMagLiveUpdating:
mag.shutdown()
- pyatspi.Registry.stop()
-
if settings.timeoutCallback and (settings.timeoutTime > 0):
signal.alarm(0)
_initialized = False
_restoreXmodmap(_orcaModifiers)
+ pyatspi.Registry.stop()
+
return True
exitCount = 0
@@ -1789,22 +1792,25 @@ def abortOnSignal(signum, frame):
def usage():
"""Prints out usage information."""
- print _("Usage: orca [OPTION...]")
- print
+ print(usageString())
+
+def usageString():
+ """Generates the usage information string."""
+ info = []
+ info.append(_("Usage: orca [OPTION...]"))
# Translators: this is the description of the command line option
# '-?, --help' that is used to display usage information.
#
- print "-?, --help " + _("Show this help message")
-
- print "-v, --version %s" % orca_platform.version
+ info.append("-?, --help " + _("Show this help message"))
+ info.append("-v, --version %s" % orca_platform.version)
# Translators: this is a testing option for the command line. It prints
# the names of the applications known to the accessibility infrastructure
# to stdout and then exits.
#
- print "-l, --list-apps " + \
- _("Print the known running applications")
+ info.append("-l, --list-apps " + \
+ _("Print the known running applications"))
# Translators: this enables debug output for Orca. The
# YYYY-MM-DD-HH:MM:SS portion is a shorthand way of saying that
@@ -1814,21 +1820,21 @@ def usage():
# always start with 'debug' and end with '.out', regardless of the
# locale.).
#
- print "--debug " + \
- _("Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out")
+ info.append("--debug " + \
+ _("Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out"))
# Translators: this enables debug output for Orca and overrides
# the name of the debug file Orca will use for debug output if the
# --debug option is used.
#
- print "--debug-file=filename " + \
- _("Send debug output to the specified file")
+ info.append("--debug-file=filename " + \
+ _("Send debug output to the specified file"))
# Translators: this is the description of the command line option
# '-s, --setup, --gui-setup' that will initially display a GUI dialog
# that would allow the user to set their Orca preferences.
#
- print "-s, --setup, --gui-setup " + _("Set up user preferences")
+ info.append("-s, --setup, --gui-setup " + _("Set up user preferences"))
# Translators: this is the description of the command line option
# '-t, --text-setup' that will initially display a list of questions
@@ -1836,58 +1842,58 @@ def usage():
# startup. For this to happen properly, Orca will need to be run
# from a terminal window.
#
- print "-t, --text-setup " + \
- _("Set up user preferences (text version)")
+ info.append("-t, --text-setup " + \
+ _("Set up user preferences (text version)"))
# Translators: this is the description of the command line option
# '-n, --no-setup' that means that Orca will startup without setting
# up any user preferences.
#
- print "-n, --no-setup " + \
- _("Skip set up of user preferences")
+ info.append("-n, --no-setup " + \
+ _("Skip set up of user preferences"))
# Translators: this is the description of the command line option
# '-u, --user-prefs-dir=dirname' that allows you to specify an alternate
# location for the user preferences.
#
- print "-u, --user-prefs-dir=dirname " + \
- _("Use alternate directory for user preferences")
+ info.append("-u, --user-prefs-dir=dirname " + \
+ _("Use alternate directory for user preferences"))
- print "-e, --enable=[" \
+ info.append("-e, --enable=[" \
+ "speech" + "|" \
+ "braille" + "|" \
+ "braille-monitor" + "|" \
+ "magnifier" + "|" \
+ "main-window" + "|" \
- + "splash-window" + "]",
+ + "splash-window" + "] ")
# Translators: if the user supplies an option via the '-e, --enable'
# command line option, it will be automatically enabled as Orca is
# started.
#
- print _("Force use of option")
+ info[-1] += _("Force use of option")
- print "-d, --disable=[" \
+ info.append("-d, --disable=[" \
+ "speech" + "|" \
+ "braille" + "|" \
+ "braille-monitor" + "|" \
+ "magnifier" + "|" \
+ "main-window" + "|" \
- + "splash-window" + "]",
+ + "splash-window" + "] ")
# Translators: if the user supplies an option via the '-d, --disable'
# command line option, it will be automatically disabled as Orca is
# started.
#
- print _("Prevent use of option")
+ info[-1] += _("Prevent use of option")
# Translators: this is the Orca command line option that will quit Orca.
# The user would run the Orca shell script again from a terminal window.
# If this command line option is specified, the script will quit any
# instances of Orca that are already running.
#
- print "-q, --quit " + \
- _("Quits Orca (if shell script used)")
+ info.append("-q, --quit " + \
+ _("Quits Orca (if shell script used)"))
# Translators: this is the Orca command line option that will force
# the termination of Orca.
@@ -1895,36 +1901,127 @@ def usage():
# If this command line option is specified, the script will quit any
# instances of Orca that are already running.
#
- print "-f, --forcequit " + \
- _("Forces orca to be terminated immediately.")
+ info.append("-f, --forcequit " + \
+ _("Forces orca to be terminated immediately."))
- print "-m, --migrate-config " +\
- "Move the user's preferences from ~/.orca to XDG-DATA-HOME/orca."
+ info.append("-m, --migrate-config " +\
+ "Move the user's preferences from ~/.orca to XDG-DATA-HOME/orca.")
# Translators: this is the Orca command line option to tell Orca to
# replace any existing Orca process(es) that might be running.
#
- print "--replace " +\
- _("Replace a currently running Orca")
+ info.append("--replace " +\
+ _("Replace a currently running Orca"))
# Translators: this is text being sent to a terminal and we want to
# keep the text lines within terminal boundaries.
#
- print
- print _("If Orca has not been previously set up by the user, Orca\n" \
- "will automatically launch the preferences set up unless\n" \
- "the -n or --no-setup option is used.")
+ info.append("\n" + \
+ _("If Orca has not been previously set up by the user, Orca\n" \
+ "will automatically launch the preferences set up unless\n" \
+ "the -n or --no-setup option is used."))
# Translators: this is more text being sent to a terminal and we want to
# keep the text lines within terminal boundaries.
#
- print
- print _("WARNING: suspending Orca, e.g. by pressing Control-Z, from\n" \
- "an AT-SPI enabled shell (such as gnome-terminal), can also\n" \
- "suspend the desktop until Orca is killed.")
+ info.append("\n" + \
+ _("WARNING: suspending Orca, e.g. by pressing Control-Z, from\n" \
+ "an AT-SPI enabled shell (such as gnome-terminal), can also\n" \
+ "suspend the desktop until Orca is killed."))
+
+ info.append("\n" + _("Report bugs to orca-list gnome org "))
+
+ return ("\n".join(info))
+
+def printMessageAndExit(msg):
+ # The use of os._exit() to immediately kill a child process
+ # after a fork() is documented at docs.python.org.
+ #
+ # pylint: disable-msg=W0212
+ #
+ pid = os.fork()
+ if pid:
+ os.waitpid(pid, 0)
+ os._exit(0)
+ else:
+ print msg
+ os._exit(0)
+
+def validateOptions(arglist, invalid=[]):
+ """Parses the list of options in arglist and removes those
+ which are not valid so that typos do not prevent the user
+ from starting Orca.
+
+ Arguments:
+ - arglist: The list of options and arguments provided by
+ the user.
+ - invalid: Options which have already been identified as
+ being invalid.
+
+ Returns: A list containing validated options, valided
+ arguments, and any items which were deemed invalid.
+ """
+
+ opts = []
+ args = []
+
+ # ? is for help
+ # e is for enabling a feature
+ # d is for disabling a feature
+ # h is for help
+ # u is for alternate user preferences location
+ # m is for migrate the user preferences location from ~/.orca
+ # s is for setup
+ # n is for no setup
+ # t is for text setup
+ # v is for version
+ #
+ shortopts = "?stnvlmd:e:u:"
+ longopts = ["help",
+ "user-prefs-dir=",
+ "enable=",
+ "disable=",
+ "setup",
+ "gui-setup",
+ "text-setup",
+ "no-setup",
+ "list-apps",
+ "debug",
+ "debug-file=",
+ "version",
+ "migrate-config",
+ "replace"]
- print
- print _("Report bugs to orca-list gnome org ")
+ try:
+ opts, args = getopt.getopt(arglist, shortopts, longopts)
+ except getopt.GetoptError as ex:
+ bogusOption = "-%s" % ex.opt
+ if len(bogusOption) >= 2:
+ bogusOption = "-%s" % bogusOption
+ invalid.append(bogusOption)
+ try:
+ arglist.remove(bogusOption)
+ except:
+ pass
+ else:
+ return validateOptions(arglist, invalid)
+ except:
+ pass
+
+ return opts, args, invalid
+
+def multipleOrcas():
+ """Returns True if multiple instances of Orca are running
+ which are owned by the same user."""
+
+ openFile = os.popen('pgrep -u %s orca' % os.getuid())
+ pids = openFile.read()
+ openFile.close()
+ orcas = [int(p) for p in pids.split()]
+
+ pid = os.getpid()
+ ppid = os.getppid()
+ return len(filter(lambda p: p not in [pid, ppid], orcas)) > 0
def main():
"""The main entry point for Orca. The exit codes for Orca will
@@ -1978,37 +2075,21 @@ def main():
if len(arglist) == 1:
arglist = arglist[0].split()
- try:
- # ? is for help
- # e is for enabling a feature
- # d is for disabling a feature
- # h is for help
- # u is for alternate user preferences location
- # m is for migrate the user preferences location from ~/.orca
- # s is for setup
- # n is for no setup
- # t is for text setup
- # v is for version
- # z is for no exit
+ validOpts, validArgs, invalidOpts = validateOptions(arglist)
+ validFeaturesListed = False
+ if invalidOpts:
+ # Translators: This message is displayed when the user tries
+ # to start Orca and includes an invalid option as an argument.
+ # After the message, the list of arguments, as typed by the
+ # user, is displayed.
#
- opts, args = getopt.getopt(
- arglist,
- "?stnvlmd:e:u:",
- ["help",
- "user-prefs-dir=",
- "enable=",
- "disable=",
- "setup",
- "gui-setup",
- "text-setup",
- "no-setup",
- "list-apps",
- "debug",
- "debug-file=",
- "version",
- "migrate-config",
- "replace"])
- for opt, val in opts:
+ msg = _("The following arguments are not valid: ")
+ print (msg + " ".join(invalidOpts))
+ if multipleOrcas():
+ die(0)
+
+ try:
+ for opt, val in validOpts:
if opt in ("-u", "--user-prefs-dir"):
userPrefsDir = val.strip()
try:
@@ -2025,50 +2106,43 @@ def main():
try:
os.renames(oldUserPrefsDir, userPrefsDir)
except:
- print "It seems like you are trying to migrate your " \
+ print "It seems like you are trying to migrate your " \
+ "preferences but the new location is not " \
+ "empty.\n" \
+ "Probably it was already migrated. \n" \
+ "Please, check it before you try again."
- die(2)
+ die(2)
settings.userPrefsDir = userPrefsDir
- if opt in ("-e", "--enable"):
- feature = val.strip()
-
- if feature == "speech":
- _commandLineSettings["enableSpeech"] = True
- elif feature == "braille":
- _commandLineSettings["enableBraille"] = True
- elif feature == "braille-monitor":
- _commandLineSettings["enableBrailleMonitor"] = True
- elif feature == "magnifier":
- _commandLineSettings["enableMagnifier"] = True
- elif feature == "main-window":
- _commandLineSettings["showMainWindow"] = True
- elif feature == "splash-window":
- _commandLineSettings["showSplashWindow"] = True
- else:
- usage()
- die(2)
-
- if opt in ("-d", "--disable"):
+ if opt in ("-e", "--enable", "-d", "--disable"):
feature = val.strip()
+ enable = opt in ("-e", "--enable")
if feature == "speech":
- _commandLineSettings["enableSpeech"] = False
+ _commandLineSettings["enableSpeech"] = enable
elif feature == "braille":
- _commandLineSettings["enableBraille"] = False
+ _commandLineSettings["enableBraille"] = enable
elif feature == "braille-monitor":
- _commandLineSettings["enableBrailleMonitor"] = False
+ _commandLineSettings["enableBrailleMonitor"] = enable
elif feature == "magnifier":
- _commandLineSettings["enableMagnifier"] = False
+ _commandLineSettings["enableMagnifier"] = enable
elif feature == "main-window":
- _commandLineSettings["showMainWindow"] = False
+ _commandLineSettings["showMainWindow"] = enable
elif feature == "splash-window":
- _commandLineSettings["showSplashWindow"] = False
+ _commandLineSettings["showSplashWindow"] = enable
else:
- usage()
- die(2)
+ valid = "\nspeech, braille, braille-monitor, magnifier, " \
+ "main-window, splash-window"
+ # Translators: This message is displayed when the user
+ # tries to enable or disable a feature via an argument,
+ # but specified an invalid feature. Valid features are:
+ # speech, braille, braille-monitor, magnifier, main-window,
+ # and splash-window. These items are not localized and are
+ # presented in a list after this message.
+ #
+ msg = _("The following items can be enabled or disabled:")
+ if not validFeaturesListed:
+ print (msg + valid)
+ validFeaturesListed = True
if opt in ("-s", "--gui-setup", "--setup"):
setupRequested = True
@@ -2079,11 +2153,9 @@ def main():
if opt in ("-n", "--no-setup"):
bypassSetup = True
if opt in ("-?", "--help"):
- usage()
- die(0)
+ printMessageAndExit(usageString())
if opt in ("-v", "--version"):
- print "Orca %s" % orca_platform.version
- die(0)
+ printMessageAndExit("Orca %s" % orca_platform.version)
if opt == "--debug":
_debugSwitch = True
if not _debugFile:
@@ -2094,10 +2166,8 @@ def main():
if opt in ("-l", "--list-apps"):
apps = filter(lambda x: x is not None,
pyatspi.Registry.getDesktop(0))
- for app in apps:
- print app.name
- die(0)
-
+ names = [app.name for app in apps]
+ printMessageAndExit("\n".join(names))
except:
debug.printException(debug.LEVEL_OFF)
usage()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]