def spawn(self, args=None, callback=None, data=None, cwd=None): '''Start the application in the background and return immediately. This is used to start an external in parallel with zim that is not expected to exit immediatly, so we do not want to wait for it - e.g. a webbrowser to show an URL that was clicked. @param args: additional arguments to give to the command as tuple or list @param callback: optional callback can be used to trigger when the application exits. The signature is:: callback(status, data) where 'C{status}' is the exit status of the process. The application object provides a constant 'C{STATUS_OK}' which can be used to test if the application was successful or not. @param data: additional data for the callback @param cwd: the folder to set as working directory for the command @returns: the PID for the new process ''' cwd, argv = self._checkargs(cwd, args) opts = {} flags = GObject.SPAWN_SEARCH_PATH if callback: flags |= GObject.SPAWN_DO_NOT_REAP_CHILD # without this flag child is reaped automatically -> no zombies logger.info('Spawning: %s (cwd: %s)', argv, cwd) if TEST_MODE: TEST_MODE_RUN_CB(argv) return None try: try: pid, stdin, stdout, stderr = \ GObject.spawn_async(argv, flags=flags, **opts) except GObject.GError: if _CAN_CALL_FLATPAK_HOST_COMMAND: pid, stdin, stdout, stderr = \ GObject.spawn_async(_FLATPAK_HOSTCOMMAND_PREFIX + argv, flags=flags, **opts) else: raise except GObject.GError: from zim.gui.widgets import ErrorDialog ErrorDialog(None, _('Failed running: %s') % argv[0]).run() #~ # T: error when application failed to start return None else: logger.debug('Process started with PID: %i', pid) if callback: # child watch does implicit reaping -> no zombies if data is None: GObject.child_watch_add( pid, lambda pid, status: callback(status)) else: GObject.child_watch_add( pid, lambda pid, status, data: callback(status, data), data) return pid
def upload_files(self, menu, files): # This is the method invoked when our extension is activated # Do whatever you want to do with the files selected if len(files) == 0: return names = [file.get_uri() for file in files] argv = [PROGRAM_NAME] + names # TODO: use startup notification GObject.spawn_async(argv, flags=GObject.SPAWN_SEARCH_PATH)
def upload_files(self, menu, files): # This is the method invoked when our extension is activated # Do whatever you want to do with the files selected if len(files) == 0: return names = [ file.get_uri() for file in files ] argv = [ PROGRAM_NAME ] + names # TODO: use startup notification GObject.spawn_async(argv, flags=GObject.SPAWN_SEARCH_PATH)
def do_spawn_async(event): flags = GLib.SPAWN_DO_NOT_REAP_CHILD|GLib.SPAWN_SEARCH_PATH if sys.platform == "win32": flags |= GLib.SPAWN_WIN32_HIDDEN_CONSOLE self.pid, stdin, stdout, stderr = GObject.spawn_async(argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=flags) log.debug("SubProcess.__init__: _initChannel...", extra={"task":self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task":self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task":self.defname}) # On Python3 pygobject versions before 3.10.0 spawn_async returns pid as 0 # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=712537 if self.pid != 0: GObject.child_watch_add(self.pid, self.__child_watch_callback, None) if event is not None: event.set()
def do_spawn_async(event): self.pid, stdin, stdout, stderr = GObject.spawn_async( argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task": self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN | GObject.IO_HUP #|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task": self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task": self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback, None) if event is not None: event.set()
def start_session(self, host, port, session, username, password, wait): """ Start a session using x2go """ # Start in the background and attach a watch for when it exits cmd = [os.path.join(softwarecenter.paths.datadir, softwarecenter.paths.X2GO_HELPER)] (self.helper_pid, stdin, stdout, stderr) = GObject.spawn_async( cmd, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD) self.helper_stdin = os.fdopen(stdin, "w") self.helper_stdout = os.fdopen(stdout) self.helper_stderr = os.fdopen(stderr) # Add a watch for when the process exits GObject.child_watch_add(self.helper_pid, self._on_x2go_exit) # Add a watch on stdout GObject.io_add_watch(self.helper_stdout, GObject.IO_IN, self._on_x2go_activity) # Start the connection self.state = "connecting" self.helper_stdin.write( "CONNECT: \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n" % (host, port, username, password, session)) self.helper_stdin.flush()
def start_session(self, host, port, session, username, password, wait): """ Start a session using qtnx """ self.state = "connecting" if not os.path.exists(os.path.expanduser('~/.qtnx')): os.mkdir(os.path.expanduser('~/.qtnx')) # Generate qtnx's configuration file filename = os.path.expanduser('~/.qtnx/%s-%s-%s.nxml') % ( host, port, session.replace("/", "_")) nxml = open(filename, "w+") config = self.NXML_TEMPLATE config = config.replace("WL_NAME", "%s-%s-%s" % (host, port, session.replace("/", "_"))) config = config.replace("WL_SERVER", host) config = config.replace("WL_PORT", str(port)) config = config.replace("WL_COMMAND", "weblive-session %s" % session) nxml.write(config) nxml.close() # Prepare qtnx call cmd = [self.BINARY_PATH, '%s-%s-%s' % (str(host), str(port), session.replace("/", "_")), username, password] def qtnx_countdown(): """ Send progress events every two seconds """ if self.helper_progress == 10: self.state = "connected" self.emit("connected", False) return False else: self.emit("progress", self.helper_progress * 10) self.helper_progress += 1 return True def qtnx_start_timer(): """ As we don't have a way of knowing the connection status, we countdown from 20s """ self.helper_progress = 0 qtnx_countdown() GObject.timeout_add_seconds(2, qtnx_countdown) qtnx_start_timer() if wait == False: # Start in the background and attach a watch for when it exits (self.helper_pid, stdin, stdout, stderr) = GObject.spawn_async( cmd, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD) GObject.child_watch_add(self.helper_pid, self._on_qtnx_exit, filename) else: # Start it and wait till it finishes p = subprocess.Popen(cmd) p.wait()
def __init__(self, path, args=[], warnwords=[], env=None, chdir="."): GObject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", 'SubProcess.linePublisher', EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f", time.localtime(t)) % (t % 60)) log.debug(path, extra={"task": self.defname}) argv = [str(u) for u in [self.path] + self.args] log.debug("SubProcess.__init__: spawning...", extra={"task": self.defname}) self.pid, stdin, stdout, stderr = GObject.spawn_async( argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task": self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN | GObject.IO_HUP #|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task": self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task": self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback) log.debug("SubProcess.__init__: subprocExitCode...", extra={"task": self.defname}) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() subprocesses.append(self) log.debug("SubProcess.__init__: finished", extra={"task": self.defname})
def run(self, cmd): self._cmd = cmd (pid, stdin, stdout, stderr) = GObject.spawn_async( cmd, flags = GObject.SPAWN_DO_NOT_REAP_CHILD, standard_output=True, standard_error=True) LOG.debug("running: '%s' as pid: '%s'" % (cmd, pid)) self._child_watch = GObject.child_watch_add( pid, self._helper_finished, data=(stdout, stderr)) self._io_watch = GObject.io_add_watch( stdout, GObject.IO_IN, self._helper_io_ready, (stdout, ))
def run(self, cmd): self._cmd = cmd (pid, stdin, stdout, stderr) = GObject.spawn_async( cmd, flags=GObject.SPAWN_DO_NOT_REAP_CHILD, standard_output=True, standard_error=True) LOG.debug("running: '%s' as pid: '%s'" % (cmd, pid)) self._child_watch = GObject.child_watch_add( pid, self._helper_finished, data=(stdout, stderr)) self._io_watch = GObject.io_add_watch( stdout, GObject.IO_IN, self._helper_io_ready, (stdout, ))
def _check_for_channel_updates_timer(self): """ run a background timer to see if the a-x-i data we have is still fresh or if the cache has changed since """ # this is expensive and does not need UI to we shove it out channel_update = os.path.join( softwarecenter.paths.datadir, "update-software-center-channels") (pid, stdin, stdout, stderr) = GObject.spawn_async( [channel_update], flags=GObject.SPAWN_DO_NOT_REAP_CHILD) GObject.child_watch_add( pid, self._on_check_for_channel_updates_finished)
def _check_for_channel_updates_timer(self): """ run a background timer to see if the a-x-i data we have is still fresh or if the cache has changed since """ # this is expensive and does not need UI to we shove it out channel_update = os.path.join(softwarecenter.paths.datadir, "update-software-center-channels") (pid, stdin, stdout, stderr) = GObject.spawn_async([channel_update], flags=GObject.SPAWN_DO_NOT_REAP_CHILD) GObject.child_watch_add(pid, self._on_check_for_channel_updates_finished)
def _run_synaptic(self, action, opt, tempf): """Execute synaptic.""" try: apt_pkg.pkgsystem_unlock() except SystemError: pass cmd = ["/usr/bin/gksu", "--desktop", "/usr/share/applications/update-manager.desktop", "--", "/usr/sbin/synaptic", "--hide-main-window", "--non-interactive", "--parent-window-id", "%s" % self.window_main.window.xid ] cmd.extend(opt) flags = GObject.SPAWN_DO_NOT_REAP_CHILD (pid, stdin, stdout, stderr) = GObject.spawn_async(cmd, flags=flags) GObject.child_watch_add(pid, self._on_synaptic_exit, (action, tempf))
def run(self, cmd): # only useful for debugging if "SOFTWARE_CENTER_DISABLE_SPAWN_HELPER" in os.environ: return self._cmd = cmd (pid, stdin, stdout, stderr) = GObject.spawn_async(cmd, flags=GObject.SPAWN_DO_NOT_REAP_CHILD, standard_output=True, standard_error=True) LOG.debug("running: '%s' as pid: '%s'" % (cmd, pid)) self._child_watch = GObject.child_watch_add(pid, self._helper_finished, data=(stdout, stderr)) self._io_watch = GObject.io_add_watch(stdout, GObject.IO_IN, self._helper_io_ready, (stdout, ))
def _run_synaptic(self, action, opt, tempf): """Execute synaptic.""" try: apt_pkg.pkgsystem_unlock() except SystemError: pass cmd = ["/usr/bin/pkexec", "/usr/sbin/synaptic", "--hide-main-window", "--non-interactive", "--parent-window-id", "%s" % self.window_main.get_window().get_xid() ] cmd.extend(opt) flags = GObject.SPAWN_DO_NOT_REAP_CHILD (pid, stdin, stdout, stderr) = GObject.spawn_async(cmd, flags=flags) # Keep a reference to the data tuple passed to # GObject.child_watch_add to avoid attempts to destroy it without a # thread context: https://bugs.launchpad.net/bugs/724687 self.child_data = (action, tempf) GObject.child_watch_add(pid, self._on_synaptic_exit, self.child_data)
def _run_synaptic(self, xid, opt, tempf, interaction): deferred = Deferred() if tempf: opt.extend(["--set-selections-file", "%s" % tempf.name]) #FIXME: Take interaction into account opt.extend(["-o", "Synaptic::closeZvt=true"]) if xid: opt.extend(["--parent-window-id", "%s" % (xid)]) cmd = ["/usr/bin/gksu", "--desktop", "/usr/share/applications/update-manager.desktop", "--", "/usr/sbin/synaptic", "--hide-main-window", "--non-interactive"] cmd.extend(opt) flags = GObject.SPAWN_DO_NOT_REAP_CHILD (pid, stdin, stdout, stderr) = GObject.spawn_async(cmd, flags=flags) GObject.child_watch_add(pid, self._on_synaptic_exit, (tempf, deferred)) return deferred
def __init__(self, path, args=[], warnwords=[], env=None, chdir="."): GObject.GObject.__init__(self) self.path = path self.args = args self.warnwords = warnwords self.env = env or os.environ self.buffer = "" self.linePublisher = EmitPublisher(self, "line", 'SubProcess.linePublisher', EmitPublisher.SEND_LIST) self.linePublisher.start() self.defname = os.path.split(path)[1] self.defname = self.defname[:1].upper() + self.defname[1:].lower() t = time.time() self.defname = (self.defname, time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60)) log.debug(path, extra={"task":self.defname}) argv = [str(u) for u in [self.path]+self.args] log.debug("SubProcess.__init__: spawning...", extra={"task":self.defname}) self.pid, stdin, stdout, stderr = GObject.spawn_async(argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task":self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task":self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task":self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback) log.debug("SubProcess.__init__: subprocExitCode...", extra={"task":self.defname}) self.subprocExitCode = (None, None) self.subprocFinishedEvent = threading.Event() subprocesses.append(self) log.debug("SubProcess.__init__: finished", extra={"task":self.defname})
def run(self): """ Run the process. """ process_data = gobject.spawn_async( self.command, flags=gobject.SPAWN_SEARCH_PATH | gobject.SPAWN_DO_NOT_REAP_CHILD, standard_output=self.stdout, standard_error=self.stderr, ) self.pid = process_data[0] self.stdout = os.fdopen(process_data[2]) self.stderr = os.fdopen(process_data[3]) print self.stderr self.watch = gobject.child_watch_add(self.pid, self.exited_cb) return self.pid
def do_spawn_async(event): self.pid, stdin, stdout, stderr = GObject.spawn_async(argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH) log.debug("SubProcess.__init__: _initChannel...", extra={"task":self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task":self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task":self.defname}) GObject.child_watch_add(self.pid, self.__child_watch_callback, None) if event is not None: event.set()
def connect_to_wifi(self, widget): if not self.network_ssid: return if self.wifi_connect_pid: return logging.info('Trying to connect to network "%s"', self.network_ssid) self.connection_status.set_text( _tr('Connecting to "%s"...') % self.network_ssid) self.connect_button.set_sensitive(False) self.spinner.start() # The connect operation always creates a new connection to # NetworkManager configuration even if it fails. Clear up all # previous wireless connections (yes this is a big hammer). self.remove_all_wireless_connections() wifi_password = self.password_entry.get_text() cmd = [ '/usr/bin/env', 'LANG=C', 'nmcli', 'device', 'wifi', 'connect', self.network_ssid ] if wifi_password: cmd += ['password', wifi_password] self.wifi_connect_output = '' flags = GLib.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_STDERR_TO_DEV_NULL (self.wifi_connect_pid, stdin, stdout, stderr) \ = GObject.spawn_async(cmd, flags=flags, standard_output=True) fl = fcntl.fcntl(stdout, fcntl.F_GETFL) fcntl.fcntl(stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) GObject.io_add_watch(stdout, GObject.IO_HUP | GObject.IO_IN, self.wifi_connect_callback, os.fdopen(stdout))
def fetch_mail(self): """Shell out to a command to fetch email into a maildir""" logging.info("Calling: %s" % " ".join(self.fetch_cmd)) try: pid, _in, out, err = GObject.spawn_async( self.fetch_cmd, flags=GObject.SPAWN_DO_NOT_REAP_CHILD) except GLib.Error as e: err_s = "spawn failed: %s" % e logging.error(err_s) self.notify(err_s) self.set_timer(self.fetch_interval) # try again in a while return False self.fetch_subprocess_pid = pid self.change_state(self.FETCH_STATE_FETCHING) GObject.child_watch_add(pid, self.fetch_done_callback, None) self.set_timer(self.fetch_timeout) # ensure it doesn't take forever logging.debug("fetch process pid: %d" % pid) return False
def convert(self): src = self.target target = src.replace(self.codec,'.mp3') if os.path.exists(target): os.remove(target) if sys.platform != "linux2": ffmpeg_path = os.path.join(os.path.dirname(os.path.dirname(config.exec_path)),'ffmpeg\\ffmpeg.exe').replace("\\","\\\\") target = target.replace("\\","\\\\") src = src.replace("\\","\\\\") else: ffmpeg_path = "/usr/bin/ffmpeg" self.print_info(_('Extracting audio...')) try: self.gui.throbber.show() #print str(ffmpeg_path), '-i', str(src), '-f', 'mp3', '-ab', '192k', str(target) (pid,t,r,s) = GObject.spawn_async([str(ffmpeg_path), '-i', str(src), '-f', 'mp3', '-ab', '192k', str(target)],flags=GObject.SPAWN_DO_NOT_REAP_CHILD,standard_output = True, standard_error = True) GObject.child_watch_add(pid, self.task_done) except: self.print_info(_('Extraction failed...')) sleep(4) self.print_info('') self.gui.throbber.hide()
def _run_synaptic(self, action, opt, tempf): """Execute synaptic.""" try: apt_pkg.pkgsystem_unlock() except SystemError: pass win = self.window_main.get_window() try: xid = win.get_xid() except AttributeError: xid = 0 cmd = ["/usr/bin/pkexec", "/usr/sbin/synaptic", "--hide-main-window", "--non-interactive", "--parent-window-id", "%s" % xid] cmd.extend(opt) flags = GObject.SPAWN_DO_NOT_REAP_CHILD (pid, stdin, stdout, stderr) = GObject.spawn_async(cmd, flags=flags) # Keep a reference to the data tuple passed to # GObject.child_watch_add to avoid attempts to destroy it without a # thread context: https://bugs.launchpad.net/bugs/724687 self.child_data = (action, tempf) GObject.child_watch_add(pid, self._on_synaptic_exit, self.child_data)
def do_spawn_async(event): flags = GLib.SPAWN_DO_NOT_REAP_CHILD | GLib.SPAWN_SEARCH_PATH if sys.platform == "win32": flags |= GLib.SPAWN_WIN32_HIDDEN_CONSOLE self.pid, stdin, stdout, stderr = GObject.spawn_async( argv, working_directory=chdir, child_setup=self.__setup, standard_input=True, standard_output=True, standard_error=True, flags=flags) log.debug("SubProcess.__init__: _initChannel...", extra={"task": self.defname}) self.__channelTags = [] self.inChannel = self._initChannel(stdin, None, None, False) readFlags = GObject.IO_IN | GObject.IO_HUP #|GObject.IO_ERR self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False) self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True) log.debug("SubProcess.__init__: channelsClosed...", extra={"task": self.defname}) self.channelsClosed = False self.channelsClosedLock = threading.Lock() log.debug("SubProcess.__init__: child_watch_add...", extra={"task": self.defname}) # On Python3 pygobject versions before 3.10.0 spawn_async returns pid as 0 # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=712537 if self.pid != 0: GObject.child_watch_add(self.pid, self.__child_watch_callback, None) if event is not None: event.set()
def _perform_action(options, callable): _gobject.spawn_async([ "/bin/bash", "-c", options["action"] % (callable(),), ]),
def __run_spawn_async (self): return GObject.spawn_async (argv = self.cmd, envp = self.envp, flags = GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH, standard_output = True, standard_error = True)
def wrap(nouse): logging.info("spawning mailbox click_command: %s" % cmd) pid, _in, out, err = GObject.spawn_async(cmd)
def _start_window_manager(): cmd = ['metacity'] cmd.extend(['--no-force-fullscreen']) GObject.spawn_async(cmd, flags=GObject.SPAWN_SEARCH_PATH)