From 37d930ac4afa9642b7b918b60ca0e0cb42b50682 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 10 Aug 2004 13:00:12 +0000 Subject: glib mainloop fix implement server status command support for sink_list/source_list in polyplib git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@110 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/Makefile.am | 4 +- polyp/clitext.c | 4 +- polyp/glib-mainloop.c | 12 ++- polyp/native-common.h | 2 + polyp/polypaudio.pa | 7 +- polyp/polyplib-error.h | 8 ++ polyp/polyplib.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++- polyp/polyplib.h | 26 +++++-- polyp/protocol-native.c | 35 ++++++++- polyp/sink.c | 1 + polyp/tagstruct.c | 4 +- polyp/util.c | 47 +++++++++++- polyp/util.h | 3 + 13 files changed, 319 insertions(+), 29 deletions(-) diff --git a/polyp/Makefile.am b/polyp/Makefile.am index b1c911a4..8206bcf6 100644 --- a/polyp/Makefile.am +++ b/polyp/Makefile.am @@ -18,8 +18,8 @@ # USA. AM_CFLAGS=-ansi -D_GNU_SOURCE -DDLSEARCHDIR=\"$(pkglibdir)\" -I$(srcdir)/.. -AM_LDADD=-L. -AM_LIBADD=-L. +AM_LDADD=-L. -lpthread +AM_LIBADD=-L. -lpthread polypincludedir=$(includedir)/polyp diff --git a/polyp/clitext.c b/polyp/clitext.c index 6d2d6253..a530238f 100644 --- a/polyp/clitext.c +++ b/polyp/clitext.c @@ -94,7 +94,7 @@ char *pa_sink_list_to_string(struct pa_core *c) { pa_strbuf_printf( s, " %c index: %u\n\tname: <%s>\n\tvolume: <0x%04x>\n\tlatency: <%u usec>\n\tmonitor_source: <%u>\n\tsample_spec: <%s>\n", - !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', + c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', sink->index, sink->name, (unsigned) sink->volume, pa_sink_get_latency(sink), @@ -125,7 +125,7 @@ char *pa_source_list_to_string(struct pa_core *c) { char ss[PA_SAMPLE_SNPRINT_MAX_LENGTH]; pa_sample_snprint(ss, sizeof(ss), &source->sample_spec); pa_strbuf_printf(s, " %c index: %u\n\tname: <%s>\n\tsample_spec: <%s>\n", - !strcmp(source->name, c->default_source_name) ? '*' : ' ', + c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ', source->index, source->name, ss); diff --git a/polyp/glib-mainloop.c b/polyp/glib-mainloop.c index 0c46ab0c..9abb1e47 100644 --- a/polyp/glib-mainloop.c +++ b/polyp/glib-mainloop.c @@ -213,7 +213,7 @@ static gboolean time_cb(gpointer data) { static void glib_time_restart(struct pa_time_event*e, const struct timeval *tv) { struct timeval now; - assert(e && e->mainloop); + assert(e && e->mainloop && !e->dead); gettimeofday(&now, NULL); if (e->source) { @@ -233,7 +233,7 @@ static void glib_time_restart(struct pa_time_event*e, const struct timeval *tv) } static void glib_time_free(struct pa_time_event *e) { - assert(e && e->mainloop); + assert(e && e->mainloop && !e->dead); if (e->source) { g_source_destroy(e->source); @@ -317,8 +317,8 @@ static void glib_defer_enable(struct pa_defer_event *e, int b) { } static void glib_defer_free(struct pa_defer_event *e) { - assert(e && e->mainloop); - + assert(e && e->mainloop && !e->dead); + if (e->source) { g_source_destroy(e->source); g_source_unref(e->source); @@ -486,6 +486,10 @@ static gboolean free_dead_events(gpointer p) { free_defer_events(g->dead_defer_events); free_time_events(g->dead_time_events); + g->dead_io_events = NULL; + g->dead_defer_events = NULL; + g->dead_time_events = NULL; + g_source_destroy(g->cleanup_source); g_source_unref(g->cleanup_source); g->cleanup_source = NULL; diff --git a/polyp/native-common.h b/polyp/native-common.h index d8a2a5ab..4a74ac44 100644 --- a/polyp/native-common.h +++ b/polyp/native-common.h @@ -47,6 +47,8 @@ enum { PA_COMMAND_FINISH_UPLOAD_STREAM, PA_COMMAND_PLAY_SAMPLE, PA_COMMAND_REMOVE_SAMPLE, + + PA_COMMAND_GET_SERVER_INFO, PA_COMMAND_GET_SINK_INFO, PA_COMMAND_GET_SINK_INFO_LIST, diff --git a/polyp/polypaudio.pa b/polyp/polypaudio.pa index 71513565..8da20c62 100755 --- a/polyp/polypaudio.pa +++ b/polyp/polypaudio.pa @@ -23,14 +23,15 @@ #load module-alsa-sink #load module-alsa-source device=plughw:1,0 #load module-oss device="/dev/dsp" sink_name=output source_name=input -#load module-oss-mmap device="/dev/dsp" +load module-oss-mmap device="/dev/dsp" sink_name=output source_name=input +load module-pipe-sink # Load audio drivers automatically on access #autoload_sink_add output module-oss device="/dev/dsp" sink_name=output source_name=input #autoload_source_add input module-oss device="/dev/dsp" sink_name=output source_name=input -autoload_sink_add output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input -autoload_source_add input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input +#autoload_sink_add output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input +#autoload_source_add input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input #autoload_sink_add output module-alsa-sink sink_name=output #autoload_source_add input module-alsa-source source_name=input diff --git a/polyp/polyplib-error.h b/polyp/polyplib-error.h index cb86864a..d76ce6ff 100644 --- a/polyp/polyplib-error.h +++ b/polyp/polyplib-error.h @@ -24,6 +24,14 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + const char* pa_strerror(uint32_t error); +#ifdef __cplusplus +} +#endif + #endif diff --git a/polyp/polyplib.c b/polyp/polyplib.c index 4d87fdb5..e14f8cf9 100644 --- a/polyp/polyplib.c +++ b/polyp/polyplib.c @@ -88,7 +88,16 @@ struct pa_context { void (*remove_sample_callback)(struct pa_context*c, int success, void *userdata); void *remove_sample_userdata; - + + void (*get_server_info_callback)(struct pa_context*c, const struct pa_server_info* i, void *userdata); + void *get_server_info_userdata; + + void (*get_sink_info_callback)(struct pa_context*c, const struct pa_sink_info* i, int is_last, void *userdata); + void *get_sink_info_userdata; + + void (*get_source_info_callback)(struct pa_context*c, const struct pa_source_info* i, int is_last, void *userdata); + void *get_source_info_userdata; + uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH]; }; @@ -182,6 +191,15 @@ struct pa_context *pa_context_new(struct pa_mainloop_api *mainloop, const char * c->remove_sample_callback = NULL; c->remove_sample_userdata = NULL; + c->get_server_info_callback = NULL; + c->get_server_info_userdata = NULL; + + c->get_sink_info_callback = NULL; + c->get_sink_info_userdata = NULL; + + c->get_source_info_callback = NULL; + c->get_source_info_userdata = NULL; + pa_check_for_sigpipe(); return c; } @@ -1055,12 +1073,12 @@ void pa_context_play_sample(struct pa_context *c, const char *name, const char * uint32_t tag; assert(c && name && *name && (!dev || *dev)); - if (!volume) - return; - c->play_sample_callback = cb; c->play_sample_userdata = userdata; + if (!cb) + return; + t = pa_tagstruct_new(NULL, 0); assert(t); pa_tagstruct_putu32(t, PA_COMMAND_PLAY_SAMPLE); @@ -1106,6 +1124,9 @@ void pa_context_remove_sample(struct pa_context *c, const char *name, void (*cb) c->remove_sample_callback = cb; c->remove_sample_userdata = userdata; + if (!cb) + return; + t = pa_tagstruct_new(NULL, 0); assert(t); pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_SAMPLE); @@ -1114,3 +1135,169 @@ void pa_context_remove_sample(struct pa_context *c, const char *name, void (*cb) pa_pstream_send_tagstruct(c->pstream, t); pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_remove_sample_callback, c); } + +static void context_get_server_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { + struct pa_context *c = userdata; + struct pa_server_info i; + assert(pd && c); + + if (command != PA_COMMAND_REPLY) { + if (handle_error(c, command, t) < 0) { + context_dead(c); + return; + } + + if (c->get_server_info_callback) + c->get_server_info_callback(c, NULL, c->get_server_info_userdata); + return; + } + + if (pa_tagstruct_gets(t, &i.server_name) < 0 || + pa_tagstruct_gets(t, &i.server_version) < 0 || + pa_tagstruct_gets(t, &i.user_name) < 0 || + pa_tagstruct_gets(t, &i.host_name) < 0 || + pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 || + !pa_tagstruct_eof(t)) { + c->error = PA_ERROR_PROTOCOL; + context_dead(c); + return; + } + + if (c->get_server_info_callback) + c->get_server_info_callback(c, &i, c->get_server_info_userdata); +} + +void pa_context_get_server_info(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_server_info*i, void *userdata), void *userdata) { + struct pa_tagstruct *t; + uint32_t tag; + assert(c); + + c->get_server_info_callback = cb; + c->get_server_info_userdata = userdata; + + if (!cb) + return; + + t = pa_tagstruct_new(NULL, 0); + assert(t); + pa_tagstruct_putu32(t, PA_COMMAND_GET_SERVER_INFO); + pa_tagstruct_putu32(t, tag = c->ctag++); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_server_info_callback, c); +} + +static void context_get_sink_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { + struct pa_context *c = userdata; + assert(pd && c); + + if (command != PA_COMMAND_REPLY) { + if (handle_error(c, command, t) < 0) { + context_dead(c); + return; + } + + if (c->get_sink_info_callback) + c->get_sink_info_callback(c, NULL, 0, c->get_sink_info_userdata); + return; + } + + while (!pa_tagstruct_eof(t)) { + struct pa_sink_info i; + + if (pa_tagstruct_getu32(t, &i.index) < 0 || + pa_tagstruct_gets(t, &i.name) < 0 || + pa_tagstruct_gets(t, &i.description) < 0 || + pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 || + pa_tagstruct_getu32(t, &i.owner_module) < 0 || + pa_tagstruct_getu32(t, &i.volume) < 0 || + pa_tagstruct_getu32(t, &i.monitor_source) < 0 || + pa_tagstruct_gets(t, &i.monitor_source_name) < 0 || + pa_tagstruct_getu32(t, &i.latency) < 0) { + c->error = PA_ERROR_PROTOCOL; + context_dead(c); + return; + } + + if (c->get_sink_info_callback) + c->get_sink_info_callback(c, &i, 0, c->get_sink_info_userdata); + } + + if (c->get_sink_info_callback) + c->get_sink_info_callback(c, NULL, 1, c->get_sink_info_userdata); +} + +void pa_context_get_sink_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, int is_last, void *userdata), void *userdata) { + struct pa_tagstruct *t; + uint32_t tag; + assert(c); + + c->get_sink_info_callback = cb; + c->get_sink_info_userdata = userdata; + + if (!cb) + return; + + t = pa_tagstruct_new(NULL, 0); + assert(t); + pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO_LIST); + pa_tagstruct_putu32(t, tag = c->ctag++); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, c); +} + +static void context_get_source_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { + struct pa_context *c = userdata; + assert(pd && c); + + if (command != PA_COMMAND_REPLY) { + if (handle_error(c, command, t) < 0) { + context_dead(c); + return; + } + + if (c->get_source_info_callback) + c->get_source_info_callback(c, NULL, 0, c->get_source_info_userdata); + return; + } + + while (!pa_tagstruct_eof(t)) { + struct pa_source_info i; + + if (pa_tagstruct_getu32(t, &i.index) < 0 || + pa_tagstruct_gets(t, &i.name) < 0 || + pa_tagstruct_gets(t, &i.description) < 0 || + pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 || + pa_tagstruct_getu32(t, &i.owner_module) < 0 || + pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 || + pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0) { + c->error = PA_ERROR_PROTOCOL; + context_dead(c); + return; + } + + if (c->get_source_info_callback) + c->get_source_info_callback(c, &i, 0, c->get_source_info_userdata); + } + + if (c->get_source_info_callback) + c->get_source_info_callback(c, NULL, 1, c->get_source_info_userdata); +} + +void pa_context_get_source_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata) { + struct pa_tagstruct *t; + uint32_t tag; + assert(c); + + c->get_source_info_callback = cb; + c->get_source_info_userdata = userdata; + + if (!cb) + return; + + t = pa_tagstruct_new(NULL, 0); + assert(t); + pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO_LIST); + pa_tagstruct_putu32(t, tag = c->ctag++); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, c); +} diff --git a/polyp/polyplib.h b/polyp/polyplib.h index 9741fc93..cc1251e2 100644 --- a/polyp/polyplib.h +++ b/polyp/polyplib.h @@ -105,7 +105,7 @@ struct pa_sink_info { const char *name; uint32_t index; const char *description; - struct pa_sample_spec *sample_spec; + struct pa_sample_spec sample_spec; uint32_t owner_module; uint32_t volume; uint32_t monitor_source; @@ -113,24 +113,34 @@ struct pa_sink_info { uint32_t latency; }; -void pa_context_get_sink_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, void *userdata), void *userdata); -void pa_context_get_sink_info_by_id(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, void *userdata), void *userdata); -void pa_context_get_sink_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, void *userdata), void *userdata); +void pa_context_get_sink_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, int is_last, void *userdata), void *userdata); +void pa_context_get_sink_info_by_id(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, int is_last, void *userdata), void *userdata); +void pa_context_get_sink_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, int is_last, void *userdata), void *userdata); struct pa_source_info { const char *name; uint32_t index; const char *description; - struct pa_sample_spec *sample_spec; + struct pa_sample_spec sample_spec; uint32_t owner_module; uint32_t monitor_of_sink; const char *monitor_of_sink_name; }; -void pa_context_get_source_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_source_info *i, void *userdata), void *userdata); -void pa_context_get_source_info_by_id(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_source_info *i, void *userdata), void *userdata); -void pa_context_get_source_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_source_info *i, void *userdata), void *userdata); +void pa_context_get_source_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata); +void pa_context_get_source_info_by_id(struct pa_context *c, uint32_t id, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata); +void pa_context_get_source_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata); +struct pa_server_info { + const char *user_name; + const char *host_name; + const char *server_version; + const char *server_name; + struct pa_sample_spec sample_spec; +}; + +void pa_context_get_server_info(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_server_info*i, void *userdata), void *userdata); + #ifdef __cplusplus } #endif diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index 778677b3..abe6c8b7 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -42,6 +42,7 @@ #include "namereg.h" #include "scache.h" #include "xmalloc.h" +#include "util.h" struct connection; struct pa_protocol_native; @@ -129,6 +130,7 @@ static void command_play_sample(struct pa_pdispatch *pd, uint32_t command, uint3 static void command_remove_sample(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata); static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata); static void command_get_info_list(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata); +static void command_get_server_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata); static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = { [PA_COMMAND_ERROR] = { NULL }, @@ -156,6 +158,7 @@ static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = { [PA_COMMAND_GET_SOURCE_INFO] = { command_get_info }, [PA_COMMAND_GET_SINK_INFO_LIST] = { command_get_info_list }, [PA_COMMAND_GET_SOURCE_INFO_LIST] = { command_get_info_list }, + [PA_COMMAND_GET_SERVER_INFO] = { command_get_server_info }, }; /* structure management */ @@ -933,7 +936,7 @@ static void sink_fill_tagstruct(struct pa_tagstruct *t, struct pa_sink *sink) { assert(t && sink); pa_tagstruct_putu32(t, sink->index); pa_tagstruct_puts(t, sink->name); - pa_tagstruct_puts(t, sink->description); + pa_tagstruct_puts(t, sink->description ? sink->description : ""); pa_tagstruct_put_sample_spec(t, &sink->sample_spec); pa_tagstruct_putu32(t, sink->owner ? sink->owner->index : (uint32_t) -1); pa_tagstruct_putu32(t, sink->volume); @@ -946,7 +949,7 @@ static void source_fill_tagstruct(struct pa_tagstruct *t, struct pa_source *sour assert(t && source); pa_tagstruct_putu32(t, source->index); pa_tagstruct_puts(t, source->name); - pa_tagstruct_puts(t, source->description); + pa_tagstruct_puts(t, source->description ? source->description : ""); pa_tagstruct_put_sample_spec(t, &source->sample_spec); pa_tagstruct_putu32(t, source->owner ? source->owner->index : (uint32_t) -1); pa_tagstruct_putu32(t, source->monitor_of ? source->monitor_of->index : (uint32_t) -1); @@ -1045,6 +1048,34 @@ static void command_get_info_list(struct pa_pdispatch *pd, uint32_t command, uin pa_pstream_send_tagstruct(c->pstream, reply); } +static void command_get_server_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { + struct connection *c = userdata; + struct pa_tagstruct *reply; + char txt[256]; + assert(c && t); + + if (!pa_tagstruct_eof(t)) { + protocol_error(c); + return; + } + + if (!c->authorized) { + pa_pstream_send_error(c->pstream, tag, PA_ERROR_ACCESS); + return; + } + + reply = pa_tagstruct_new(NULL, 0); + assert(reply); + pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); + pa_tagstruct_putu32(reply, tag); + pa_tagstruct_puts(reply, PACKAGE_NAME); + pa_tagstruct_puts(reply, PACKAGE_VERSION); + pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt))); + pa_tagstruct_puts(reply, pa_get_host_name(txt, sizeof(txt))); + pa_tagstruct_put_sample_spec(reply, &c->protocol->core->default_sample_spec); + pa_pstream_send_tagstruct(c->pstream, reply); +} + /*** pstream callbacks ***/ static void pstream_packet_callback(struct pa_pstream *p, struct pa_packet *packet, void *userdata) { diff --git a/polyp/sink.c b/polyp/sink.c index 6df92e76..9628d8bd 100644 --- a/polyp/sink.c +++ b/polyp/sink.c @@ -64,6 +64,7 @@ struct pa_sink* pa_sink_new(struct pa_core *core, const char *name, int fail, co assert(s->monitor_source); pa_xfree(n); s->monitor_source->monitor_of = s; + s->monitor_source->description = pa_sprintf_malloc("Monitor source of sink '%s'", s->name); s->volume = PA_VOLUME_NORM; diff --git a/polyp/tagstruct.c b/polyp/tagstruct.c index cb93a9c4..9578a9eb 100644 --- a/polyp/tagstruct.c +++ b/polyp/tagstruct.c @@ -83,10 +83,10 @@ uint8_t* pa_tagstruct_free_data(struct pa_tagstruct*t, size_t *l) { static void extend(struct pa_tagstruct*t, size_t l) { assert(t && t->dynamic); - if (l <= t->allocated) + if (t->length+l <= t->allocated) return; - t->data = pa_xrealloc(t->data, t->allocated = l+100); + t->data = pa_xrealloc(t->data, t->allocated = t->length+l+100); } void pa_tagstruct_puts(struct pa_tagstruct*t, const char *s) { diff --git a/polyp/util.c b/polyp/util.c index 98d91075..70766a06 100644 --- a/polyp/util.c +++ b/polyp/util.c @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include #include "util.h" #include "xmalloc.h" @@ -109,14 +112,27 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size) { void pa_check_for_sigpipe(void) { struct sigaction sa; + sigset_t set; + + if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) { + if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) { + fprintf(stderr, __FILE__": sigprocmask() failed: %s\n", strerror(errno)); + return; + } + } + if (sigismember(&set, SIGPIPE)) + return; + if (sigaction(SIGPIPE, NULL, &sa) < 0) { fprintf(stderr, __FILE__": sigaction() failed: %s\n", strerror(errno)); return; } - if (sa.sa_handler == SIG_DFL) - fprintf(stderr, "polypaudio: WARNING: SIGPIPE is not trapped. This might cause malfunction!\n"); + if (sa.sa_handler != SIG_DFL) + return; + + fprintf(stderr, "polypaudio: WARNING: SIGPIPE is not trapped. This might cause malfunction!\n"); } /* The following is based on an example from the GNU libc documentation */ @@ -145,3 +161,30 @@ char *pa_sprintf_malloc(const char *format, ...) { size *= 2; } } + +char *pa_get_user_name(char *s, size_t l) { + struct passwd pw, *r; + char buf[1024]; + char *p; + + if (!(p = getenv("USER"))) + if (!(p = getenv("LOGNAME"))) + if (!(p = getenv("USERNAME"))) { + + if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) { + snprintf(s, l, "%lu", (unsigned long) getuid()); + return s; + } + + p = r->pw_name; + } + + snprintf(s, l, "%s", p); + return s; +} + +char *pa_get_host_name(char *s, size_t l) { + gethostname(s, l); + s[l-1] = 0; + return s; +} diff --git a/polyp/util.h b/polyp/util.h index 96fde11c..7dd7b7de 100644 --- a/polyp/util.h +++ b/polyp/util.h @@ -35,4 +35,7 @@ void pa_check_for_sigpipe(void); char *pa_sprintf_malloc(const char *format, ...) __attribute__ ((format (printf, 1, 2))); +char *pa_get_user_name(char *s, size_t l); +char *pa_get_host_name(char *s, size_t l); + #endif -- cgit