Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file oBus_bus.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247(*
* oBus_bus.ml
* -----------
* Copyright : (c) 2008, Jeremie Dimino <jeremie@dimino.org>
* Licence : BSD3
*
* This file is a part of obus, an ocaml implementation of D-Bus.
*)letsection=Lwt_log.Section.make"obus(bus)"openLwt_reactopenLwt.InfixopenOBus_interfaces.Org_freedesktop_DBustypet=OBus_connection.t(* +-----------------------------------------------------------------+
| Local properties |
+-----------------------------------------------------------------+ *)moduleString_set=Set.Make(String)typeinfo={names:String_set.tsignal;set_names:String_set.t->unit;connection:OBus_connection.t;}letkey=OBus_connection.new_key()letname=OBus_connection.nameletnamesconnection=matchOBus_connection.getconnectionkeywith|Someinfo->info.names|None->invalid_arg"OBus_bus.names: not connected to a message bus"(* +-----------------------------------------------------------------+
| Message bus creation |
+-----------------------------------------------------------------+ *)letproxybus=OBus_proxy.make(OBus_peer.makebusOBus_protocol.bus_name)OBus_protocol.bus_pathletexit_on_disconnect=function|OBus_wire.Protocol_errormsg->ignore(Lwt_log.error_f~section"the D-Bus connection with the message bus has been closed due to a protocol error: %s"msg);exit1|OBus_connection.Connection_lost->ignore(Lwt_log.info~section"disconnected from D-Bus message bus");exit0|OBus_connection.Transport_errorexn->ignore(Lwt_log.error_f~section"the D-Bus connection with the message bus has been closed due to a transport error: %s"(Printexc.to_stringexn));exit1|exn->ignore(Lwt_log.error~section~exn"the D-Bus connection with the message bus has been closed due to this uncaught exception");exit1(* Handle name lost/acquired events *)letupdate_namesinfomessage=letopenOBus_messageinletname=OBus_connection.nameinfo.connectioninifname<>""&&message.destination=namethenmatchmessagewith|{sender="org.freedesktop.DBus";typ=Signal(["org";"freedesktop";"DBus"],"org.freedesktop.DBus","NameAcquired");body=[OBus_value.V.Basic(OBus_value.V.Stringname)]}->info.set_names(String_set.addname(S.valueinfo.names));Somemessage|{sender="org.freedesktop.DBus";typ=Signal(["org";"freedesktop";"DBus"],"org.freedesktop.DBus","NameLost");body=[OBus_value.V.Basic(OBus_value.V.Stringname)]}->info.set_names(String_set.removename(S.valueinfo.names));Somemessage|_->SomemessageelseSomemessageletregister_connectionconnection=matchOBus_connection.getconnectionkeywith|None->letnames,set_names=S.createString_set.emptyinletinfo={names;set_names;connection}inOBus_connection.setconnectionkey(Someinfo);let_=Lwt_sequence.add_l(update_namesinfo)(OBus_connection.incoming_filtersconnection)inlet%lwtname=OBus_method.callm_Hello(proxyconnection)()inOBus_connection.set_nameconnectionname;Lwt.return()|Some_->Lwt.return()letof_addresses?switchaddresses=let%lwtbus=OBus_connection.of_addresses?switchaddresses~shared:trueinlet%lwt()=register_connectionbusinLwt.returnbusletsession_bus=lazy(try%lwtlet%lwtbus=Lazy.forceOBus_address.session>>=of_addressesinOBus_connection.set_on_disconnectbusexit_on_disconnect;Lwt.returnbuswithexn->let%lwt()=Lwt_log.warning~exn~section"Failed to open a connection to the session bus"inLwt.failexn)letsession?switch()=Lwt_switch.checkswitch;let%lwtbus=Lazy.forcesession_businlet%lwt()=Lwt_switch.add_hook_or_execswitch(fun()->OBus_connection.closebus)inLwt.returnbusletsystem_bus_state=refNoneletsystem_bus_mutex=Lwt_mutex.create()letsystem?switch()=Lwt_switch.checkswitch;let%lwtbus=Lwt_mutex.with_locksystem_bus_mutex(fun()->match!system_bus_statewith|SomebuswhenS.value(OBus_connection.activebus)->Lwt.returnbus|_->try%lwtlet%lwtbus=Lazy.forceOBus_address.system>>=of_addressesinsystem_bus_state:=Somebus;Lwt.returnbuswithexn->let%lwt()=Lwt_log.warning~exn~section"Failed to open a connection to the system bus"inLwt.failexn)inlet%lwt()=Lwt_switch.add_hook_or_execswitch(fun()->OBus_connection.closebus)inLwt.returnbus(* +-----------------------------------------------------------------+
| Bindings to functions of the message bus |
+-----------------------------------------------------------------+ *)exceptionAccess_deniedofstring[@@obus"org.freedesktop.DBus.Error.AccessDenied"]exceptionService_unknownofstring[@@obus"org.freedesktop.DBus.Error.ServiceUnknown"]exceptionMatch_rule_not_foundofstring[@@obus"org.freedesktop.DBus.Error.MatchRuleNotFound"]exceptionMatch_rule_invalidofstring[@@obus"org.freedesktop.DBus.Error.MatchRuleInvalid"]exceptionName_has_no_ownerofstring[@@obus"org.freedesktop.DBus.Error.NameHasNoOwner"]exceptionAdt_audit_data_unknownofstring[@@obus"org.freedesktop.DBus.Error.AdtAuditDataUnknown"]exceptionSelinux_security_context_unknownofstring[@@obus"org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"]lethellobus=OBus_method.callm_Hello(proxybus)()typerequest_name_result=type_request_name_resultletrequest_namebus?(allow_replacement=false)?(replace_existing=false)?(do_not_queue=false)name=letflags=[]inletflags=ifallow_replacementthen`Allow_replacement::flagselseflagsinletflags=ifreplace_existingthen`Replace_existing::flagselseflagsinletflags=ifdo_not_queuethen`Do_not_queue::flagselseflagsinOBus_method.callm_RequestName(proxybus)(name,cast_request_name_flagsflags)>|=make_request_name_resulttyperelease_name_result=type_release_name_resultletrelease_namebusname=OBus_method.callm_ReleaseName(proxybus)name>|=make_release_name_resulttypestart_service_by_name_result=type_start_service_by_name_resultletstart_service_by_namebusname=OBus_method.callm_StartServiceByName(proxybus)(name,0l)>|=make_start_service_by_name_resultletname_has_ownerbusname=OBus_method.callm_NameHasOwner(proxybus)nameletlist_namesbus=OBus_method.callm_ListNames(proxybus)()letlist_activatable_namesbus=OBus_method.callm_ListActivatableNames(proxybus)()letget_name_ownerbusname=OBus_method.callm_GetNameOwner(proxybus)nameletlist_queued_ownersbusname=OBus_method.callm_ListQueuedOwners(proxybus)nameletadd_matchbusrule=OBus_method.callm_AddMatch(proxybus)(OBus_match.string_of_rulerule)letremove_matchbusrule=OBus_method.callm_RemoveMatch(proxybus)(OBus_match.string_of_rulerule)letupdate_activation_environmentbusdata=OBus_method.callm_UpdateActivationEnvironment(proxybus)dataletget_connection_unix_userbusname=OBus_method.callm_GetConnectionUnixUser(proxybus)name>|=Int32.to_intletget_connection_unix_process_idbusname=OBus_method.callm_GetConnectionUnixProcessID(proxybus)name>|=Int32.to_intletget_adt_audit_session_databusname=OBus_method.callm_GetAdtAuditSessionData(proxybus)nameletget_connection_selinux_security_contextbusname=OBus_method.callm_GetConnectionSELinuxSecurityContext(proxybus)nameletreload_configbus=OBus_method.callm_ReloadConfig(proxybus)()letget_idbus=OBus_method.callm_GetId(proxybus)()>|=OBus_uuid.of_stringletname_owner_changedbus=OBus_signal.makes_NameOwnerChanged(proxybus)letname_lostbus=OBus_signal.makes_NameLost(proxybus)letname_acquiredbus=OBus_signal.makes_NameAcquired(proxybus)letget_peerbusname=try%lwtlet%lwtunique_name=get_name_ownerbusnameinLwt.return(OBus_peer.makebusunique_name)withName_has_no_ownermsg->let%lwt_=start_service_by_namebusnameinlet%lwtunique_name=get_name_ownerbusnameinLwt.return(OBus_peer.makebusunique_name)letget_proxybusnamepath=let%lwtpeer=get_peerbusnameinLwt.return(OBus_proxy.makepeerpath)