#define ENDSWITH_SET(p, ...) \
endswith_strv(p, STRV_MAKE(__VA_ARGS__))
-#define strv_from_stdarg_alloca(first) \
- ({ \
- char **_l; \
- \
- if (!first) \
- _l = (char**) &first; \
- else { \
- size_t _n; \
- va_list _ap; \
- \
- _n = 1; \
- va_start(_ap, first); \
- while (va_arg(_ap, char*)) \
- _n++; \
- va_end(_ap); \
- \
- _l = newa(char*, _n+1); \
- _l[_n = 0] = (char*) first; \
- va_start(_ap, first); \
- for (;;) { \
- _l[++_n] = va_arg(_ap, char*); \
- if (!_l[_n]) \
- break; \
- } \
- va_end(_ap); \
- } \
- _l; \
- })
-
#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
#define STRPTR_IN_SET(x, ...) \
({ \
const char *interface,
const char *name, ...) {
- char **names;
+ _cleanup_strv_free_ char **names = NULL;
assert_return(bus, -EINVAL);
assert_return(bus = bus_resolve(bus), -ENOPKG);
if (!name)
return 0;
- names = strv_from_stdarg_alloca(name);
+ va_list ap;
+
+ va_start(ap, name);
+ names = strv_new_ap(name, ap);
+ va_end(ap);
+
+ if (!names)
+ return -ENOMEM;
return sd_bus_emit_properties_changed_strv(bus, path, interface, names);
}
}
_public_ int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const char *interface, ...) {
- char **interfaces;
+ _cleanup_strv_free_ char **interfaces = NULL;
assert_return(bus, -EINVAL);
assert_return(bus = bus_resolve(bus), -ENOPKG);
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
- interfaces = strv_from_stdarg_alloca(interface);
+ va_list ap;
+
+ va_start(ap, interface);
+ interfaces = strv_new_ap(interface, ap);
+ va_end(ap);
+
+ if (!interfaces)
+ return -ENOMEM;
return sd_bus_emit_interfaces_added_strv(bus, path, interfaces);
}
}
_public_ int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *interface, ...) {
- char **interfaces;
+ _cleanup_strv_free_ char **interfaces = NULL;
assert_return(bus, -EINVAL);
assert_return(bus = bus_resolve(bus), -ENOPKG);
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
- interfaces = strv_from_stdarg_alloca(interface);
+ va_list ap;
+
+ va_start(ap, interface);
+ interfaces = strv_new_ap(interface, ap);
+ va_end(ap);
+
+ if (!interfaces)
+ return -ENOMEM;
return sd_bus_emit_interfaces_removed_strv(bus, path, interfaces);
}
b->lid_closed = true;
button_lid_switch_handle_action(b->manager, /* is_edge= */ true, b->seat);
button_install_check_event_source(b);
- manager_send_changed(b->manager, "LidClosed", NULL);
+ manager_send_changed(b->manager, "LidClosed");
} else if (ev.code == SW_DOCK) {
log_struct(LOG_INFO,
b->lid_closed = false;
b->check_event_source = sd_event_source_unref(b->check_event_source);
- manager_send_changed(b->manager, "LidClosed", NULL);
+ manager_send_changed(b->manager, "LidClosed");
} else if (ev.code == SW_DOCK) {
log_struct(LOG_INFO,
b->lid_closed = bitset_get(switches, SW_LID);
b->docked = bitset_get(switches, SW_DOCK);
- manager_send_changed(b->manager, "LidClosed", NULL);
+ manager_send_changed(b->manager, "LidClosed");
if (b->lid_closed)
button_install_check_event_source(b);
(void) unlink(SHUTDOWN_SCHEDULE_FILE);
- manager_send_changed(m, "ScheduledShutdown", NULL);
+ manager_send_changed(m, "ScheduledShutdown");
}
static int update_schedule_file(Manager *m) {
return r;
}
- manager_send_changed(m, "ScheduledShutdown", NULL);
+ manager_send_changed(m, "ScheduledShutdown");
return sd_bus_reply_method_return(message, NULL);
}
return 0;
}
-int manager_send_changed(Manager *manager, const char *property, ...) {
- char **l;
-
+int manager_send_changed_strv(Manager *manager, char **properties) {
assert(manager);
- l = strv_from_stdarg_alloca(property);
-
return sd_bus_emit_properties_changed_strv(
manager->bus,
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
- l);
+ properties);
}
int manager_start_scope(
int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
+int manager_send_changed_strv(Manager *manager, char **properties);
+#define manager_send_changed(manager, ...) manager_send_changed_strv(manager, STRV_MAKE(__VA_ARGS__))
int manager_start_scope(
Manager *manager,
if (!seat_has_master_device(s)) {
seat_add_to_gc_queue(s);
- seat_send_changed(s, "CanGraphical", NULL);
+ seat_send_changed(s, "CanGraphical");
}
}
if (!had_master && d->master && s->started) {
seat_save(s);
- seat_send_changed(s, "CanGraphical", NULL);
+ seat_send_changed(s, "CanGraphical");
}
}
property = IN_SET(i->mode, INHIBIT_BLOCK, INHIBIT_BLOCK_WEAK) ? "BlockInhibited" : "DelayInhibited";
- return manager_send_changed(i->manager, property, NULL);
+ return manager_send_changed(i->manager, property);
}
int inhibitor_start(Inhibitor *i) {
"so", s->id, p);
}
-int seat_send_changed(Seat *s, const char *properties, ...) {
+int seat_send_changed_strv(Seat *s, char **properties) {
_cleanup_free_ char *p = NULL;
- char **l;
assert(s);
if (!p)
return -ENOMEM;
- l = strv_from_stdarg_alloca(properties);
-
- return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Seat", l);
+ return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Seat", properties);
}
static const sd_bus_vtable seat_vtable[] = {
char* seat_bus_path(Seat *s);
int seat_send_signal(Seat *s, bool new_seat);
-int seat_send_changed(Seat *s, const char *properties, ...) _sentinel_;
+int seat_send_changed_strv(Seat *s, char **properties);
+#define seat_send_changed(s, ...) seat_send_changed_strv(s, STRV_MAKE(__VA_ARGS__))
int bus_seat_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
if (old_active) {
session_device_pause_all(old_active);
- session_send_changed(old_active, "Active", NULL);
+ session_send_changed(old_active, "Active");
}
(void) seat_apply_acls(s, old_active);
if (session && session->started) {
- session_send_changed(session, "Active", NULL);
+ session_send_changed(session, "Active");
session_device_resume_all(session);
}
if (!session || session->started)
- seat_send_changed(s, "ActiveSession", NULL);
+ seat_send_changed(s, "ActiveSession");
if (session) {
session_save(session);
"so", s->id, p);
}
-int session_send_changed(Session *s, const char *properties, ...) {
+int session_send_changed_strv(Session *s, char **properties) {
_cleanup_free_ char *p = NULL;
- char **l;
assert(s);
if (!p)
return -ENOMEM;
- l = strv_from_stdarg_alloca(properties);
-
- return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Session", l);
+ return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Session", properties);
}
int session_send_lock(Session *s, bool lock) {
char* session_bus_path(Session *s);
int session_send_signal(Session *s, bool new_session);
-int session_send_changed(Session *s, const char *properties, ...) _sentinel_;
+int session_send_changed_strv(Session *s, char **properties);
+#define session_send_changed(s, ...) session_send_changed_strv(s, STRV_MAKE(__VA_ARGS__))
int session_send_lock(Session *s, bool lock);
int session_send_lock_all(Manager *m, bool lock);
/* Send signals */
session_send_signal(s, true);
- user_send_changed(s->user, "Display", NULL);
+ user_send_changed(s->user, "Display");
if (s->seat && s->seat->active == s)
- (void) seat_send_changed(s->seat, "ActiveSession", NULL);
+ (void) seat_send_changed(s->seat, "ActiveSession");
return 0;
}
session_reset_leader(s, /* keep_fdstore = */ false);
(void) user_save(s->user);
- (void) user_send_changed(s->user, "Display", NULL);
+ (void) user_send_changed(s->user, "Display");
return 0;
}
s->idle_hint = b;
dual_timestamp_now(&s->idle_hint_timestamp);
- session_send_changed(s, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
+ session_send_changed(s, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic");
if (s->seat)
- seat_send_changed(s->seat, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
+ seat_send_changed(s->seat, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic");
- user_send_changed(s->user, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
- manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic", NULL);
+ user_send_changed(s->user, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic");
+ manager_send_changed(s->manager, "IdleHint", "IdleSinceHint", "IdleSinceHintMonotonic");
return 1;
}
s->locked_hint = b;
(void) session_save(s);
- (void) session_send_changed(s, "LockedHint", NULL);
+ (void) session_send_changed(s, "LockedHint");
return 1;
}
s->type = t;
(void) session_save(s);
- (void) session_send_changed(s, "Type", NULL);
+ (void) session_send_changed(s, "Type");
}
void session_set_class(Session *s, SessionClass c) {
s->class = c;
(void) session_save(s);
- (void) session_send_changed(s, "Class", NULL);
+ (void) session_send_changed(s, "Class");
/* This class change might mean we need the per-user session manager now. Try to start it. */
(void) user_start_service_manager(s->user);
return r;
(void) session_save(s);
- (void) session_send_changed(s, "Display", NULL);
+ (void) session_send_changed(s, "Display");
return 1;
}
return r;
(void) session_save(s);
- (void) session_send_changed(s, "TTY", NULL);
+ (void) session_send_changed(s, "TTY");
return 1;
}
"uo", (uint32_t) u->user_record->uid, p);
}
-int user_send_changed(User *u, const char *properties, ...) {
+int user_send_changed_strv(User *u, char **properties) {
_cleanup_free_ char *p = NULL;
- char **l;
assert(u);
if (!p)
return -ENOMEM;
- l = strv_from_stdarg_alloca(properties);
-
- return sd_bus_emit_properties_changed_strv(u->manager->bus, p, "org.freedesktop.login1.User", l);
+ return sd_bus_emit_properties_changed_strv(u->manager->bus, p, "org.freedesktop.login1.User", properties);
}
char* user_bus_path(User *s);
int user_send_signal(User *u, bool new_user);
-int user_send_changed(User *u, const char *properties, ...) _sentinel_;
+int user_send_changed_strv(User *u, char **properties);
+#define user_send_changed(u, ...) user_send_changed_strv(u, STRV_MAKE(__VA_ARGS__))
int bus_user_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);
return sd_bus_message_close_container(reply);
}
-static int dhcp_server_emit_changed(Link *link, const char *property, ...) {
+static int dhcp_server_emit_changed_strv(Link *link, char **properties) {
_cleanup_free_ char *path = NULL;
- char **l;
assert(link);
if (!path)
return log_oom();
- l = strv_from_stdarg_alloca(property);
-
return sd_bus_emit_properties_changed_strv(
link->manager->bus,
path,
"org.freedesktop.network1.DHCPServer",
- l);
+ properties);
}
void dhcp_server_callback(sd_dhcp_server *s, uint64_t event, void *data) {
Link *l = ASSERT_PTR(data);
if (event & SD_DHCP_SERVER_EVENT_LEASE_CHANGED)
- (void) dhcp_server_emit_changed(l, "Leases", NULL);
+ (void) dhcp_server_emit_changed_strv(l, STRV_MAKE("Leases"));
}
static const sd_bus_vtable dhcp_server_vtable[] = {
return sd_bus_message_append(reply, "s", dhcp_state_to_string(dhcp_client_get_state(c)));
}
-static int dhcp_client_emit_changed(Link *link, const char *property, ...) {
+static int dhcp_client_emit_changed(Link *link, char **properties) {
_cleanup_free_ char *path = NULL;
- char **l;
assert(link);
if (!path)
return log_oom();
- l = strv_from_stdarg_alloca(property);
-
return sd_bus_emit_properties_changed_strv(
link->manager->bus,
path,
"org.freedesktop.network1.DHCPv4Client",
- l);
+ properties);
}
int dhcp_client_callback_bus(sd_dhcp_client *c, int event, void *userdata) {
Link *l = ASSERT_PTR(userdata);
- return dhcp_client_emit_changed(l, "State", NULL);
+ return dhcp_client_emit_changed(l, STRV_MAKE("State"));
}
static const sd_bus_vtable dhcp_client_vtable[] = {
return sd_bus_message_append(reply, "s", dhcp6_state_to_string(dhcp6_client_get_state(c)));
}
-static int dhcp6_client_emit_changed(Link *link, const char *property, ...) {
+static int dhcp6_client_emit_changed_strv(Link *link, char **properties) {
_cleanup_free_ char *path = NULL;
- char **l;
assert(link);
if (!path)
return log_oom();
- l = strv_from_stdarg_alloca(property);
-
return sd_bus_emit_properties_changed_strv(
link->manager->bus,
path,
"org.freedesktop.network1.DHCPv6Client",
- l);
+ properties);
}
void dhcp6_client_callback_bus(sd_dhcp6_client *c, int event, void *userdata) {
Link *l = ASSERT_PTR(userdata);
- dhcp6_client_emit_changed(l, "State", NULL);
+ dhcp6_client_emit_changed_strv(l, STRV_MAKE("State"));
}
static const sd_bus_vtable dhcp6_client_vtable[] = {
properties);
}
-int link_send_changed(Link *link, const char *property, ...) {
- char **properties;
-
- properties = strv_from_stdarg_alloca(property);
-
- return link_send_changed_strv(link, properties);
-}
-
const BusObjectImplementation link_object = {
"/org/freedesktop/network1/link",
"org.freedesktop.network1.Link",
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
int link_send_changed_strv(Link *link, char **properties);
-int link_send_changed(Link *link, const char *property, ...) _sentinel_;
+#define link_send_changed(link, ...) link_send_changed_strv(link, STRV_MAKE(__VA_ARGS__));
int property_get_operational_state(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
int property_get_carrier_state(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
link->state = state;
- link_send_changed(link, "AdministrativeState", NULL);
+ link_send_changed(link, "AdministrativeState");
link_dirty(link);
}
return 0;
}
-int _manager_send_changed(Manager *manager, const char *property, ...) {
+int manager_send_changed_strv(Manager *manager, char **properties) {
assert(manager);
if (sd_bus_is_ready(manager->bus) <= 0)
return 0;
- char **l = strv_from_stdarg_alloca(property);
-
int r = sd_bus_emit_properties_changed_strv(
manager->bus,
"/org/freedesktop/resolve1",
"org.freedesktop.resolve1.Manager",
- l);
+ properties);
if (r < 0)
- log_notice_errno(r, "Failed to emit notification about changed property %s: %m", property);
+ log_notice_errno(r, "Failed to emit notification about changed properties: %m");
+
return r;
}
extern const BusObjectImplementation manager_object;
int manager_connect_bus(Manager *m);
-int _manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
-#define manager_send_changed(manager, ...) _manager_send_changed(manager, __VA_ARGS__, NULL)
+int manager_send_changed_strv(Manager *manager, char **properties);
+#define manager_send_changed(manager, ...) manager_send_changed_strv(manager, STRV_MAKE(__VA_ARGS__));
int bus_dns_server_append(sd_bus_message *reply, DnsServer *s, bool with_ifindex, bool extended);
int bus_property_get_resolve_support(sd_bus *bus, const char *path, const char *interface,
const char *property, sd_bus_message *reply,
return true;
}
-int _fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
+int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, pid_t *ret_pid) {
int r;
- assert(path);
+ assert(!strv_isempty(argv));
/* Spawns a temporary TTY agent, making sure it goes away when we go away */
}
/* Count arguments */
- char **l = strv_from_stdarg_alloca(path);
- execv(path, l);
- log_error_errno(errno, "Failed to execute %s: %m", path);
+ execv(argv[0], argv);
+ log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
_exit(EXIT_FAILURE);
}
int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]);
int shall_fork_agent(void);
-int _fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) _sentinel_;
-#define fork_agent(name, ...) _fork_agent(name, __VA_ARGS__, NULL)
+int _fork_agent(const char *name, char * const *argv, const int except[], size_t n_except, pid_t *ret_pid);
+#define fork_agent(name, except, n_except, ret_pid, ...) _fork_agent(name, STRV_MAKE(__VA_ARGS__), except, n_except, ret_pid)
ASSERT_STREQ(*x, *y);
}
-static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
- char **j;
- unsigned i;
-
- log_info("/* %s */", __func__);
-
- j = strv_from_stdarg_alloca(first);
-
- for (i = 0;; i++) {
- ASSERT_STREQ(l[i], j[i]);
-
- if (!l[i])
- break;
- }
-}
-
-TEST(strv_from_stdarg_alloca) {
- test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
- test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
- test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
-}
-
TEST(strv_insert) {
_cleanup_strv_free_ char **a = NULL;