2020-11-09 05:23:58 +01:00
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2013-10-16 06:10:04 +02:00
# pragma once
2015-12-03 21:13:37 +01:00
# include <stdbool.h>
# include <stddef.h>
# include <stdint.h>
# include <sys/types.h>
2013-10-16 06:10:04 +02:00
# include "sd-bus.h"
2015-10-24 22:58:24 +02:00
# include "sd-event.h"
2020-12-14 16:36:00 +01:00
# include "errno-util.h"
2015-12-03 21:13:37 +01:00
# include "macro.h"
2015-10-24 22:58:24 +02:00
# include "string-util.h"
2019-03-27 11:32:41 +01:00
# include "time-util.h"
2013-10-16 06:10:04 +02:00
2015-08-27 16:32:22 +02:00
typedef enum BusTransport {
BUS_TRANSPORT_LOCAL ,
BUS_TRANSPORT_REMOTE ,
BUS_TRANSPORT_MACHINE ,
_BUS_TRANSPORT_MAX ,
_BUS_TRANSPORT_INVALID = - 1
} BusTransport ;
2013-12-12 22:21:25 +01:00
int bus_async_unregister_and_exit ( sd_event * e , sd_bus * bus , const char * name ) ;
2013-10-16 06:10:04 +02:00
2013-12-19 21:14:52 +01:00
typedef bool ( * check_idle_t ) ( void * userdata ) ;
int bus_event_loop_with_idle ( sd_event * e , sd_bus * bus , const char * name , usec_t timeout , check_idle_t check_idle , void * userdata ) ;
2013-11-19 21:12:59 +01:00
2013-11-28 14:50:19 +01:00
int bus_name_has_owner ( sd_bus * c , const char * name , sd_bus_error * error ) ;
2020-08-22 18:48:03 +02:00
bool bus_error_is_unknown_service ( const sd_bus_error * error ) ;
2013-11-28 14:50:19 +01:00
2013-11-19 21:12:59 +01:00
int bus_check_peercred ( sd_bus * c ) ;
2013-10-16 06:10:04 +02:00
2015-09-24 13:30:10 +02:00
int bus_connect_system_systemd ( sd_bus * * _bus ) ;
int bus_connect_user_systemd ( sd_bus * * _bus ) ;
2013-08-12 14:19:22 +02:00
2015-09-24 13:30:10 +02:00
int bus_connect_transport ( BusTransport transport , const char * host , bool user , sd_bus * * bus ) ;
int bus_connect_transport_systemd ( BusTransport transport , const char * host , bool user , sd_bus * * bus ) ;
2013-10-30 16:44:55 +01:00
2020-10-14 12:15:58 +02:00
# define bus_log_address_error(r) \
2020-12-14 16:36:00 +01:00
( { \
int _k = ( r ) ; \
log_error_errno ( _k , \
_k = = - ENOMEDIUM ? " Failed to set bus address: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user) " : \
" Failed to set bus address: %m " ) ; \
} )
2020-10-14 12:15:58 +02:00
# define bus_log_connect_error(r) \
2020-12-14 16:36:00 +01:00
( { \
int _k = ( r ) ; \
log_error_errno ( _k , \
_k = = - ENOMEDIUM ? " Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user) " : \
ERRNO_IS_PRIVILEGE ( _k ) ? " Failed to connect to bus: Operation not permitted (consider using --machine=<user>@.host --user to connect to bus of other user) " : \
" Failed to connect to bus: %m " ) ; \
} )
2020-10-14 12:15:58 +02:00
# define bus_log_parse_error(r) \
2019-07-28 11:43:53 +02:00
log_error_errno ( r , " Failed to parse bus message: %m " )
2020-10-14 12:15:58 +02:00
# define bus_log_create_error(r) \
2019-07-28 11:43:53 +02:00
log_error_errno ( r , " Failed to create bus message: %m " )
2013-11-07 05:49:04 +01:00
bus: implement bus_path_{en,de}code_unique()
Whenever we provide a bus API that allows clients to create and manage
server-side objects, we need to provide a unique name for these objects.
There are two ways to provide them:
1) Let the server choose a name and return it as method reply.
2) Let the client pass its name of choice in the method arguments.
The first method is the easiest one to implement. However, it suffers from
a race condition: If a client creates an object asynchronously, it cannot
destroy that object until it received the method reply. It cannot know the
name of the new object, thus, it cannot destroy it. Furthermore, this
method enforces a round-trip. If the client _depends_ on the method call
to succeed (eg., it would close() the connection if it failed), the client
usually has no reason to wait for the method reply. Instead, the client
can immediately schedule further method calls on the newly created object
(in case the API guarantees in-order method-call handling).
The second method fixes both problems: The client passes an object name
with the method-call. The server uses it to create the object. Therefore,
the client can schedule object destruction even if the object-creation
hasn't finished, yet (again, requiring in-order method-call handling).
Furthermore, the client can schedule further method calls on the newly
created object, before the constructor returned.
There're two problems to solve, though:
1) Object names are usually defined via dbus object paths, which are
usually globally namespaced. Therefore, multiple clients must be able
to choose unique object names without interference.
2) If multiple libraries share the same bus connection, they must be
able to choose unique object names without interference.
The first problem is solved easily by prefixing a name with the
unique-bus-name of a connection. The server side must enforce this and
reject any other name.
The second problem is solved by providing unique suffixes from within
sd-bus. As long as sd-bus always returns a fresh new ID, if requested,
multiple libraries will never interfere. This implementation re-uses
bus->cookie as ID generator, which already provides unique IDs for each
bus connection.
This patch introduces two new helpers:
bus_path_encode_unique(sd_bus *bus,
const char *prefix,
const char *sender_id,
const char *external_id,
char **ret_path);
This creates a new object-path via the template
'/prefix/sender_id/external_id'. That is, it appends two new labels to
the given prefix. If 'sender_id' is NULL, it will use
bus->unique_name, if 'external_id' is NULL, it will allocate a fresh,
unique cookie from bus->cookie.
bus_path_decode_unique(const char *path,
const char *prefix,
char **ret_sender,
char **ret_external);
This reverses what bus_path_encode_unique() did. It parses 'path' from
the template '/prefix/sender/external' and returns both suffix-labels
in 'ret_sender' and 'ret_external'. In case the template does not
match, 0 is returned and both output arguments are set to NULL.
Otherwise, 1 is returned and the output arguments contain the decoded
labels.
Note: Client-side allocated IDs are inspired by the Wayland protocol
(which itself was inspired by X11). Wayland uses those IDs heavily
to avoid round-trips. Clients can create server-side objects and
send method calls without any round-trip and waiting for any object
IDs to be returned. But unlike Wayland, DBus uses gobally namespaced
object names. Therefore, we have to add the extra step by adding the
unique-name of the bus connection.
2015-04-10 17:44:30 +02:00
int bus_path_encode_unique ( sd_bus * b , const char * prefix , const char * sender_id , const char * external_id , char * * ret_path ) ;
int bus_path_decode_unique ( const char * path , const char * prefix , char * * ret_sender , char * * ret_external ) ;
2015-08-27 16:32:22 +02:00
2016-11-15 19:18:36 +01:00
int bus_track_add_name_many ( sd_bus_track * t , char * * l ) ;
2017-12-19 15:54:30 +01:00
2018-04-17 16:37:52 +02:00
int bus_open_system_watch_bind_with_description ( sd_bus * * ret , const char * description ) ;
static inline int bus_open_system_watch_bind ( sd_bus * * ret ) {
return bus_open_system_watch_bind_with_description ( ret , NULL ) ;
}
2018-05-19 18:55:39 +02:00
2018-04-09 19:44:21 +02:00
int bus_reply_pair_array ( sd_bus_message * m , char * * l ) ;
logind: add SetBrightness() bus call for setting brightness of leds/backlight devices associated with a seat
This augments the drm/input device management by adding a single method
call for setting the brightness of an "leds" or "backlight" kernel class
device.
This method call requires no privileges to call, but a caller can only
change the brightness on sessions that are currently active, and they
must own the session.
This does not do enumeration of such class devices, feature or range
probing, chnage notification; it doesn't help associating graphics or
input devices with their backlight or leds devices. For all that clients
should go directly to udev/sysfs. The SetBrightness() call is just for
executing the actual change operation, that is otherwise privileged.
Example line:
busctl call org.freedesktop.login1 /org/freedesktop/login1/session/self org.freedesktop.login1.Session SetBrightness ssu "backlight" "intel_backlight" 200
The parameter the SetBrightness() call takes are the kernel subsystem
(i.e. "leds" or "backlight"), the device name, and the brightness
value.
On some hw setting the brightness is slow, and implementation and write
access to the sysfs knobs exposes this slowness. Due to this we'll fork
off a writer process in the background so that logind doesn't have to
block. Moreover, write requestes are coalesced: when a write request is
enqueued while one is already being executed it is queued. When another
write reques is then enqueued the earlier one is replaced by the newer
one, so that only one queued write request per device remains at any
time. Method replies are sent as soon as the first write request that
happens after the request was received is completed.
It is recommended that bus clients turn off the "expect_reply" flag on
the dbus messages they send though, that relieves logind from sending
completion notification and is particularly a good idea if clients
implement reactive UI sliders that send a quick secession of write
requests.
Replaces: #12413
2019-04-28 11:07:56 +02:00
extern const struct hash_ops bus_message_hash_ops ;