static char* get_backtrace(unsigned show_nframes) { void* trace[32]; int n_frames; char **symbols, *e, *r; unsigned j, n, s; size_t a; pa_assert(show_nframes > 0); n_frames = backtrace(trace, PA_ELEMENTSOF(trace)); if (n_frames <= 0) return NULL; symbols = backtrace_symbols(trace, n_frames); if (!symbols) return NULL; s = skip_backtrace; n = PA_MIN((unsigned) n_frames, s + show_nframes); a = 4; for (j = s; j < n; j++) { if (j > s) a += 2; a += strlen(pa_path_get_filename(symbols[j])); } r = pa_xnew(char, a); strcpy(r, " ("); e = r + 2; for (j = s; j < n; j++) { const char *sym; if (j > s) { strcpy(e, "<<"); e += 2; } sym = pa_path_get_filename(symbols[j]); strcpy(e, sym); e += strlen(sym); } strcpy(e, ")"); free(symbols); return r; }
static int add_dbus_match(struct cmtspeech_dbus_conn *e, DBusConnection *dbusconn, char *match) { DBusError error; uint i; dbus_error_init(&error); for(i = 0; i < PA_ELEMENTSOF(e->dbus_match_rules) && e->dbus_match_rules[i] != NULL; i++); pa_return_val_if_fail (i < PA_ELEMENTSOF(e->dbus_match_rules), -1); dbus_bus_add_match(dbusconn, match, &error); if (dbus_error_is_set(&error)) { pa_log_error("Unable to add dbus match:\"%s\": %s: %s", match, error.name, error.message); return -1;; } e->dbus_match_rules[i] = pa_xstrdup(match); pa_log_debug("added dbus match \"%s\"", match); return 0; }
static void clear_dbus_matches(struct cmtspeech_dbus_conn *e, DBusConnection *dbusconn) { int i; for(i = PA_ELEMENTSOF(e->dbus_match_rules) - 1; i >= 0; i--) { if (e->dbus_match_rules[i] == NULL) continue; dbus_bus_remove_match(dbusconn, e->dbus_match_rules[i], NULL); pa_log_debug("removed dbus match \"%s\"", e->dbus_match_rules[i]); pa_xfree(e->dbus_match_rules[i]); e->dbus_match_rules[i] = NULL; } }
END_TEST START_TEST(int_test) { pa_json_object *o; unsigned int i; const char *ints_parse[] = { "1", "-1", "1234", "0" }; const int ints_compare[] = { 1, -1, 1234, 0 }; for (i = 0; i < PA_ELEMENTSOF(ints_parse); i++) { o = pa_json_parse(ints_parse[i]); fail_unless(o != NULL); fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_INT); fail_unless(pa_json_object_get_int(o) == ints_compare[i]); pa_json_object_free(o); } }
END_TEST START_TEST(double_test) { pa_json_object *o; unsigned int i; const char *doubles_parse[] = { "1.0", "-1.1", "1234e2", "1234e0", "0.1234", "-0.1234", "1234e-1", "1234.5e-1", "1234.5e+2", }; const double doubles_compare[] = { 1.0, -1.1, 123400.0, 1234.0, 0.1234, -0.1234, 123.4, 123.45, 123450.0, }; for (i = 0; i < PA_ELEMENTSOF(doubles_parse); i++) { o = pa_json_parse(doubles_parse[i]); fail_unless(o != NULL); fail_unless(pa_json_object_get_type(o) == PA_JSON_TYPE_DOUBLE); fail_unless(PA_DOUBLE_IS_EQUAL(pa_json_object_get_double(o), doubles_compare[i])); pa_json_object_free(o); } }
END_TEST START_TEST(bad_test) { unsigned int i; const char *bad_parse[] = { "\"" /* Quote not closed */, "123456789012345678901234567890" /* Overflow */, "0.123456789012345678901234567890" /* Overflow */, "1e123456789012345678901234567890" /* Overflow */, "1e" /* Bad number string */, "1." /* Bad number string */, "1.e3" /* Bad number string */, "-" /* Bad number string */, "{ \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { \"a\": { } } } } } } } } } } } } } } } } } } } } } }" /* Nested too deep */, "[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ { \"a\": \"b\" } ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]" /* Nested too deep */, "asdf" /* Unquoted string */, "{ a: true }" /* Unquoted key in object */, "\" \a\"" /* Alarm is not a valid character */ }; for (i = 0; i < PA_ELEMENTSOF(bad_parse); i++) { fail_unless(pa_json_parse(bad_parse[i]) == NULL); } }
static int context_autospawn(pa_context *c) { pid_t pid; int status, r; struct sigaction sa; pa_context_ref(c); if (sigaction(SIGCHLD, NULL, &sa) < 0) { pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); goto fail; } if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) { pa_log_debug("Process disabled waitpid(), cannot autospawn."); pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); goto fail; } pa_log_debug("Trying to autospawn..."); if (c->spawn_api.prefork) c->spawn_api.prefork(); if ((pid = fork()) < 0) { pa_log_error(_("fork(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); if (c->spawn_api.postfork) c->spawn_api.postfork(); goto fail; } else if (!pid) { /* Child */ const char *state = NULL; const char * argv[32]; unsigned n = 0; if (c->spawn_api.atfork) c->spawn_api.atfork(); /* We leave most of the cleaning up of the process environment * to the executable. We only clean up the file descriptors to * make sure the executable can actually be loaded * correctly. */ pa_close_all(-1); /* Setup argv */ argv[n++] = c->conf->daemon_binary; argv[n++] = "--start"; while (n < PA_ELEMENTSOF(argv)-1) { char *a; if (!(a = pa_split_spaces(c->conf->extra_arguments, &state))) break; argv[n++] = a; } argv[n++] = NULL; pa_assert(n <= PA_ELEMENTSOF(argv)); execv(argv[0], (char * const *) argv); _exit(1); } /* Parent */ if (c->spawn_api.postfork) c->spawn_api.postfork(); do { r = waitpid(pid, &status, 0); } while (r < 0 && errno == EINTR); if (r < 0) { if (errno != ESRCH) { pa_log(_("waitpid(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); goto fail; } /* hmm, something already reaped our child, so we assume * startup worked, even if we cannot know */ } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); goto fail; } pa_context_unref(c); return 0; fail: pa_context_unref(c); return -1; }
static int context_autospawn(pa_context *c) { pid_t pid; int status, r; struct sigaction sa; pa_context_ref(c); if (sigaction(SIGCHLD, NULL, &sa) < 0) { pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); goto fail; } #ifdef SA_NOCLDWAIT if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) { #else if (sa.sa_handler == SIG_IGN) { #endif pa_log_debug("Process disabled waitpid(), cannot autospawn."); pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); goto fail; } pa_log_debug("Trying to autospawn..."); if (c->spawn_api.prefork) c->spawn_api.prefork(); if ((pid = fork()) < 0) { pa_log_error(_("fork(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); if (c->spawn_api.postfork) c->spawn_api.postfork(); goto fail; } else if (!pid) { /* Child */ const char *state = NULL; const char * argv[32]; unsigned n = 0; if (c->spawn_api.atfork) c->spawn_api.atfork(); /* We leave most of the cleaning up of the process environment * to the executable. We only clean up the file descriptors to * make sure the executable can actually be loaded * correctly. */ pa_close_all(-1); /* Setup argv */ argv[n++] = c->conf->daemon_binary; argv[n++] = "--start"; while (n < PA_ELEMENTSOF(argv)-1) { char *a; if (!(a = pa_split_spaces(c->conf->extra_arguments, &state))) break; argv[n++] = a; } argv[n++] = NULL; pa_assert(n <= PA_ELEMENTSOF(argv)); execv(argv[0], (char * const *) argv); _exit(1); } /* Parent */ if (c->spawn_api.postfork) c->spawn_api.postfork(); do { r = waitpid(pid, &status, 0); } while (r < 0 && errno == EINTR); if (r < 0) { if (errno != ESRCH) { pa_log(_("waitpid(): %s"), pa_cstrerror(errno)); pa_context_fail(c, PA_ERR_INTERNAL); goto fail; } /* hmm, something already reaped our child, so we assume * startup worked, even if we cannot know */ } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); goto fail; } pa_context_unref(c); return 0; fail: pa_context_unref(c); return -1; } #endif /* OS_IS_WIN32 */ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata); #ifdef HAVE_DBUS static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wrap_connection **conn) { DBusError error; pa_assert(c); pa_assert(conn); dbus_error_init(&error); if (!(*conn = pa_dbus_wrap_connection_new(c->mainloop, c->use_rtclock, type, &error)) || dbus_error_is_set(&error)) { pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message); goto fail; } if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn), filter_cb, c, NULL)) { pa_log_warn("Failed to add filter function"); goto fail; } c->filter_added = true; if (pa_dbus_add_matches( pa_dbus_wrap_connection_get(*conn), &error, "type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL) < 0) { pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error.name, error.message); goto fail; } return; fail: if (*conn) { pa_dbus_wrap_connection_free(*conn); *conn = NULL; } dbus_error_free(&error); }
int main(int argc, char *argv[]) { pa_format_info *f1 = NULL, *f2 = NULL; int rates1[] = { 32000, 44100, 48000 }; const char *strings[] = { "thing1", "thing2", "thing3" }; /* 1. Simple fixed format int check */ INIT(f1); INIT(f2); f1->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int(f1, PA_PROP_FORMAT_RATE, 32000); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100); pa_assert(!pa_format_info_is_compatible(f1, f2)); /* 2. Check int array membership - positive */ REINIT(f1); REINIT(f2); f1->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int_array(f1, PA_PROP_FORMAT_RATE, rates1, PA_ELEMENTSOF(rates1)); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100); pa_assert(pa_format_info_is_compatible(f1, f2)); pa_assert(pa_format_info_is_compatible(f2, f1)); /* 3. Check int array memebership - negative */ REINIT(f2); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 96000); pa_assert(!pa_format_info_is_compatible(f1, f2)); pa_assert(!pa_format_info_is_compatible(f2, f1)); /* 4. Check int range - positive */ REINIT(f1); REINIT(f2); f1->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int_range(f1, PA_PROP_FORMAT_RATE, 32000, 48000); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100); pa_assert(pa_format_info_is_compatible(f1, f2)); pa_assert(pa_format_info_is_compatible(f2, f1)); /* 5. Check int range - negative */ REINIT(f2); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 96000); pa_assert(!pa_format_info_is_compatible(f1, f2)); pa_assert(!pa_format_info_is_compatible(f2, f1)); /* 6. Simple fixed format string check */ REINIT(f1); REINIT(f2); f1->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_string(f1, "format.test_string", "thing1"); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_string(f2, "format.test_string", "notthing1"); pa_assert(!pa_format_info_is_compatible(f1, f2)); /* 7. Check string array membership - positive */ REINIT(f1); REINIT(f2); f1->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_string_array(f1, "format.test_string", strings, PA_ELEMENTSOF(strings)); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_string(f2, "format.test_string", "thing3"); pa_assert(pa_format_info_is_compatible(f1, f2)); pa_assert(pa_format_info_is_compatible(f2, f1)); /* 8. Check string array memebership - negative */ REINIT(f2); f2->encoding = PA_ENCODING_AC3_IEC61937; pa_format_info_set_prop_string(f2, "format.test_string", "thing5"); pa_assert(!pa_format_info_is_compatible(f1, f2)); pa_assert(!pa_format_info_is_compatible(f2, f1)); DEINIT(f1); DEINIT(f2); return 0; }
int pa__init(pa_module*m) { pa_modargs *ma = NULL; char t[256], *vendor, *client_id; SmcCallbacks callbacks; SmProp prop_program, prop_user; SmProp *prop_list[2]; SmPropValue val_program, val_user; struct userdata *u; const char *e; pa_client_new_data data; pa_assert(m); if (ice_in_use) { pa_log("module-x11-xsmp may no be loaded twice."); return -1; } IceAddConnectionWatch(new_ice_connection, m->core); ice_in_use = TRUE; m->userdata = u = pa_xnew(struct userdata, 1); u->core = m->core; u->module = m; u->client = NULL; u->connection = NULL; u->x11 = NULL; if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; } if (!(u->x11 = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL)))) goto fail; e = pa_modargs_get_value(ma, "session_manager", NULL); if (!e && !getenv("SESSION_MANAGER")) { pa_log("X11 session manager not running."); goto fail; } memset(&callbacks, 0, sizeof(callbacks)); callbacks.die.callback = die_cb; callbacks.die.client_data = u; callbacks.save_yourself.callback = save_yourself_cb; callbacks.save_yourself.client_data = m->core; callbacks.save_complete.callback = save_complete_cb; callbacks.save_complete.client_data = m->core; callbacks.shutdown_cancelled.callback = shutdown_cancelled_cb; callbacks.shutdown_cancelled.client_data = m->core; if (!(u->connection = SmcOpenConnection( (char*) e, m->core, SmProtoMajor, SmProtoMinor, SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, &callbacks, NULL, &client_id, sizeof(t), t))) { pa_log("Failed to open connection to session manager: %s", t); goto fail; } prop_program.name = (char*) SmProgram; prop_program.type = (char*) SmARRAY8; val_program.value = (char*) PACKAGE_NAME; val_program.length = (int) strlen(val_program.value); prop_program.num_vals = 1; prop_program.vals = &val_program; prop_list[0] = &prop_program; prop_user.name = (char*) SmUserID; prop_user.type = (char*) SmARRAY8; pa_get_user_name(t, sizeof(t)); val_user.value = t; val_user.length = (int) strlen(val_user.value); prop_user.num_vals = 1; prop_user.vals = &val_user; prop_list[1] = &prop_user; SmcSetProperties(u->connection, PA_ELEMENTSOF(prop_list), prop_list); pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(u->connection), client_id); pa_client_new_data_init(&data); data.module = m; data.driver = __FILE__; pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "XSMP Session on %s as %s", vendor, client_id); pa_proplist_sets(data.proplist, "xsmp.vendor", vendor); pa_proplist_sets(data.proplist, "xsmp.client.id", client_id); u->client = pa_client_new(u->core, &data); pa_client_new_data_done(&data); free(vendor); free(client_id); if (!u->client) goto fail; pa_modargs_free(ma); return 0; fail: if (ma) pa_modargs_free(ma); pa__done(m); return -1; }