static void signal_handler (int sig) { DBusString str; switch (sig) { #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX case SIGIO: /* explicit fall-through */ #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */ case SIGHUP: _dbus_string_init_const (&str, "foo"); if (!_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) { _dbus_warn ("Unable to write to reload pipe.\n"); exit (1); } break; case SIGTERM: _dbus_loop_quit (bus_context_get_loop (context)); break; } }
void bus_test_run_everything (BusContext *context) { while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) || (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE))) ; }
static void close_reload_pipe (DBusWatch **watch) { _dbus_loop_remove_watch (bus_context_get_loop (context), *watch); _dbus_watch_invalidate (*watch); _dbus_watch_unref (*watch); *watch = NULL; _dbus_close_socket (reload_pipe[RELOAD_READ_END], NULL); reload_pipe[RELOAD_READ_END] = -1; _dbus_close_socket (reload_pipe[RELOAD_WRITE_END], NULL); reload_pipe[RELOAD_WRITE_END] = -1; }
void bus_test_run_bus_loop (BusContext *context, dbus_bool_t block_once) { _dbus_verbose ("---> Dispatching on \"server side\"\n"); /* dispatch before we block so pending dispatches * won't make our block return early */ _dbus_loop_dispatch (bus_context_get_loop (context)); /* Do one blocking wait, since we're expecting data */ if (block_once) { _dbus_verbose ("---> blocking on \"server side\"\n"); _dbus_loop_iterate (bus_context_get_loop (context), TRUE); } /* Then mop everything up */ while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE)) ; _dbus_verbose ("---> Done dispatching on \"server side\"\n"); }
static int _init_kqueue (BusContext *context) { int ret = 0; if (kq < 0) { kq = kqueue (); if (kq < 0) { _dbus_warn ("Cannot create kqueue; error '%s'\n", _dbus_strerror (errno)); goto out; } loop = bus_context_get_loop (context); watch = _dbus_watch_new (kq, DBUS_WATCH_READABLE, TRUE, _handle_kqueue_watch, NULL, NULL); if (watch == NULL) { _dbus_warn ("Unable to create kqueue watch\n"); close (kq); kq = -1; goto out; } if (!_dbus_loop_add_watch (loop, watch)) { _dbus_warn ("Unable to add reload watch to main loop"); _dbus_watch_invalidate (watch); _dbus_watch_unref (watch); watch = NULL; close (kq); kq = -1; goto out; } } ret = 1; out: return ret; }
int main (int argc, char **argv) { DBusError error; DBusString config_file; DBusString address; DBusString addr_fd; DBusString pid_fd; const char *prev_arg; DBusPipe print_addr_pipe; DBusPipe print_pid_pipe; int i; dbus_bool_t print_address; dbus_bool_t print_pid; BusContextFlags flags; if (!_dbus_string_init (&config_file)) return 1; if (!_dbus_string_init (&address)) return 1; if (!_dbus_string_init (&addr_fd)) return 1; if (!_dbus_string_init (&pid_fd)) return 1; print_address = FALSE; print_pid = FALSE; flags = BUS_CONTEXT_FLAG_WRITE_PID_FILE; prev_arg = NULL; i = 1; while (i < argc) { const char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-h") == 0 || strcmp (arg, "-?") == 0) { usage (); } else if (strcmp (arg, "--version") == 0) { version (); } else if (strcmp (arg, "--introspect") == 0) { introspect (); } else if (strcmp (arg, "--nofork") == 0) { flags &= ~BUS_CONTEXT_FLAG_FORK_ALWAYS; flags |= BUS_CONTEXT_FLAG_FORK_NEVER; } #ifdef DBUS_UNIX else if (strcmp (arg, "--fork") == 0) { flags &= ~BUS_CONTEXT_FLAG_FORK_NEVER; flags |= BUS_CONTEXT_FLAG_FORK_ALWAYS; } else if (strcmp (arg, "--systemd-activation") == 0) { flags |= BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION; } #endif else if (strcmp (arg, "--nopidfile") == 0) { flags &= ~BUS_CONTEXT_FLAG_WRITE_PID_FILE; } else if (strcmp (arg, "--system") == 0) { check_two_config_files (&config_file, "system"); if (!_dbus_append_system_config_file (&config_file)) exit (1); } else if (strcmp (arg, "--session") == 0) { check_two_config_files (&config_file, "session"); if (!_dbus_append_session_config_file (&config_file)) exit (1); } else if (strstr (arg, "--config-file=") == arg) { const char *file; check_two_config_files (&config_file, "config-file"); file = strchr (arg, '='); ++file; if (!_dbus_string_append (&config_file, file)) exit (1); } else if (prev_arg && strcmp (prev_arg, "--config-file") == 0) { check_two_config_files (&config_file, "config-file"); if (!_dbus_string_append (&config_file, arg)) exit (1); } else if (strcmp (arg, "--config-file") == 0) { /* wait for next arg */ } else if (strstr (arg, "--address=") == arg) { const char *file; check_two_addresses (&address, "address"); file = strchr (arg, '='); ++file; if (!_dbus_string_append (&address, file)) exit (1); } else if (prev_arg && strcmp (prev_arg, "--address") == 0) { check_two_addresses (&address, "address"); if (!_dbus_string_append (&address, arg)) exit (1); } else if (strcmp (arg, "--address") == 0) { /* wait for next arg */ } else if (strstr (arg, "--print-address=") == arg) { const char *desc; check_two_addr_descriptors (&addr_fd, "print-address"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&addr_fd, desc)) exit (1); print_address = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-address") == 0) { check_two_addr_descriptors (&addr_fd, "print-address"); if (!_dbus_string_append (&addr_fd, arg)) exit (1); print_address = TRUE; } else if (strcmp (arg, "--print-address") == 0) { print_address = TRUE; /* and we'll get the next arg if appropriate */ } else if (strstr (arg, "--print-pid=") == arg) { const char *desc; check_two_pid_descriptors (&pid_fd, "print-pid"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&pid_fd, desc)) exit (1); print_pid = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-pid") == 0) { check_two_pid_descriptors (&pid_fd, "print-pid"); if (!_dbus_string_append (&pid_fd, arg)) exit (1); print_pid = TRUE; } else if (strcmp (arg, "--print-pid") == 0) { print_pid = TRUE; /* and we'll get the next arg if appropriate */ } else { usage (); } prev_arg = arg; ++i; } if (_dbus_string_get_length (&config_file) == 0) { fprintf (stderr, "No configuration file specified.\n"); usage (); } _dbus_pipe_invalidate (&print_addr_pipe); if (print_address) { _dbus_pipe_init_stdout (&print_addr_pipe); if (_dbus_string_get_length (&addr_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) || end != _dbus_string_get_length (&addr_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&addr_fd)); exit (1); } _dbus_pipe_init (&print_addr_pipe, val); } } _dbus_string_free (&addr_fd); _dbus_pipe_invalidate (&print_pid_pipe); if (print_pid) { _dbus_pipe_init_stdout (&print_pid_pipe); if (_dbus_string_get_length (&pid_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) || end != _dbus_string_get_length (&pid_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&pid_fd)); exit (1); } _dbus_pipe_init (&print_pid_pipe, val); } } _dbus_string_free (&pid_fd); if (!bus_selinux_pre_init ()) { _dbus_warn ("SELinux pre-initialization failed\n"); exit (1); } dbus_error_init (&error); context = bus_context_new (&config_file, flags, &print_addr_pipe, &print_pid_pipe, _dbus_string_get_length(&address) > 0 ? &address : NULL, &error); _dbus_string_free (&config_file); if (context == NULL) { _dbus_warn ("Failed to start message bus: %s\n", error.message); dbus_error_free (&error); exit (1); } /* bus_context_new() closes the print_addr_pipe and * print_pid_pipe */ #ifdef DBUS_UNIX setup_reload_pipe (bus_context_get_loop (context)); /* POSIX signals are Unix-specific, and _dbus_set_signal_handler is * unimplemented (and probably unimplementable) on Windows, so there's * no point in trying to make the handler portable to non-Unix. */ _dbus_set_signal_handler (SIGTERM, signal_handler); _dbus_set_signal_handler (SIGHUP, signal_handler); #endif /* DBUS_UNIX */ _dbus_verbose ("We are on D-Bus...\n"); _dbus_loop_run (bus_context_get_loop (context)); bus_context_shutdown (context); bus_context_unref (context); bus_selinux_shutdown (); return 0; }
static dbus_bool_t handle_reload_watch (DBusWatch *watch, unsigned int flags, void *data) { DBusError error; DBusString str; char *action_str; char action = '\0'; while (!_dbus_string_init (&str)) _dbus_wait_for_memory (); if ((reload_pipe[RELOAD_READ_END] > 0) && _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1) { _dbus_warn ("Couldn't read from reload pipe.\n"); close_reload_pipe (&watch); return TRUE; } action_str = _dbus_string_get_data (&str); if (action_str != NULL) { action = action_str[0]; } _dbus_string_free (&str); /* this can only fail if we don't understand the config file * or OOM. Either way we should just stick with the currently * loaded config. */ dbus_error_init (&error); switch (action) { case ACTION_RELOAD: if (! bus_context_reload_config (context, &error)) { _DBUS_ASSERT_ERROR_IS_SET (&error); _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) || dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)); _dbus_warn ("Unable to reload configuration: %s\n", error.message); dbus_error_free (&error); } break; case ACTION_QUIT: { DBusLoop *loop; /* * On OSs without abstract sockets, we want to quit * gracefully rather than being killed by SIGTERM, * so that DBusServer gets a chance to clean up the * sockets from the filesystem. fd.o #38656 */ loop = bus_context_get_loop (context); if (loop != NULL) { _dbus_loop_quit (loop); } } break; default: break; } return TRUE; }
static int _init_kqueue (BusContext *context) { if (kq < 0) { kq = kqueue (); if (kq < 0) { _dbus_warn ("Cannot create kqueue; error '%s'\n", _dbus_strerror (errno)); goto out; } loop = bus_context_get_loop (context); _dbus_loop_ref (loop); watch = _dbus_watch_new (kq, DBUS_WATCH_READABLE, TRUE, _handle_kqueue_watch, NULL, NULL); if (watch == NULL) { _dbus_warn ("Unable to create kqueue watch\n"); goto out1; } if (!_dbus_loop_add_watch (loop, watch)) { _dbus_warn ("Unable to add reload watch to main loop"); goto out2; } if (!_dbus_register_shutdown_func (_shutdown_kqueue, NULL)) { _dbus_warn ("Unable to register shutdown function"); goto out3; } } return 1; out3: _dbus_loop_remove_watch (loop, watch); out2: if (watch) { _dbus_watch_invalidate (watch); _dbus_watch_unref (watch); watch = NULL; } out1: if (kq >= 0) { close (kq); kq = -1; } if (loop) { _dbus_loop_unref (loop); loop = NULL; } out: return 0; }
int main (int argc, char **argv) { DBusError error; DBusString config_file; DBusString addr_fd; DBusString pid_fd; const char *prev_arg; int print_addr_fd; int print_pid_fd; int i; dbus_bool_t print_address; dbus_bool_t print_pid; int force_fork; if (!_dbus_string_init (&config_file)) return 1; if (!_dbus_string_init (&addr_fd)) return 1; if (!_dbus_string_init (&pid_fd)) return 1; print_address = FALSE; print_pid = FALSE; force_fork = FORK_FOLLOW_CONFIG_FILE; prev_arg = NULL; i = 1; while (i < argc) { const char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-h") == 0 || strcmp (arg, "-?") == 0) usage (); else if (strcmp (arg, "--version") == 0) version (); else if (strcmp (arg, "--introspect") == 0) introspect (); else if (strcmp (arg, "--nofork") == 0) force_fork = FORK_NEVER; else if (strcmp (arg, "--fork") == 0) force_fork = FORK_ALWAYS; else if (strcmp (arg, "--system") == 0) { check_two_config_files (&config_file, "system"); if (!_dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE)) exit (1); } else if (strcmp (arg, "--session") == 0) { check_two_config_files (&config_file, "session"); if (!_dbus_string_append (&config_file, DBUS_SESSION_CONFIG_FILE)) exit (1); } else if (strstr (arg, "--config-file=") == arg) { const char *file; check_two_config_files (&config_file, "config-file"); file = strchr (arg, '='); ++file; if (!_dbus_string_append (&config_file, file)) exit (1); } else if (prev_arg && strcmp (prev_arg, "--config-file") == 0) { check_two_config_files (&config_file, "config-file"); if (!_dbus_string_append (&config_file, arg)) exit (1); } else if (strcmp (arg, "--config-file") == 0) ; /* wait for next arg */ else if (strstr (arg, "--print-address=") == arg) { const char *desc; check_two_addr_descriptors (&addr_fd, "print-address"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&addr_fd, desc)) exit (1); print_address = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-address") == 0) { check_two_addr_descriptors (&addr_fd, "print-address"); if (!_dbus_string_append (&addr_fd, arg)) exit (1); print_address = TRUE; } else if (strcmp (arg, "--print-address") == 0) print_address = TRUE; /* and we'll get the next arg if appropriate */ else if (strstr (arg, "--print-pid=") == arg) { const char *desc; check_two_pid_descriptors (&pid_fd, "print-pid"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&pid_fd, desc)) exit (1); print_pid = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-pid") == 0) { check_two_pid_descriptors (&pid_fd, "print-pid"); if (!_dbus_string_append (&pid_fd, arg)) exit (1); print_pid = TRUE; } else if (strcmp (arg, "--print-pid") == 0) print_pid = TRUE; /* and we'll get the next arg if appropriate */ else usage (); prev_arg = arg; ++i; } if (_dbus_string_get_length (&config_file) == 0) { fprintf (stderr, "No configuration file specified.\n"); usage (); } print_addr_fd = -1; if (print_address) { print_addr_fd = 1; /* stdout */ if (_dbus_string_get_length (&addr_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) || end != _dbus_string_get_length (&addr_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&addr_fd)); exit (1); } print_addr_fd = val; } } _dbus_string_free (&addr_fd); print_pid_fd = -1; if (print_pid) { print_pid_fd = 1; /* stdout */ if (_dbus_string_get_length (&pid_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) || end != _dbus_string_get_length (&pid_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&pid_fd)); exit (1); } print_pid_fd = val; } } _dbus_string_free (&pid_fd); if (!bus_selinux_pre_init ()) { _dbus_warn ("SELinux pre-initialization failed\n"); exit (1); } dbus_error_init (&error); context = bus_context_new (&config_file, force_fork, print_addr_fd, print_pid_fd, &error); _dbus_string_free (&config_file); if (context == NULL) { _dbus_warn ("Failed to start message bus: %s\n", error.message); dbus_error_free (&error); exit (1); } setup_reload_pipe (bus_context_get_loop (context)); _dbus_set_signal_handler (SIGHUP, signal_handler); _dbus_set_signal_handler (SIGTERM, signal_handler); #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX _dbus_set_signal_handler (SIGIO, signal_handler); #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */ _dbus_verbose ("We are on D-Bus...\n"); _dbus_loop_run (bus_context_get_loop (context)); bus_context_shutdown (context); bus_context_unref (context); bus_selinux_shutdown (); return 0; }