简体   繁体   中英

python: simple dbus example- os.fork() in service routine?

I am trying to write dbus server where I want to run some external shell program ( grep here) to do the job.

when I do:

prompt$ server.py

then:

prompt$ client.py # works fine, ie. runs grep command in child process.

prompt$ client.py # ..., but second invocation produces following error message:

DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.example.ExampleService was not provided by any .service files

I am stuck. Are You able to help me?

here is server.py (client.py thereafter):

import gtk, glib
import os
import dbus
import dbus.service
import dbus.mainloop.glib
import subprocess

messages_queue=list()
grep_pid=0


def queue_msg(message):
    global messages_queue
    messages_queue.append(message)
    return

def dequeue_msg():
    global messages_queue,grep_pid
    if grep_pid != 0:
        try:
            pid=os.waitpid(grep_pid,os.P_NOWAIT)
        except:
            return True
        if pid[0] == 0:
            return True
        grep_pid=0

    if len(messages_queue) == 0:
            return True
    else:
            tekst=messages_queue.pop(0)

        cmd="grep 'pp'"

        print cmd
        #works fine, when I do return here
        #return True

    grep_pid=os.fork()
    if grep_pid != 0:
        return True
    os.setpgid(0,0)
    pop=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE)
    pop.stdin.write(tekst)
    pop.stdin.close()
    pop.wait()
    exit(0)

class DemoException(dbus.DBusException):
    _dbus_error_name = 'org.example.Exception'

class MyServer(dbus.service.Object):

    @dbus.service.method("org.example.ExampleInterface",
                         in_signature='', out_signature='')
    def QueueMsg(self):
            queue_msg("ppppp")

    @dbus.service.method("org.example.ExampleInterface",
                         in_signature='', out_signature='')
    def Exit(self):
        mainloop.quit()

from dbus.mainloop.glib import threads_init

if __name__ == '__main__':
        glib.threads_init()

        threads_init()

        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

        session_bus = dbus.SessionBus()
        name = dbus.service.BusName("org.example.ExampleService", session_bus)
        object = MyServer(session_bus, '/My')

        glib.timeout_add_seconds(1, dequeue_msg)
        mainloop = glib.MainLoop()
        print "Running example service."
        mainloop.run()

now client.py:

import sys
from traceback import print_exc
import dbus

def main():
    bus = dbus.SessionBus()

    try:
        remote_object = bus.get_object("org.example.ExampleService",
                                       "/My")

    except dbus.DBusException:
        print_exc()
        sys.exit(1)

    iface = dbus.Interface(remote_object, "org.example.ExampleInterface")

    iface.QueueMsg()

    if sys.argv[1:] == ['--exit-service']:
        iface.Exit()

if __name__ == '__main__':
    main()

You usually get this error message when you try to access a service that is no longer available. Check if your server is still running.

You can use d-feet to debug your dbus connections.

The error message about the missing .service file means that you need to create a service file in dbus-1/services.

For example:

# /usr/local/share/dbus-1/services/org.example.ExampleService.service
[D-BUS Service]
Name=org.example.ExampleService
Exec=/home/user1401567/service.py

A lot of tutorials don't include this detail (maybe .service files didn't use to be required?) But, at least on Ubuntu 12.04, dbus services can't be connected to without it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM